2016-11-07 69 views
0
import re, traceback, keyword 

def pnamedtuple(type_name, field_names, mutable=False): 
    def show_listing(s): 
     for i, l in enumerate(s.split('\n'), 1): 
      print('{num: >4} {txt}'.format(num= i, txt= l.rstrip())) 


    class type_name: 
     def __init__(self, x, y): 
      self.x = x 
      self.y = y 
      self._fields = [x,y] 
      self._mutable = False 

     def __repr__(self): 
      return 'Point(x={x},y={y})'.format(x=self.x,y=self.y) 

     def get_x(self): 
      return self.x 

     def get_y(self): 
      return self.y 

     def __getitem__(self, i): 
      if i == 0: 
       i = "x" 
      elif i == 1: 
       i = "y" 

      if i == "x": 
       return self.get_x() 
      elif i == "y": 
       return self.get_y() 
      else: 
       raise IndexError("Invalid key: {}".format(i)) 

     def __eq__(self,right): 
      if self[1] == right[1]: 
       return True 
      return False 

     def _replace(self,**kargs): 
      for key, value in kargs.iteritems(): 
       z = zip(key,value) 
      for x in z: 
       for y in self.field: 
        if x[0] == y: 
         self.x = x[1] 
        if x[0] == y: 
         self.y = x[1] 

    name_space = dict(__name__='pnamedtuple_{type_name}'.format(type_name= type_name)) 
    try: 
     exec(class_definition,name_space) 
     name_space[type_name].source_code = class_definition 
    except(SyntaxError, TypeError): 
     show_listing(class_definition) 
     traceback.print_exc() 
    return name_space[type_name] 

標題是DEF pnamedtuple(TYPE_NAME,FIELD_NAMES,可變=假):一個例子調用此函數是爲什麼我的函數沒有定義?

Point = pnamedtuple('Point', ['x','y'], mutable=False) 

,這相當於寫入

Point = pnamedtuple('Point', 'x y') 
Point = pnamedtuple('Point', 'x,y') 

合法名稱類型和字段必須以0或更多字母,數字或下劃線字符後面的字母開頭

field_names必須是合法名稱列表,如['x','y']或'x y'或'x,y'

p =點(1,2)寫p.get_x()或p [ 0])或p ['x']返回1

new_origin = origin._replace(y = 5),則print(origin,new_origin)將顯示爲Point(x = 0,y = 0) )點(x = 0,y = 5)

但是,當我運行此函數時,它顯示所有內容都未定義。 我加入了bsc.txt下面的代碼,這是一個有點長:

6 # Test pnamedtuple (as pnt) 
7 *Error: Triple1 = pnt('Triple1', 'a b c') raised exception NameError: name 'class_definition' is not defined 
8 *Error: print(Triple1.source_code) raised exception NameError: name 'Triple1' is not defined 
9 *Error: Triple2 = pnt('Triple2', 'a, b, c') raised exception NameError: name 'class_definition' is not defined 
10 *Error: Triple3 = pnt('Triple3', ['a','b','c']) raised exception NameError: name 'class_definition' is not defined 
11 *Error: Triple_Bad = pnt(1, 'a b c') raised wrong exception(NameError) should be from list: SyntaxError 
12 *Error: Triple_Bad = pnt('Triple_Bad', {'a','b','c'}) raised wrong exception(NameError) should be from list: SyntaxError 
13 *Error: Triple_Bad = pnt('3', 'a b c') raised wrong exception(NameError) should be from list: SyntaxError 
14 *Error: Triple_Bad = pnt('Triple_Bad', 'a 3 c') raised wrong exception(NameError) should be from list: SyntaxError 
15 *Error: Triple_Bad = pnt('Triple_Bad', 'a b if') raised wrong exception(NameError) should be from list: SyntaxError 
16 *Error: Triple_Bad = pnt('Triple_Bad', '_a _b _c') raised wrong exception(NameError) should be from list: SyntaxError 
17 *Error: Triple_OK = pnt('Triple_OK', 'a17 b__1 c__2') raised exception NameError: name 'class_definition' is not defined 
18 # Test init/repr 
19 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
20 *Error: repr(t1) raised exception NameError: name 't1' is not defined 
21 *Error: t2 = Triple2(1,2,3) raised exception NameError: name 'Triple2' is not defined 
22 *Error: repr(t2) raised exception NameError: name 't2' is not defined 
23 *Error: t3 = Triple3(1,2,3) raised exception NameError: name 'Triple3' is not defined 
24 *Error: repr(t3) raised exception NameError: name 't3' is not defined 
25 *Error: t3 = Triple3(c=3,b=2,a=1) raised exception NameError: name 'Triple3' is not defined 
26 *Error: repr(t3) raised exception NameError: name 't3' is not defined 
27 *Error: tok= Triple_OK(c__2=3,b__1=2,a17=1) raised exception NameError: name 'Triple_OK' is not defined 
28 *Error: repr(tok) raised exception NameError: name 'tok' is not defined 
29 *Error: t1.a raised exception NameError: name 't1' is not defined 
30 *Error: t1.b raised exception NameError: name 't1' is not defined 
31 *Error: t1.c raised exception NameError: name 't1' is not defined 
32 *Error: t1.d raised wrong exception(NameError) should be from list: AttributeError 
33 # Test get_ methods 
34 *Error: t1.get_a() raised exception NameError: name 't1' is not defined 
35 *Error: t1.get_b() raised exception NameError: name 't1' is not defined 
36 *Error: t1.get_c() raised exception NameError: name 't1' is not defined 
37 *Error: t1.get_d() raised wrong exception(NameError) should be from list: AttributeError 
38 *Error: l = [Triple1(a=1,b=2,c=3),Triple1(b=1,c=2,a=3),Triple1(c=1,a=2,b=3)] raised exception NameError: name 'Triple1' is not defined 
39 *Error: l.sort(key=Triple1.get_a) raised exception NameError: name 'l' is not defined 
40 *Error: l raised exception NameError: name 'l' is not defined 
41 # Test __getitem__ functions 
42 *Error: t1[0] raised exception NameError: name 't1' is not defined 
43 *Error: t1[1] raised exception NameError: name 't1' is not defined 
44 *Error: t1[2] raised exception NameError: name 't1' is not defined 
45 *Error: t1['a'] raised exception NameError: name 't1' is not defined 
46 *Error: t1['b'] raised exception NameError: name 't1' is not defined 
47 *Error: t1['c'] raised exception NameError: name 't1' is not defined 
48 *Error: t1[4] raised wrong exception(NameError) should be from list: IndexError 
49 *Error: t1['d'] raised wrong exception(NameError) should be from list: IndexError 
50 *Error: t1[3.2] raised wrong exception(NameError) should be from list: IndexError 
51 # Test == 
52 *Error: t1 == t1 raised exception NameError: name 't1' is not defined 
53 *Error: t1 == t2 raised exception NameError: name 't1' is not defined 
54 *Error: t1 == Triple1(a=1,b=2,c=3) raised exception NameError: name 't1' is not defined 
55 *Error: t1 == Triple1(a=1,b=1,c=3) raised exception NameError: name 't1' is not defined 
56 # Test replace (not mutable) 
57 *Error: t1._replace(a=2) raised exception; unevaluated: Triple1(2,2,3) 
58 *Error: t1._replace(a=2,c=2) raised exception; unevaluated: Triple1(2,2,2) 
59 *Error: t1._replace(a=2,c=2,d=2) raised wrong exception(NameError) should be from list: TypeError 
60 *Error: t1 raised exception; unevaluated: Triple1(a=1,b=2,c=3) 
61 # Test _replace (mutable) 
62 *Error: Triple1 = pnt('Triple1', 'a b c',mutable=True) raised exception NameError: name 'class_definition' is not defined 
63 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
64 *Error: t1._replace(a=2,c=2) raised exception NameError: name 't1' is not defined 
65 *Error: t1 raised exception; unevaluated: Triple1(a=2,b=2,c=2) 
66 # Test Extra Credit (prohibit mutation if immutable) 
67 *Error: Triple1 = pnt('Triple1', 'a b c',mutable=False) raised exception NameError: name 'class_definition' is not defined 
68 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
69 *Error: t1.a = 2 raised wrong exception(NameError) should be from list: AttributeError 
70 *Error: Triple1 = pnt('Triple1', 'a b c',mutable=True) raised exception NameError: name 'class_definition' is not defined 
71 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
72 *Error: t1.a = 2 raised exception NameError: name 't1' is not defined 
73 *Error: t1 raised exception; unevaluated: Triple1(2,2,3) 

可以someon告訴我,爲什麼我得到所有這些錯誤的?是否因爲我的類型名稱有問題?有人能告訴我如何解決它嗎?非常感謝。

這是我提供的基本代碼:

import re, traceback, keyword 

def pnamedtuple(type_name, field_names, mutable=False): 
    def show_listing(s): 
     for i, l in enumerate(s.split('\n'), 1): 
      print('{num: >4} {txt}'.format(num= i, txt= l.rstrip())) 

# put your code here 
# bind class_definition (used below) to the string constructed for the class 


# For initial debugging, always show the source code of the class 
#show_listing(class_definition) 

# Execute the class_definition string in a local namespace, binding the 
# name source_code in its dictionary to the class_defintion; return the 
# class object created; if there is a syntax error, list the class and 
# also show the error 
    name_space = dict(__name__='pnamedtuple_{type_name}'.format(type_name= type_name)) 
    try: 
     exec(class_definition,name_space) 
     name_space[type_name].source_code = class_definition 
    except(SyntaxError, TypeError): 
     show_listing(class_definition) 
     traceback.print_exc() 
    return name_space[type_name] 
+1

你爲什麼要在一個方法中定義一個類? –

+1

是的,這可能會給你73錯誤...不要那樣做 – Jakub

+0

我認爲這是要求,它不正確? – zeyuxie

回答

0

我不知道你的類定義是什麼,或者你來自哪裏得到它,如果你將它張貼這將是非常有益的。我想你有一些源代碼躺在周圍,應該把它包裝在繼承自函數中基類的類中。

我調用基類irrelevant,因爲名稱字面無關緊要,它只能在函數範圍內解析,這就是評論者所說的。對於你的情況,它不能在外部範圍內解決的事實不僅是可以接受的,而且是有意的。

該代碼會做你期望它做的,我想什麼:

import re, traceback, keyword 


def pnamedtuple(type_name, field_names, mutable=False): 
    def show_listing(s): 
     for i, l in enumerate(s.split('\n'), 1): 
      print('{num: >4} {txt}'.format(num= i, txt= l.rstrip())) 


    class irrelevant: 
     def __init__(self, x, y): 
      self.x = x 
      self.y = y 
      self._fields = [x,y] 
      self._mutable = False 

     def __repr__(self): 
      return 'Point(x={x},y={y})'.format(x=self.x,y=self.y) 

     def get_x(self): 
      return self.x 

     def get_y(self): 
      return self.y 

     def __getitem__(self, i): 
      if i == 0: 
       i = "x" 
      elif i == 1: 
       i = "y" 

      if i == "x": 
       return self.get_x() 
      elif i == "y": 
       return self.get_y() 
      else: 
       raise IndexError("Invalid key: {}".format(i)) 

     def __eq__(self,right): 
      if self[1] == right[1]: 
       return True 
      return False 

     def _replace(self,**kargs): 
      for key, value in kargs.iteritems(): 
       z = zip(key,value) 
      for x in z: 
       for y in self.field: 
        if x[0] == y: 
         self.x = x[1] 
        if x[0] == y: 
         self.y = x[1] 

    name_space = dict(__name__='pnamedtuple_{type_name}'.format(type_name= type_name),irrelevant=irrelevant) 
    class_definition = "class Point(irrelevant):\n pass" 

    try: 
     exec(class_definition,name_space) 
     name_space[type_name].source_code = class_definition 
    except(SyntaxError, TypeError): 
     show_listing(class_definition) 
     traceback.print_exc() 
    return name_space[type_name] 

Point = pnamedtuple('Point', ['x','y'], mutable=False) 
p = Point(1,2) 
print(p.get_x()) 

的訣竅是在經過基類中的上下文中執行代碼。根據class_definition的初始內容,代碼可能需要更改。

明智的問題,你從哪裏得到這個任務?

+0

嗨,這實際上是我的家庭作業,這是類將要做的事情: – zeyuxie

+0

編寫一個名爲pnamedtuple的函數,傳遞關於命名元組的信息:它返回對類對象的引用,從中我們可以構造指定命名元組的實例。我們可以使用這個類如下:from pcollections import pnamedtuple Point = pnamedtuple('Point','x y') p = Point(0,0) – zeyuxie

+0

另外,我不認爲你可以更改基本代碼,它仍然在我更改您提供的代碼後顯示未定義。 – zeyuxie

相關問題