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: >1} {txt}'.format(num= i, txt= l.rstrip()))
# put your code here
# bind class_definition (used below) to the string constructed for the class
field_names = field_names.replace(',', ' ').split()
if type(type_name) == int or type(field_names) == set or type_name[0].isalpha() == False:
raise SyntaxError
class_template = '''\
class {type_name}:
def __init__(self, {fields}):
self._fields = [{fields}]
self._mutable = False
self.a = self._fields[0]
self.b = self._fields[1]
self.c = self._fields[2]
def __repr__(self):
return 'Triple1' + '(a='+self.a+',b='+self.b+',c=self.c)'
def get_a(self):
return self.a
def get_b(self):
return self.b
def get_c(self):
return self.c
def __getitem__(self,i):
if type(i) == int:
if i > 2:
raise IndexError
if type(i) == str:
if i not in 'abc':
raise IndexError
if i == 0 or i == 'a':
return self.a
if i == 1 or i == 'b':
return self.b
if i == 2 or i == 'c':
return self.c
def _replace(self, **kwargs):
if self._mutable:
for key, value in kwargs.iteritems():
setattr(self, key, value)
else:
for field in self._fields:
if field not in kwargs:
kwargs[field] = getattr(self, field)
'''
class_definition = class_template.format(
type_name = type_name,
fields = ','.join(name for name in field_names)
)
# 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))
print(name_space)
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),这是相当于写Point = pnamedtuple(' Point',' x y')或Point = pnamedtuple(' Point',' x,y' ) 类型和字段的合法名称必须以字母开头,后面可以跟0个或多个字母,数字或下划线字符
我正在处理 repr 方法。它返回一个字符串。一个例子是:对于Point,如果我们定义origin = Point(0,0),则调用repr(origin)将返回' Point(x = 0,y = 0)'。 我试着打电话
t1 = Triple1(1,2,3)
repr(t1)
它给我以下错误:
18 # Test init/repr
20 *Error: repr(t1) -> <pnamedtuple_Triple1.Triple1 object at 0x015AF7B0> but should -> Triple1(a=1,b=2,c=3)
22 *Error: repr(t2) -> <pnamedtuple_Triple2.Triple2 object at 0x015AF9D0> but should -> Triple2(a=1,b=2,c=3)
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
28 *Error: repr(tok) -> <pnamedtuple_Triple_OK.Triple_OK object at 0x015AF850> but should -> Triple_OK(a17=1,b__1=2,c__2=3)
这是repr的bsc.txt代码:
# Test init/repr
c-->t1 = Triple1(1,2,3)
e-->repr(t1)-->Triple1(a=1,b=2,c=3)
c-->t2 = Triple2(1,2,3)
e-->repr(t2)-->Triple2(a=1,b=2,c=3)
c-->t3 = Triple3(1,2,3)
e-->repr(t3)-->Triple3(a=1,b=2,c=3)
c-->t3 = Triple3(c=3,b=2,a=1)
e-->repr(t3)-->Triple3(a=1,b=2,c=3)
c-->tok= Triple_OK(c__2=3,b__1=2,a17=1)
e-->repr(tok)-->Triple_OK(a17=1,b__1=2,c__2=3)
e-->t1.a-->1
e-->t1.b-->2
e-->t1.c-->3
有人可以帮我修复 repr 方法吗?我问了所有的TA,但他们无法弄清楚为什么我在第20行得到错误。