Python 属性 继承
Python property inheritance
我是 python 的新手,我不确定自己的做法是否正确。
我有一个基础 class A
和一个继承的 class B
.
class A(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
class B(A):
def __init__(self, name):
super(NominalValue, self).__init__(name)
@property
def name2(self):
return self.__name2
@name2.setter
def name2(self, n):
self.__name2 = n
def toString():
print self.__name + self.__name2
if __name__ == "__main__":
instance = B('name');
instance.toString()
当我 运行 它抱怨 class B
没有任何属性 __name
.
AttributeError: 'B' object has no attribute '_B__name'
我显然没有正确地进行继承。您如何对待正确继承的属性并避免在继承的属性中重复属性class?
以两个下划线开头的属性,例如您的 __name
,表示为私有变量。没有对这些进行实际的 PROTECTION(也就是说:如果你能找到它,你就可以访问它),但它们的名称被破坏了,因此不太容易访问。 More information about that can be found on the docs page
Any identifier of the form __spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam
, where classname
is the current class name with leading underscore(s) stripped.
因此,即使您继承了 A
的 __name
属性,您在 [=17= 类型的任何对象中都没有属性 __name
].您拥有的是 _A__name
属性。这就是 name-mangling 的工作原理:__attributename
变成 _classname__attributename
您可以改用 _name
,这只是给未来用户的一个标志,它不应该是 public。然后你的整个代码应该工作。
以双下划线为前缀的属性名称会被编译器特殊处理,在您更好地理解 Python 之前,您应该避免使用它们。
大多数 Python 程序员不知道为什么他们很特别,他们仍然可以过着快乐而富有成效的编程生活。它们客观上也很丑……你不觉得吗?
另请注意,在 Python 中,您开始使用 getter 和 setter 并不是为了好玩。只需从数据成员开始,仅在需要时(且仅在需要时)才迁移到属性。为简单地 returns 成员的 getter 和简单地改变它的 setter 编写代码是无稽之谈。何时(以及是否)您需要对成员访问进行特殊处理,将它们更改为属性,并且无需使用您的 class.
更改代码
在技术解释方面 Python 只是将 class 名称添加到以双下划线开头的属性,以避免与其他 class 中的同名属性发生不必要的冲突。然而,这种问题并不常见,这就是为什么大多数 Python 程序员从来没有必要使用此功能的原因。
我是 python 的新手,我不确定自己的做法是否正确。
我有一个基础 class A
和一个继承的 class B
.
class A(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
class B(A):
def __init__(self, name):
super(NominalValue, self).__init__(name)
@property
def name2(self):
return self.__name2
@name2.setter
def name2(self, n):
self.__name2 = n
def toString():
print self.__name + self.__name2
if __name__ == "__main__":
instance = B('name');
instance.toString()
当我 运行 它抱怨 class B
没有任何属性 __name
.
AttributeError: 'B' object has no attribute '_B__name'
我显然没有正确地进行继承。您如何对待正确继承的属性并避免在继承的属性中重复属性class?
以两个下划线开头的属性,例如您的 __name
,表示为私有变量。没有对这些进行实际的 PROTECTION(也就是说:如果你能找到它,你就可以访问它),但它们的名称被破坏了,因此不太容易访问。 More information about that can be found on the docs page
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped.
因此,即使您继承了 A
的 __name
属性,您在 [=17= 类型的任何对象中都没有属性 __name
].您拥有的是 _A__name
属性。这就是 name-mangling 的工作原理:__attributename
变成 _classname__attributename
您可以改用 _name
,这只是给未来用户的一个标志,它不应该是 public。然后你的整个代码应该工作。
以双下划线为前缀的属性名称会被编译器特殊处理,在您更好地理解 Python 之前,您应该避免使用它们。
大多数 Python 程序员不知道为什么他们很特别,他们仍然可以过着快乐而富有成效的编程生活。它们客观上也很丑……你不觉得吗?
另请注意,在 Python 中,您开始使用 getter 和 setter 并不是为了好玩。只需从数据成员开始,仅在需要时(且仅在需要时)才迁移到属性。为简单地 returns 成员的 getter 和简单地改变它的 setter 编写代码是无稽之谈。何时(以及是否)您需要对成员访问进行特殊处理,将它们更改为属性,并且无需使用您的 class.
更改代码在技术解释方面 Python 只是将 class 名称添加到以双下划线开头的属性,以避免与其他 class 中的同名属性发生不必要的冲突。然而,这种问题并不常见,这就是为什么大多数 Python 程序员从来没有必要使用此功能的原因。