【问题标题】:Python - Updating Child Attributes with a Base Class MethodPython - 使用基类方法更新子属性
【发布时间】:2015-04-17 07:56:39
【问题描述】:

我花了一天的时间试图找到这个问题的答案,但一无所获。

假设我有几个类,每个类都包含与其他类相同的方法。

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 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)

我希望能够以这样的方式从蓝色变为红色 这样我就不必在每个类 AB 中定义相同的方法

exampleA.set_color("red")

但这并没有像我预期的那样工作,它不会改变exampleA.__color的值

【问题讨论】:

  • 我意识到这只是一个例子,但是 setter 方法(和 getter 方法)不被认为是 Pythonic,除非你需要它们来做“神奇”的事情。如果只想设置属性的值,直接设置即可。
  • @PM2Ring:事实上,即使您确实希望他们做神奇的事情,除非您需要明确说明,作为界面的一部分,这种神奇正在发生,通常你最好还是把 getter 和 setter 放在 @property...

标签: python inheritance abstract-class object-oriented-analysis


【解决方案1】:

你不能。 __private 样式属性的全部意义在于它们是私有的。基类、子类、局外人,没有其他人可以看到或修改它们。如果一个基类或子类尝试,他们最终会在实例上创建自己的自己的私有属性,完全独立于你的。

如果你不想这样,就不要使用__private-style 属性。

那么,应该做什么呢?

嗯,最 Pythonic 的事情是只使用公共属性,完全废弃你的 getter 和 setter:exampleA.color = 'red'

如果你有一个很好的理由需要隐藏属性,也许你想将它们设为_private 而不是__private,这意味着它们只是按照惯例是私有的,所以你的代码将作为 -是。但同样,我怀疑你真的需要隐藏它们。

如果你真的,真的需要__private 成员,但仍然真的需要破坏__private 成员的全部目的……好吧,在那种情况下,我撒谎了;您实际上可以通过手动修改名称来访问它们。例如,在类 A 内部命名为 __color 的属性在类 A 外部命名为 _A__color

如果您想知道为什么 Python 允许您违反 __private 保护...好吧,与 Java 中的类似功能不同,这并不是为了保护您免受其他人的恶意代码的侵害。它可以保护您免受这样的场景的影响:您编写了一个带有属性__x 的类A。我写了一个类B,属性为__x。其他人通过从两者继承来组成我们的类,而无需告诉您或我。我的代码仍然有效,你的也是。

有关详细信息,请参阅private variables 上的教程部分和identifiers 上的参考文档。

【讨论】:

    【解决方案2】:

    这不能完全按照您的方式工作的唯一原因是因为您使用以__ 为前缀的属性,这使得它们“私有”,因此父类无法访问。不要那样做:只使用普通的属性名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 2014-05-26
      相关资源
      最近更新 更多