【问题标题】:Can you make a class attribute a specific instance of that class within the class definition?您可以在类定义中使类属性成为该类的特定实例吗?
【发布时间】:2021-05-04 12:24:54
【问题描述】:

想知道是否有一种方法可以从类定义中将类属性设置为特定实例。例如,

class Value:
    def __init__(self, x):
        self.x = x

    # Something like
    # half = Value(0.5)

>>> Value.half.x
0.5
>>> Value.half.half.x
0.5

我也知道我可以轻松地将它设置在看起来更笨重且容易出错的类之外,就像这样

class Value:
    def __init__(self, x):
        self.x = x

Value.half = Value(0.5)

>>> Value.half.x
0.5
>>> Value.half.half.x
0.5

【问题讨论】:

    标签: python class-attributes


    【解决方案1】:

    没有。在评估类的主体时,该类还不存在。类语句是调用元类的声明性语法:

    class Value:
        def __init__(self, x):
            self.x = x
    

    大致相当于

    def init(self, x):
        self.x = x
    
    
    Value = type('Value', (object,), {'__init__': init})
    

    您的类属性必须是作为第三个参数传递的dict 的成员,必须在调用type 之前对其进行完全定义。

    【讨论】:

      【解决方案2】:

      不完全是,但是您可以使用 classmethod 装饰器创建一个类方法,以任何您想要的方式返回您的类的新实例

      >>> class Value:
          def __init__(self, x):
              self.x=x
      
          def __repr__(self):
              return f"{type(self).__name__}({self.x})"
      
          @classmethod
          def half(cls):
              return cls(0.5)
      
          
      >>> Value(10)
      Value(10)
      >>> Value.half()
      Value(0.5)
      >>> 
      

      看起来像在 py3.9 中,你可以将它与属性装饰器结合起来来实现这一点,请参阅上面的链接文档(但我目前没有)

      【讨论】:

        【解决方案3】:

        简单地说,你不能因为这个类还不存在。但是您可以使用元类或类装饰器来实现与以下所示相同的目标:

        #Metaclass
        class Meta(type):
            def __init__(cls, clsname, clsbases, clsdict):
                cls.half = cls(0.5)
        
        class Value(metaclass=Meta):
            def __init__(self, x):
                self.x = x
        
        #Decorator
        def decorator(cls):
            cls.half = cls(0.5)
            return cls
        
        @decorator
        class Value2:
            def __init__(self, x):
                self.x = x
        
        print(Value.half.half.x)
        print(Value.half.x)
        print(Value2.half.half.x)
        print(Value2.half.x)
        

        【讨论】:

          猜你喜欢
          • 2015-07-16
          • 2018-08-04
          • 2018-06-12
          • 2016-07-11
          • 2023-03-27
          • 2013-11-08
          • 1970-01-01
          • 1970-01-01
          • 2015-06-29
          相关资源
          最近更新 更多