我试图创建一个类的默认实例。我想有在类定义中创建类的实例
class Foo():
def __init__(self):
....
_default = Foo()
@staticmethod
def get_default():
return _default
然而_default = Foo()
导致NameError: name 'Foo' is not defined
我试图创建一个类的默认实例。我想有在类定义中创建类的实例
class Foo():
def __init__(self):
....
_default = Foo()
@staticmethod
def get_default():
return _default
然而_default = Foo()
导致NameError: name 'Foo' is not defined
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):
# ...
当你可能会想使用哪种方法?
您不能引用尚不存在的类。在类定义体内,Foo
类是尚未创建。
添加类已经被创建之后的属性:
class Foo():
def __init__(self):
....
@staticmethod
def get_default():
return Foo._default
Foo._default = Foo()
请注意,您还需要改变get_default()
静态方法;班级主体不构成范围,因此您不能从get_default()
以_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
您可以懒洋洋地初始化默认实例。
class Foo(object):
_default = None
@staticmethod
def get_default():
if not Foo._default:
Foo._default = Foo()
return Foo._default
试图避免延迟初始化,因为它不是线程安全的 – mingxiao
请注意'__init'不是一种特殊的方法;它是'__init__'。 – abarnert
同时,这听起来像[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。许多想要这样做,但不知道如何的人,正试图用Python编写Java风格的代码,但实际上有更好的方法来解决他们真正的问题。所以,_why_你想要一个“默认实例”,你可以用这样的'staticmethod'来获得吗?为什么不,例如,只需要一个全局的'default_foo'对象? (是的,全局变量是不好的 - 但是单例变量是全局变量,它们只是隐藏了它们的全局性,而不是解决所有问题,但使事情变得更加复杂)。 – abarnert
对于这个问题,即使你希望全局默认实例被类所拥有,为什么你需要一个getter方法呢?这几乎总是非pythonic设计的标志。 – abarnert