链接类方法只设置一个时相互覆盖

时间:2016-04-29 16:25:15

标签: python python-2.7 class

我已经在一组类中创建了链式方法,但是当我为链中的最后一个链接设置值时,它会覆盖我认为是类链中单独实例的值。

例如:

sub0.one.some.a.time_t.raw = 1
sub0.one.some.b.time_t.raw = 2

可是:

print sub0.one.some.a.time_t.raw

返回2(不是1,如上所述)

print sub0.one.some.b.time_t.raw

返回2

代码如下。 Sub0是链中的顶级,Sub4是最低级别。我使用type()方法将类的实例添加为类中的方法。

为什么sub0.one.some.a.time_t.raw没有按照我设置的那样返回1?它不是链中所有类的单独实例吗?

class Sub4(object):
    pass

class Sub3(object):
    pass

class Sub2(object):
    pass

class Sub1(object):
    def __init__(self, config):
        self.config_field = config['flag']

class Sub0(object):
    def __init__(self, config):
        self.config = config


sub4_methods = ['raw']
Sub4 = type("Sub4", (Sub4, ), { sub4:None for sub4 in sub4_methods})

sub3_methods = ['time_t']
Sub3 = type("Sub3", (Sub3, ), { sub3:Sub4() for sub3 in sub3_methods})

sub2_methods = ['a', 'b']
Sub2 = type("Sub2", (Sub2, ), { sub2:Sub3() for sub2 in sub2_methods})

sub1_methods = ['all', 'some']
Sub1 = type("Sub1", (Sub1,), { sub1:Sub2() for sub1 in sub1_methods})

configs = {
    "one": { "flag": True },
    "two": { "flag": False },
    }
Sub0 = type("Sub0", (Sub0,), { k:Sub1(v) for (k,v) in zip(configs.keys(), configs.values())})

#create class instance
sub0 = Sub0(configs)

#set values
sub0.one.some.a.time_t.raw = 1
sub0.one.some.b.time_t.raw = 2

#both of these return 1, even though they are set to 1 & 2 respectively
print sub0.one.some.a.time_t.raw
#returns 1

print sub0.one.some.b.time_t.raw
#returns 1

谢谢!

1 个答案:

答案 0 :(得分:2)

  

我使用type()方法将类的实例添加为类中的方法。

这不是type所做的。 type创造了一个全新的课程。即使你已经意识到这一点(你似乎并不是这样),但对于你正在尝试做的事情来说,这是一个奇怪且不合适的选择。

  

它不是链中所有类的单独实例吗?

没有。此属性链中的所有对象都是共享的。

如果您希望Sub0个实例将Sub1个对象作为属性而Sub1个对象将Sub2个对象作为属性等,请按正常方式执行, __init__

class Sub0(object):
    def __init__(self):
        self.one = Sub1({"flag": True})
        self.two = Sub1({"flag": False})

class Sub1(object):
    def __init__(self):
        self.all = Sub2()
        self.some = Sub2()
...

如果您想使用列表定义属性名称,可以使用setattr中的__init__执行此操作:

class Sub1(object):
    def __init__(self):
        for name in ['all', 'some']:
            setattr(self, name, Sub2())