代码之家  ›  专栏  ›  技术社区  ›  Ponkadoodle

类\初始化\(不是实例\初始化\)

  •  8
  • Ponkadoodle  · 技术社区  · 15 年前

    下面是一个非常简单的例子,说明我想了解的情况:

    class Test(object):
        some_dict = {Test: True}
    

    问题是,当测试还在定义时,我不能引用它

    通常,我会这样做:

    class Test(object):
        some_dict = {}
        def __init__(self):
            if self.__class__.some_dict == {}:
                self.__class__.some_dict = {Test: True}
    

    但我从未创建此类的实例。它实际上只是一个容器,用来存放一组相关的函数和数据(我有几个类,我传递对它们的引用,所以 测试必须是自己的课程)

    所以我的问题是,当测试被定义的时候,我该如何引用它,或者是否有类似的东西 __init__ 一旦定义了类就调用了get?如果可能的话,我想 self.some_dict = {Test: True} 保留在类定义中。到目前为止,这是我唯一知道如何做到这一点的方法:

    class Test(object):
        @classmethod
        def class_init(cls):
            cls.some_dict = {Test: True}
    Test.class_init()
    
    5 回复  |  直到 13 年前
        1
  •  12
  •   jfs    15 年前

    类在定义时实际上不存在。方法 class 语句的工作方式是在单独的命名空间中以代码块的形式执行语句体。在执行结束时,该命名空间将传递给元类(例如 type )并且元类使用命名空间作为attributespace创建类。

    根据你的描述,是的 考试成为一门课所必需的声音。听起来应该是 模块 相反。 some_dict 是全局的——即使它是一个类属性,在程序中也只有一个这样的属性,所以它并不比拥有一个全局更好——类中的任何类方法都可以是函数。

    如果您真的希望它是一个类,您有三个选项:在定义类之后设置dict:

    class Test:
        some_dict = {}
    Test.some_dict[Test] = True
    

    使用类修饰器(在Python2.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 = {}
    
        2
  •  4
  •   Trey Hunner    15 年前

    您可以在主类定义之后添加一些\u dict属性。

    class Test(object):
      pass
    Test.some_dict = {Test: True}
    
        3
  •  1
  •   James    13 年前

    我以前尝试过用这种方式使用类,但是很快就变得很难看了(例如,所有的方法都需要是类方法或静态方法,并且您可能最终会意识到您想要定义某些特殊的方法,为此您必须开始使用元clasSES)。如果您只使用类实例,它可以使事情变得更容易——实际上没有任何缺点。

    与其他人的建议不同的是:你可以使用 __new__ :

    class Test(object):
        def __new__(cls):
            cls.some_dict = {cls: True}
    
    Test()
    

    你甚至可以 _新建__ 返回对类的引用并使用decorator调用它:

    def instantiate(cls):
        return cls()
    
    @instantiate
    class Test(object):
        def __new__(cls):
            cls.some_dict = {cls: True}
            return cls
    
        4
  •  0
  •   fraca7    15 年前

    您还可以使用元类(此处为函数,但还有其他方法):

    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
    
        5
  •  0
  •   darkfeline    13 年前

    托马斯的第一个例子是非常好的,但这里有一个更为蟒蛇式的方法来做同样的事情。

    class Test:
        x = {}
        @classmethod
        def init(cls):
            # do whatever setup you need here
            cls.x[cls] = True
    Test.init()