[英]Compare attributes of parent and child class in Python
I have a Python class like this:我有一个 Python class 像这样:
class A:
__val1: float = 0.0
__val2: float
def __init__():
validate()
def validate() -> bool:
if not hasattr(self, __val2): # how is this supposed to be done?
raise NotImplementedError()
return self.__val1 >= self.val2
My goal is to use A
as an abstract class where the child classes are forced to implement __val2
.我的目标是将
A
用作抽象 class ,其中子类被迫实现__val2
。
I create a child class B
:我创建了一个孩子 class
B
:
class B(A):
__val2 = 1.0
def __init__():
super().__init__()
When I initialize an object of class B
, this error is thrown:当我初始化 class
B
的 object 时,会抛出此错误:
E AttributeError: 'B' object has no attribute '_A__val2'
I tried modifying B
like this:我尝试像这样修改
B
:
class B(A):
A.__val2 = 1.0
[...]
But this throws the same exception.但这会引发相同的异常。
Trying the same but with super
:尝试相同但使用
super
:
class B(A):
super.__val2 = 1.0
[...]
But this throws another error:但这会引发另一个错误:
E TypeError: can't set attributes of built-in/extension type 'super'
What is the Pythonic way do handle this kind of abstraction?处理这种抽象的 Pythonic 方式是什么? How should
validate()
be implemented so that it checks for __val2
?应该如何实现
validate()
以便检查__val2
?
When you use double preceding underscores for your class attribute names, python converts them to _<classname>_<varname>
.当您对 class 属性名称使用双前下划线时, python 会将它们转换为
_<classname>_<varname>
。 So in your case, A.__val2
becomes A._A__val2
and B.__val2
becomes B._B__val2
, which means they won't share the same name.因此,在您的情况下,
A.__val2
变为A._A__val2
并且B.__val2
变为B._B__val2
,这意味着它们不会共享相同的名称。 See the link Thierry Lathuille has shared in the comment on your question, and here's the link to python docs: https://docs.python.org/3/tutorial/classes.html#private-variables .请参阅 Thierry Lathuille 在您的问题的评论中分享的链接,这里是 python 文档的链接: https://docs.python.org/3/tutorial.html/privateclasses.html/privateclasses.html
You can fix this by not using double underscores, so go for something like _val2
or val2
.您可以通过不使用双下划线来解决此问题,因此 go 用于
_val2
或val2
之类的东西。
There are a few other issues in your code: all your class methods need self
as the first argument, and you need to access them by calling self.<method_name>
.您的代码中还有一些其他问题:您的所有 class 方法都需要
self
作为第一个参数,您需要通过调用self.<method_name>
来访问它们。 So to access validate
, you need to call it with self.validate()
.因此,要访问
validate
,您需要使用self.validate()
调用它。 Also, the second arg to hasattr
must be a string.此外,
hasattr
的第二个参数必须是字符串。
Here's an updated example that should fix your issue:这是一个更新的示例,应该可以解决您的问题:
class A:
_val1: float = 0.0
_val2: float
def __init__(self):
self.validate()
def validate(self) -> bool:
if not hasattr(self, '_val2'):
raise NotImplementedError()
return self._val1 >= self._val2
class B(A):
_val2 = 1.0
def __init__(self):
super().__init__()
print(B()._val2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.