我試圖創建一個類的默認實例。我想有在類定義中創建類的實例
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