好吧,我有几乎相同的question,除了一个细节:我需要得到基类的私有值。代码:
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()
译员输出:
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'
问题是,当我需要_Child__field
时,口译员会尝试获取_Parent__field
。我可以使用@property
来获取此值,但它会阻止封装。我也可以用self._Parent__field
来解决这个问题,但这很难看,而且代码显然很糟糕。还有其他方法吗?
答案 0 :(得分:2)
正如您在问题中所述,可以通过在子类中明确使用其名称的错位形式来访问父属性:
def ChildMethodWhichUsingParentField(self):
return self._Parent__field
这是您直接问题的唯一简单答案。
但是,如果您可以控制Parent
类,那么这将是一个非常糟糕的设计。你不应该使用双下划线属性名称作为其他类类将使用的东西(即使你不期望任何这样的使用,你也可能不应该使用它)。请改用单个下划线(_field
)。这个&#34;文件&#34;该属性是私有的(例如,不是类的公共API的一部分),而不启用名称修改。这样,如果你发现晚于另一个类确实需要访问它可以的变量。 Python不会强制实施隐私(即使使用了名称修改),因此您总是需要依赖其他代码才能很好地运行。
名称修改实际上仅用于需要避免名称冲突的情况。例如,代理对象可能会使用损坏的名称作为其自己的属性,以便它可以呈现一个接口,该接口是另一个对象接口的精确副本(可能未提前知道)。或者mixin类可能会对其变量使用名称修改,因为它无法确定将在其旁边继承的(可能很多)其他类中使用哪些属性名称。如果您将自己使用的属性添加到其他对象(而不是self
)并且希望避免错误地覆盖其现有属性,那么它也会很有用。
答案 1 :(得分:1)
这可以通过添加一个getter
来实现class Parent(object):
def __init__(self):
self.__field = 13
def get_field(self):
return self.__field
class Child(Parent):
"""docstring for Child"""
def __init__(self):
super(Child, self).__init__()
def ChildMethodWhichUsingParentField(self):
return self.get_field()
if __name__ == '__main__':
c = Child()
print c.ChildMethodWhichUsingParentField()