类(非实例)构造函数

时间:2014-01-21 02:22:54

标签: python

基本上我正在尝试做这样的事情:

class A:
    some_field = None # that is the field which should have 123 value

    # what needs to be here?

class B(A(123)):
    pass

class C(A(456)):
    pass

我想要一个基类A。我希望孩子BC能够像A(123)一样将参数传递给它。

例如,如果我B.some_field,我应该123

我该怎么做?

2 个答案:

答案 0 :(得分:3)

unutbu的回答是正确的。我只想指出你甚至可以动态地做这些事情......

def make_class(base, value):
    class NewClass(base):
        some_field = value
    return NewClass

class A(object):
    some_field = None

B = make_class(A, 123)
C = make_class(A, 456)

实际上,这个非常重要,python实际上有一个内置来实现它:

class A(object):
    some_field = None

B = type('B', (A,), {'some_field': 123})

type需要3个参数 - 类的名称,基类的元组和类属性的字典。

答案 1 :(得分:2)

如果您定义BC,请执行以下操作:

class B(A):
    some_field = 123

class C(A):
    some_field = 123    

然后:

In [147]: B.some_field
Out[147]: 123

顺便说一下,A(123)会将123传递给A.__init__。它不会设置some_field

此外,在课程定义中,

class B(...)

括号中的内容必须是类或以逗号分隔的类列表(或者,在Python3中,metaclass=SomeMetaClass)。它不能是类的实例。所以

class B(A(123))

是明确的禁忌。


回复评论:您可以使用A.__new__方法返回一个类:

class A(object):
    some_field = None 
    def __new__(cls, val):
        cls.some_field = val
        return cls

class B(A(123)): pass

然后

In [161]: B.some_field
Out[161]: 123

但这是__new__的非标准用法,因为它通常用于返回A的实例。如果它不返回A的实例,则A.__init__ is not called

使用类工厂更容易理解,而不是使用class A

class B(make_class(123)): ...

正如您在下面的评论中提到的那样。