返回类

时间:2016-11-09 03:36:39

标签: python class

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行得到错误。

0 个答案:

没有答案