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,mutable = False):对此函数的示例调用是
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)Point(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)
可以告诉我为什么我会收到所有这些错误?是因为我的typename有问题吗?有人能告诉我如何解决它吗?非常感谢。
这是我提供的基本代码:
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]
答案 0 :(得分: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())
诀窍是在你的上下文中传递基类时执行你的代码。根据{{1}}的初始内容,代码可能需要更改。
很棒的问题,你在哪里获得这项任务?