【问题标题】:How to force a python class to have a CLASS property? (not a INSTANCE property!!!)如何强制 python 类具有 CLASS 属性? (不是实例属性!!!)
【发布时间】:2020-06-19 01:42:04
【问题描述】:

我已经搜索了一段时间,但我得到的都是关于 INSTANCE 属性而不是 CLASS 属性。 例如,这是来自 stackoverflow 的question 投票最多的答案

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        return 'someValue'

class D(C)
    def my_abstract_property(self):
        return 'aValue'

class E(c)
   # I expect the subclass should have this assignment,
   # but how to enforce this?
   my_abstract_property = 'aValue'  

但是,这是 INSTANCE PROPERTY 案例,而不是我的 CLASS PROPERTY 案例。换句话说,调用
D.my_abstract_property 将返回类似<unbound method D.my_abstract_property> 的内容。返回 '​​aValue' 是我所期望的,就像 E 类一样。

【问题讨论】:

  • 所以你想要一个对于所有子类实例都是常量的类变量?
  • 是的。这确实是我想要的。
  • 不完全是。我确实想要一个类变量,但我希望它对于所有“实例”都是常量,而不是“子类”。我希望“C”的所有子类都有一个同名的类属性,但值可能会有所不同。

标签: python class properties abstract


【解决方案1】:

根据您的示例和对我之前回复的评论,我构建了以下适用于ABC 的内容。 :

from abc import ABC

class C(ABC):
    _myprop = None

    def __init__(self):
        assert self._myprop, "class._myprop should be set"

    @property
    def myprop(self):
        return self._myprop


class D(C):
    _myprop = None

    def __init__(self):
        super().__init__()


class E(C):
    _myprop = 'e'

    def __init__(self):
        super().__init__()


e = E()
print(e.myprop)

d = D()
print(d.myprop)

您是正确的,没有 Python 预扫描会检测到另一个开发人员在初始化之前没有为类变量赋值。初始化程序将负责在使用中快速通知。

【讨论】:

  • 快到了。我希望“C.myprop”是“None”,并且每个 C 的子类都有自己的“myprop”值。在您的代码中,D 仍然需要再调用一次函数来设置自己的值。子类的开发者可以在他的子类的实现中分配“myprop”而不需要外部函数调用吗?
【解决方案2】:

你可以使用@classmethod 装饰器。

【讨论】:

  • 我试过了,好像不行。如果 c 是用 abc.ABCMeta 声明的,并且有一个名为“my_abstract_property”的方法,由@classmethod 修饰,并且 D 继承了 C,则调用 'D.my_abstract_property` 返回 'main.D'>>'。可以分享一些可以正常工作的代码吗?
【解决方案3】:

我想出了一个棘手的解决方法。

class C(object):
    myProp = None
    def __init__(self):
        assert self.myProp, 'you should set class property "name"'

class D(C):

    def __init__(self):
        C.__init__(self)

class E(C):
    myProp = 'e'
    def __init__(self):
        C.__init__(self)

print(D.myProp)
print(E.myProp)

但还是有一些问题:

  1. D.myProp 不会引发任何异常来警告开发人员有关约束(将 myProp 分配为其类属性),直到开发人员初始化其类的实例。
  2. abc 模块无法使用此解决方案,这意味着该模块的许多有用功能会丢失

【讨论】:

    猜你喜欢
    • 2020-02-09
    • 1970-01-01
    • 2018-08-04
    • 2011-11-24
    • 2021-04-02
    • 2011-08-01
    • 2022-06-15
    • 2019-10-09
    相关资源
    最近更新 更多