在类定义中创建类的实例

时间:2013-11-04 22:49:38

标签: python

我正在尝试拥有一个类的默认实例。我想要

class Foo():
    def __init__(self):
        ....

    _default = Foo()

    @staticmethod
    def get_default():
        return _default

_default = Foo()导致NameError: name 'Foo' is not defined

3 个答案:

答案 0 :(得分:5)

在完成类定义之前,

Foo不存在。您可以在类定义之后轻松地引用它

class Foo(object):
    def __init__(self):
    # ....

Foo.default_instance = Foo()

另请注意,我已删除了多余的getter方法,转而使用普通旧属性。

您还可以使用装饰器解决问题:

def defaultinstance(Class):
    Class.default_instance = Class()
    return Class

@defaultinstance
class Foo(object):
    # ...

或者,无偿地,使用元类:

def defaultmeta(name, bases, attrs):
    Class = type(name, bases, attrs)
    Class.default_instance = Class()
    return Class

# Python 2.x usage
class Foo(object):
    __metaclass__ = defaultmeta
    # ...

# Python 3.x usage
class Foo(metaclass=defaultmeta):
    # ...

您何时可能想要使用每种方法?

  • 使用后定义类属性分配为一次性
  • 如果你想在很多不相关的类中使用相同的行为并且“隐藏”它的实现(虽然它没有被隐藏,或者甚至那么复杂,但是在这里使用),使用装饰器。
  • 如果您希望行为可继承,请使用元类,在这种情况下,它并非真正无偿。 : - )

答案 1 :(得分:2)

您不能引用尚不存在的类。在类定义主体中,Foo尚未创建

创建类后添加属性:

class Foo():
    def __init__(self):
        ....

    @staticmethod
    def get_default():
        return Foo._default


Foo._default = Foo()

请注意,您还需要更改get_default()静态方法;类主体不构成范围,因此您无法从_default作为非本地联系get_default()

然而,你现在正在重复自己。通过改为get_default()类方法来减少重复:

class Foo():
    def __init__(self):
        ....

    @classmethod
    def get_default(cls):
        return cls._default


Foo._default = Foo()

或在第一次通话时创建默认值:

class Foo():
    def __init__(self):
        ....

    @classmethod
    def get_default(cls):
        if not hasattr(cls, '_default'):
            cls._default = cls()
        return cls._default

答案 2 :(得分:0)

您可能会懒惰地初始化您的默认实例。

class Foo(object):

    _default = None

    @staticmethod
    def get_default():
        if not Foo._default:
            Foo._default = Foo()
        return Foo._default