python - Python类继承——属性混淆
问题描述
在我看来,当程序员必须使用由其他人开发的类时,Python 存在固有的困难,他/她有关于他/她的基本文档(如何构造它,可用的函数等)但没有其实现的细节. 当然,当事情开始出错时,人们可以检查源代码,但所说的类可能是完全健壮的,直到有人想要对其进行子类化。
考虑这个简单的例子:-
class Base():
def __init__(self):
self._n = 99
@property
def n(self):
return self._n
@n.setter
def n(self, n):
self._n = n
def func(self):
print(self.n)
这里的关键是 Base 有一个函数,它在某种程度上依赖于属性 _n。
我现在决定要开发一个子类 Base 的类。所以,我写这个:-
class Myclass(Base):
def __init__(self, n):
super().__init__()
self.n = n
现在我遇到了麻烦,因为我刚刚在我的超类中删除了一个属性,并且可能完全破坏了它的功能。
是否有针对此潜在问题的任何开发模式或任何其他形式的防御?
解决方案
您可以通过对“private”* 属性使用名称修饰来避免“切换”超类的属性。名称以两个下划线**开头的属性将自动修改其名称,以免与超类中声明的名称发生冲突。
class A:
def __init__(self):
self.__x = 1
def get_A_x(self):
return self.__x
class B(A):
def __init__(self):
super().__init__()
self.__x = 2
def get_B_x(self):
return self.__x
obj = B()
print(obj.get_A_x(), obj.get_B_x())
# prints "1 2"
在最好的情况下,超类总是被编写为使用名称修饰来保护它自己的“私有”属性。如果不是,那么至少您可以确定子类中的名称损坏属性不会与它们发生冲突;仍然存在子类的公共属性可能与超类的未知“私有”属性发生冲突的风险。在这种情况下,您能做的最好的事情(除了在他们的问题跟踪器上打开一个问题)将尝试通过检查__dict__
超类实例的属性来找出超类声明的未记录属性,然后避免与这些名称发生冲突。
*当然在 Python 中,没有属性是真正私有的。甚至可以从声明它们的类外部访问名称损坏的属性,如果它们是通过它们的损坏名称访问的。
**不包括“dunder 方法”之类__init__
的,或任何其他也以两个或多个下划线结尾的名称。
推荐阅读
- oracle - 用于 nodejs 客户端的 aws oracle rds 数据库的连接字符串
- bluetooth-lowenergy - 减少 Instant Passed (0x28) BLE 断开错误的发生
- openconnect - openconnect,ssl连接失败
- email - 我可以使用 Openssl 创建 DKIM 密钥吗
- c# - 当 SDF 文件具有允许只读的权限时,为什么我不能以只读方式打开 SQL Server CE 数据库?
- javascript - 在 ajax 响应中加载列表对象并使用此数据创建动态列表 div
- javascript - 如何正确将以下 Jquery 转换为纯 Javascript?
- reinforcement-learning - PPO 对情节延迟奖励问题有好处吗
- python - 断言本地安装了mysql
- javascript - 如何使用 jQuery 将新的 HTML 添加到顶部?