python - 如何跨实例正确重置类变量
问题描述
dict 类变量在继承和实例化中被保留:
>>> class Superclass:
... x = {'one': 1}
... def __init__(self):
... self.x['one'] += 1
...
>>> class Subclass(Superclass):
... def __init__(self):
... super().__init__()
...
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 3}
>>> Subclass().x
{'one': 4}
>>> Subclass().x
{'one': 5}
>>> Subclass().x
{'one': 6}
>>> Subclass().x
{'one': 7}
我如何Superclass
在每次实例化时强制使用新的字典,我希望:
>>> class Superclass:
... x = {'one': 1}
... def __init__(self):
... self.x['one'] += 1
...
>>> class Subclass(Superclass):
... def __init__(self):
... super().__init__()
...
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
并且
>>> class Superclass:
... x = {'one': 1}
... def __init__(self):
... self.x['one'] += 1
...
>>> class Subclass(Superclass):
... x = {'one': 5}
... def __init__(self):
... super().__init__()
...
>>> Subclass().x
{'one': 6}
>>> Subclass().x
{'one': 6}
>>> Subclass().x
{'one': 6}
>>> Subclass().x
{'one': 6}
>>> Subclass().x
{'one': 6}
>>> Subclass().x
{'one': 6}
拥有一个实例变量显然是行不通的:
>>> class Superclass:
... def __init__(self):
... self.x = {'one': 1}
... self.x['one'] += 1
...
>>> class Subclass(Superclass):
... def __init__(self):
... self.x = {'one': 5}
... super().__init__()
...
>>> Subclass().x # desired: {'one': 6}
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
>>> Subclass().x
{'one': 2}
当超类被重新实例化时,混合不起作用:
>>> class Superclass:
... x = {'one': 1}
... def __init__(self):
... self.x['one'] += 1
...
>>> class Subclass(Superclass):
... def __init__(self):
... self.x = {'one': 5}
... super().__init__()
...
>>> Superclass().x
{'one': 2}
>>> Superclass().x
{'one': 3}
>>> Superclass().x
{'one': 4}
>>> Superclass().x
{'one': 5}
>>> Superclass().x
{'one': 6}
>>> Superclass().x
{'one': 7}
解决此问题的正确且成熟的方法是什么?
解决方案
You want subclasses to be able to override the code the superclass uses to construct its initial value of x
, before it performs further modification. That's kind of a weird thing to override, but I would approach it by moving the construction of the initial x
value into its own overridable method:
class Super:
def __init__(self):
self.x = self._initial_x()
self.x['one'] += 1
@classmethod
def _initial_x(cls):
return {'one': 1}
class Sub(Super):
@classmethod
def _initial_x(cls):
return {'one': 5}
推荐阅读
- c# - 用于查找不在“”字符之间的单词的正则表达式
- awk - 如何通过 grep 命令在 gnuplot 中使用 for 循环
- azure - 使用 Terraform 更新现有应用服务
- node.js - 使用 AWS 无服务器和 NodeJS 在接收器 lambda 处未接收到来自 SQS 的所有消息
- python - 如何将 f(k) 插入系列?
- c# - 在接口的泛型方法中使用泛型类型的参数
- c - 通过 C 操作文件以制作前 5 名排行榜
- c# - 在 EF 中获取未更新的迁移名称
- python - Python insert() 方法相关的问题
- python - Robot Framework:[Setup] 目的是什么?