【问题标题】:How make my pattern observer with metaclass work?如何让我的模式观察者使用元类工作?
【发布时间】:2020-02-04 07:42:48
【问题描述】:

我想在我的类属性上设置一个模式观察器

我尝试使用@classmethod,但它没有setter 属性。

class dataframe():
    df = None
    @classmethod
    @property
    def weather(cls):
        return cls.df
    @classmethod
    @weather.setter
    def weather(cls,value):
        cls.df= value
        print("the weath was change {}".format(cls.df))
<ipython-input-119-7e26ac08cb26> in dataframe()
      6         return cls.df
      7     @classmethod
----> 8     @weather.setter
      9     def weather(cls,value):
     10         cls.df= value

AttributeError: 'classmethod' object has no attribute 'setter'

然后我尝试调整我在那里找到的解决方案来解决我的问题Using property() on classmethods

class dataframe_meta(type):
    def __init__(cls, *args, **kwargs):
        cls.df = None

    @property
    def change(cls):
        return cls.df

    @change.setter
    def change(cls, value):
        cls.df = value
        print("the weath was change {}".format(cls.df))

class dataframe(metaclass=dataframe_meta):
    pass

dataframe.df = 5 它不返回任何错误,但未显示来自函数设置器的print

如何让它正常工作?

【问题讨论】:

  • 你链接的问题中的这个答案可能对你更有帮助stackoverflow.com/a/39542816/548562
  • 您不会看到 print 语句,因为您没有调用 setter,而是直接修改了成员。 dataframe.change = 5 将显示您要查找的打印语句。话虽如此,我不确定一般方法是否是最好的,但如果不了解更多信息就很难说。

标签: python observer-pattern metaclass


【解决方案1】:

如果您想查看对df 属性所做的更改,您应该将方法命名为df,并将存储df 实际值的属性命名为其他名称,例如_df

class dataframe_meta(type):    
    def __init__(cls, *args, **kwargs):
        cls._df = None

    @property
    def df(cls):
        return cls._df

    @df.setter
    def df(cls,value):
        cls._df= value
        print("the weath was change {}".format(cls._df))

【讨论】:

    【解决方案2】:

    你发布的代码,

    
    class dataframe_meta(type):
        def __init__(cls, *args, **kwargs):
            cls.df = None
    
        @property
        def change(cls):
            return cls.df
    
        @change.setter
        def change(cls, value):
            cls.df = value
            print("the weath was change {}".format(cls.df))
    
    class dataframe(metaclass=dataframe_meta):
        pass
    

    将按原样工作 - 但是,您将属性命名为 change 而不是 df - 如果您命名为 dataframe.change = 5,您将看到打印。

    但是,对dataframe.df 的访问本身是不受保护的。

    如果您希望dataframe.df 本身触发getter/setter 方法,您必须将属性本身命名为df,并将结果存储在另一个名称的属性中。是的,元类是“属性”处理类属性的一种直接方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 2013-03-05
      相关资源
      最近更新 更多