Mon*_*eal 6 python oop inheritance
好吧,我有几乎相同的问题,除了一个细节:我需要获取基类的私有值。代码:
class Parent(object):
def __init__(self):
self.__field = 13
class Child(Parent):
"""docstring for Child"""
def __init__(self):
super(Child, self).__init__()
def ChildMethodWhichUsingParentField(self):
return self.__field
if __name__ == '__main__':
c = Child()
c.ChildMethodWhichUsingParentField()
Run Code Online (Sandbox Code Playgroud)
口译输出:
Traceback (most recent call last):
File "foo.py", line 20, in <module>
c.ChildMethodWhichUsingParentField()
File "foo.py", line 16, in ChildMethodWhichUsingParentField
return self.__field
AttributeError: 'Child' object has no attribute '_Child__field'
Run Code Online (Sandbox Code Playgroud)
问题是口译员试图_Child__field在我需要时获取_Parent__field. 我可以使用 获得这个值@property,但它会阻止封装。我也可以解决这个问题,self._Parent__field但这是丑陋的,显然是糟糕的代码。还有其他方法吗?
正如您在问题中所指出的,您可以通过在子类中显式使用其名称的损坏形式来访问父属性:
def ChildMethodWhichUsingParentField(self):
return self._Parent__field
Run Code Online (Sandbox Code Playgroud)
这是对您直接问题的唯一简单答案。
然而,如果你可以控制类Parent,这将是一个非常糟糕的设计。您不应该将双下划线属性名称用于另一个类将使用的内容(实际上您可能不应该使用它,即使您不希望有任何此类使用)。使用单个下划线 (_field )。这“证明”该属性是私有的(例如,不是类的公共 API 的一部分),而不启用名称修改。这样,如果您稍后发现另一个类确实需要访问该变量,它也可以。Python 不强制执行隐私(即使使用名称修改时也不例外),因此您始终需要依赖其他表现良好的代码。
名称修饰实际上仅适用于需要避免名称冲突的情况。例如,代理对象可能对其自己的属性使用损坏的名称,以便它可以呈现一个与另一个对象的接口(可能无法提前知道)精确复制的接口。或者,mixin 类可能对其变量使用名称修饰,因为它无法确定将在(可能是许多)与其一起继承的其他类中使用哪些属性名称。如果您要将自己使用的属性添加到其他对象(而不是self)并且希望避免错误地覆盖其现有属性,那么它也很有用。
这是通过添加 getter 来实现的
class Parent(object):
def __init__(self):
self.__field = 13
def get_field(self):
return self.__field
class Child(Parent):
def ChildMethodWhichUsingParentField(self):
return self.get_field()
c = Child()
print c.ChildMethodWhichUsingParentField()
Run Code Online (Sandbox Code Playgroud)