【发布时间】:2022-01-10 23:27:32
【问题描述】:
我已经通过在元类中定义带有@property 装饰器的属性来定义类属性,正如SO answer 中所建议的那样。
由于在定义后我只能访问类定义(将从元类继承),因此我将在之后继承它,这要归功于上述 SO 答案中给出的技巧。
我希望定义的类属性在继承类及其实例中都可用。 但我没有成功在它的实例中拥有它。
那么,让我们回顾一下我当前的代码:
class TopLevel(type):
""" TopLevel metaclass defining class properties. """
@property
def depth(cls) -> int:
return cls._depth
class OtherClass:
""" Class that will inherit from 'TopLevel' after it has been defined.
Dummy implementation."""
def __init__(self, var):
self.var = var
# Making 'Otherclass' inheriting from metaclass 'TopLevel' to have available
# as class properties 'depth'.
# As per https://stackoverflow.com/a/5121381/4442753
OtherClass = TopLevel(OtherClass.__name__,
OtherClass.__bases__,
dict(OtherClass.__dict__))
# Set a value to '_depth'
OtherClass._depth = 3
# Check OtherClass has 'depth' class property
OtherClass.depth
Out[6]: 3
# Instanciate OtherClass: instance has no 'depth' attribute?
otherclass = OtherClass(4)
otherclass.depth
Traceback (most recent call last):
File "/tmp/ipykernel_748533/2343605532.py", line 1, in <module>
otherclass.depth
AttributeError: 'OtherClass' object has no attribute 'depth'
这可以实现吗?
编辑
代码 sn-p 说明了我对 @martineau 第一条评论的回答:
class A:
a=2
class B(A):
def __init__(self,var):
self.var = var
b = B(42)
b.a
Out[26]: 2
b.var
Out[27]: 42
【问题讨论】:
-
为什么您首先希望类属性可用于该类的实例 - 无论该属性是否被继承?
-
嗨,马蒂诺。我想我对@property 的作用还不清楚。我正在想象无论它做什么,结果都会作为继承类中的类属性保存。实例化一个类时,您会发现类属性进入其实例,这是“正常”行为。我在初始帖子中给出了一个代码 sn-p。在这段代码 sn-p 中,如果我将“保护”“b”作为类属性,我希望它在类实例中受到保护。下面的答案使这成为可能,它符合我的需要。
-
您的更新令人困惑,因为
a和var被赋予相同的值。如果您将其更改为b = B(42),则生成的b.var值不会令人惊讶地为42— 这并不意味着a类B属性正在通过b类B的实例进行访问. -
对不起,martineau,我不明白你的评论。我根据您的评论进行了更改以减少混乱,它仍然显示了我认为是您最初问题的答案:因为将“类属性”的东西分开,从类 B 继承的类 A 的实例保持类B 属性。这就是为什么我期待这个 B 类属性,如果它被更改为属性,则保留在 A 的实例中。我期待“正常的 python 行为”保留,该属性是否是 B 中的属性。
-
好吧,这更有意义。
标签: python inheritance