Python - 使用基本 Class 方法更新子属性
Python - Updating Child Attributes with a Base Class Method
我花了一天时间试图找到这个问题的答案,但一无所获。
假设我有几个 classes,每个都包含一个与其他方法相同的方法。
class A:
def __init__(self, attr1, attr2, color):
self.__attr1 = attr1
self.__attr2 = attr2
self.__color = color
def set_color(self, color):
self.__color = color
class B:
def __init__(name, attr3, attr4, color):
self.__attr3 = attr3
self.__attr4 = attr4
self.__color = color
def set_color(self, color):
self.__color = color
在这个例子中,相同的方法被简化为只有一个相同的方法,set_color,以说明我正在尝试做的事情。
有没有办法消除重复代码,或许可以用如下摘要class?
class Parent:
def set_color(self, color):
self.__color = color
class A(Parent):
def __init__(self, attr1, attr2, color):
self.__attr1 = attr1
self.__attr2 = attr2
self.__color = color
class B(Parent):
def __init__(name, attr3, attr4, color):
self.__attr3 = attr3
self.__attr4 = attr4
self.__color = color
exampleA = A(attr1, attr2, "blue)
我希望能够像这样从蓝色变为红色
这样我就不必在每个 class A
和 B
中定义相同的方法
exampleA.set_color("red")
但这并没有像我预期的那样工作,它没有改变 exampleA.__color
的值
你不能。 __private
样式属性的全部意义在于它们是私有的。 Base classes,subclasses,局外人,没有其他人可以看到或修改它们。如果 base class 或 subclass 尝试,他们最终将在实例上创建自己的 own 私有属性,完全独立于您的私有属性。
如果你不想那样,就不要使用 __private
风格的属性。
那么,你应该做什么?
嗯,最 Pythonic 的事情就是只使用 public 属性,并完全废弃你的 getter 和 setter:exampleA.color = 'red'
。
如果您有充分的理由需要隐藏属性,也许您想将它们设为 _private
而不是 __private
,这意味着它们只是按照惯例是私有的,所以您的代码将按原样工作。但同样,我怀疑你真的需要隐藏它们。
如果你真的、真的需要 __private
成员,但仍然真的需要打败 __private
成员的全部目的……好吧,在那种情况下,我撒谎了;实际上,您 可以 通过手动修改名称来访问它们。例如,从 class A
内部命名为 __color
的属性从 class A
.
外部命名为 _A__color
如果您想知道为什么 Python 会让您违反 __private
保护...好吧,与 Java 中的类似功能不同,这并不是为了保护您针对他人的恶意代码。它保护你的是这样的场景:你写了一个 class A
和一个属性 __x
。我写了一个 class B
和一个属性 __x
。其他人通过继承两者来组成我们的 classes,而没有告诉你或我。我的代码仍然有效,你的也是。
有关详细信息,请参阅 private variables, and the reference documentation on identifiers 上的教程部分。
这不能完全像您所拥有的那样工作的唯一原因是因为您使用的是前缀为 __
的属性,这使得它们 "private" 因此父级无法访问 class。不要那样做:只使用普通的属性名称。
我花了一天时间试图找到这个问题的答案,但一无所获。
假设我有几个 classes,每个都包含一个与其他方法相同的方法。
class A:
def __init__(self, attr1, attr2, color):
self.__attr1 = attr1
self.__attr2 = attr2
self.__color = color
def set_color(self, color):
self.__color = color
class B:
def __init__(name, attr3, attr4, color):
self.__attr3 = attr3
self.__attr4 = attr4
self.__color = color
def set_color(self, color):
self.__color = color
在这个例子中,相同的方法被简化为只有一个相同的方法,set_color,以说明我正在尝试做的事情。
有没有办法消除重复代码,或许可以用如下摘要class?
class Parent:
def set_color(self, color):
self.__color = color
class A(Parent):
def __init__(self, attr1, attr2, color):
self.__attr1 = attr1
self.__attr2 = attr2
self.__color = color
class B(Parent):
def __init__(name, attr3, attr4, color):
self.__attr3 = attr3
self.__attr4 = attr4
self.__color = color
exampleA = A(attr1, attr2, "blue)
我希望能够像这样从蓝色变为红色
这样我就不必在每个 class A
和 B
exampleA.set_color("red")
但这并没有像我预期的那样工作,它没有改变 exampleA.__color
你不能。 __private
样式属性的全部意义在于它们是私有的。 Base classes,subclasses,局外人,没有其他人可以看到或修改它们。如果 base class 或 subclass 尝试,他们最终将在实例上创建自己的 own 私有属性,完全独立于您的私有属性。
如果你不想那样,就不要使用 __private
风格的属性。
那么,你应该做什么?
嗯,最 Pythonic 的事情就是只使用 public 属性,并完全废弃你的 getter 和 setter:exampleA.color = 'red'
。
如果您有充分的理由需要隐藏属性,也许您想将它们设为 _private
而不是 __private
,这意味着它们只是按照惯例是私有的,所以您的代码将按原样工作。但同样,我怀疑你真的需要隐藏它们。
如果你真的、真的需要 __private
成员,但仍然真的需要打败 __private
成员的全部目的……好吧,在那种情况下,我撒谎了;实际上,您 可以 通过手动修改名称来访问它们。例如,从 class A
内部命名为 __color
的属性从 class A
.
_A__color
如果您想知道为什么 Python 会让您违反 __private
保护...好吧,与 Java 中的类似功能不同,这并不是为了保护您针对他人的恶意代码。它保护你的是这样的场景:你写了一个 class A
和一个属性 __x
。我写了一个 class B
和一个属性 __x
。其他人通过继承两者来组成我们的 classes,而没有告诉你或我。我的代码仍然有效,你的也是。
有关详细信息,请参阅 private variables, and the reference documentation on identifiers 上的教程部分。
这不能完全像您所拥有的那样工作的唯一原因是因为您使用的是前缀为 __
的属性,这使得它们 "private" 因此父级无法访问 class。不要那样做:只使用普通的属性名称。