簡體   English   中英

class __init __(不是實例__init__)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM