[英]class __init__ (not instance __init__)
這是我想要解決的一個非常簡單的例子:
class Test(object):
some_dict = {Test: True}
問題是我仍然無法在定義時引用Test
通常,我只是這樣做:
class Test(object):
some_dict = {}
def __init__(self):
if self.__class__.some_dict == {}:
self.__class__.some_dict = {Test: True}
但我從來沒有創建過這個類的實例。 這真的只是一個容器,以便容納一組相關的功能和數據(我有幾個這些類的,我繞過它們的引用,因此有必要對測試是它自己的類)
所以我的問題是,我在定義時如何引用Test,或者是否有類似於__init__
東西,只要定義了類就會調用它? 如果可能的話,我希望self.some_dict = {Test: True}
保留在類定義中。 到目前為止,這是我知道如何做到這一點的唯一方法:
class Test(object):
@classmethod
def class_init(cls):
cls.some_dict = {Test: True}
Test.class_init()
實際上,在確定類時,它確實不存在。 class
語句的工作方式是語句的主體作為代碼塊在單獨的命名空間中執行。 在執行結束時,該命名空間將傳遞給元類(例如type
),而元類使用命名空間作為屬性空間創建類。
根據您的描述,測試成為一個類似乎沒有必要。 聽起來它應該是一個模塊而不是。 some_dict
是一個全局 - 即使它是一個類屬性,你的程序中只有一個這樣的屬性,所以它沒有比擁有全局更好 - 並且你在類中擁有的任何類方法都可以只是函數。
如果你真的想讓它成為一個類,你有三個選擇:在定義類之后設置dict:
class Test:
some_dict = {}
Test.some_dict[Test] = True
使用類裝飾器(在Python 2.6或更高版本中):
def set_some_dict(cls):
cls.some_dict[cls] = True
@set_some_dict
class Test:
some_dict = {}
或者使用元類:
class SomeDictSetterType(type):
def __init__(self, name, bases, attrs):
self.some_dict[self] = True
super(SomeDictSetterType, self).__init__(name, bases, attrs)
class Test(object):
__metaclass__ = SomeDictSetterType
some_dict = {}
您可以在主類定義之后添加some_dict屬性。
class Test(object):
pass
Test.some_dict = {Test: True}
我過去曾試圖以這種方式使用類,並且它很快變得丑陋(例如,所有方法都需要是類方法或靜態方法,你最終可能會意識到你想要定義某些特殊的方法,您將不得不開始使用元類)。 如果您只使用類實例,它可以使事情變得更容易 - 實際上沒有任何缺點。
一個(奇怪的)替代其他人的建議:你可以使用__new__
:
class Test(object):
def __new__(cls):
cls.some_dict = {cls: True}
Test()
您甚至可以讓__new__
返回對類的引用並使用裝飾器來調用它:
def instantiate(cls):
return cls()
@instantiate
class Test(object):
def __new__(cls):
cls.some_dict = {cls: True}
return cls
托馬斯的第一個例子是非常好的,但這是一種更多的Pythonic方式做同樣的事情。
class Test:
x = {}
@classmethod
def init(cls):
# do whatever setup you need here
cls.x[cls] = True
Test.init()
您還可以使用元類(此處的函數,但還有其他方法):
def Meta(name, bases, ns):
klass = type(name, bases, ns)
setattr(klass, 'some_dict', { klass: True })
return klass
class Test(object):
__metaclass__ = Meta
print Test.some_dict
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.