动态创建具有继承和类方法的类列表

时间:2013-05-08 12:35:50

标签: python inheritance dynamic python-2.7 class-method

我有一个类列表,我正在尝试动态创建另一个类列表,这样每个类都有一个classmethod,它从原始列表中创建一个类的子实例。登记/> 问题是所有方法最终返回同一个类的实例(最后一个创建的实例)。

以下是我的代码的最小化版本:

class C1():
    var = 1
class C2():
    var = 2

parents = (C1, C2)
children = []
wrappers = []

for c in parents:

    class ChildClass(c):
        pass
    children.append(ChildClass())

    class Wrapper():
        @classmethod
        def method(cls):
            cls.wrapped = ChildClass()

    wrappers.append(Wrapper)

print(list(child.var for child in children))

for wrapper in wrappers:
    wrapper.method()

print(list(wrapper.wrapped.var for wrapper in wrappers))

输出:

[1, 2]
[2, 2]

您可以看到children列表包含不同的实例,而classmethod在两种情况下都会创建C2子项的实例。

如何修复我的代码,以便每个classmethod创建一个正确类的实例?

(我正在使用python 2.7.4)

1 个答案:

答案 0 :(得分:2)

ChildClass中的Wrapper.method()引用是一个自由变量,意味着在定义方法时,Wrapper.method()被调用时将解析

当您调用该方法时,名称ChildClass将引用您创建的最后一个类。

您需要提供仅ChildClass具有一个明确值的范围,或者在定义时绑定引用。后者可以使用函数参数default:

来完成
class Wrapper():
    @classmethod
    def method(cls, child_class=ChildClass):
        cls.wrapped = child_class()

您还可以使用函数作用域将引用绑定到该作用域中的局部变量:

def createClasses(parent):
    class ChildClass(parent):
        pass

    class Wrapper():
        @classmethod
        def method(cls):
            cls.wrapped = ChildClass()

    return ChildClass, Wrapper

for c in parents:
    child, wrapper = createClasses(c)

    children.append(child)
    wrappers.append(wrapper)

这里,当Wrapper.method引用ChildClass时,它将在createClasses函数的本地命名空间中查找,并且只会有一个值绑定到那个名字。