[英]Python - Updating Child Attributes with a Base Class Method
I have spent the day trying to find an answer to this question but have come up with nothing. 我花了一天时间试图找到这个问题的答案,但却没有提出任何问题。
Suppose I have several classes, each containing a methods that are identical to those in the others. 假设我有几个类,每个类都包含一个与其他类相同的方法。
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
In this example, the identical methods are reduced to just one identical method, set_color, to illustrate what I am trying to do. 在这个例子中,相同的方法被简化为一个相同的方法set_color,以说明我想要做的事情。
Is there a way to eliminate repeating code, perhaps with an abstract class as follows? 有没有办法消除重复代码,也许有一个抽象类如下?
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)
I want to be able change from blue to red in a way like this so that I don't have to define the same methods within each class A
and B
我希望能够以这样的方式从蓝色变为红色,这样我就不必在每个
A
和B
类中定义相同的方法
exampleA.set_color("red")
but this doesn't work as I expected it to, it doesn't change the value of exampleA.__color
但是这不像我预期的那样工作,它不会改变
exampleA.__color
的值
You can't. 你不能。 The whole point of
__private
-style attributes is that they're private. __private
风格属性的重点在于它们是私有的。 Base classes, subclasses, outsiders, nobody else can see the or modify them. 基类,子类,局外人,其他人都无法看到或修改它们。 If a base class or subclass tries, they will end up creating their own private attribute on the instance, completely independent of yours.
如果基类或子类尝试,它们最终将在实例上创建自己的私有属性,完全独立于您的属性。
If you don't want that, just don't use __private
-style attributes. 如果您不想这样,请不要使用
__private
style属性。
So, what should you do? 那么,你应该怎么做?
Well, the most Pythonic thing is to just use public attributes, and scrap your getters and setters entirely: exampleA.color = 'red'
. 好吧,最Pythonic的事情就是使用公共属性,完全废弃你的getter和setter:
exampleA.color = 'red'
。
If you have a really good reason you need to hide the attributes, maybe you wanted to make them _private
instead of __private
, which means they're private only by convention, so your code will just work as-is. 如果你有一个很好的理由需要隐藏属性,也许你想让它们
_private
而不是__private
,这意味着它们只是按惯例隐私,所以你的代码将按原样工作。 But again, I doubt you really need to hide them. 但同样,我怀疑你真的需要隐藏它们。
If you really, really need __private
members, but still really need to defeat the entire purpose of __private
members… well, in that case, I lied; 如果你真的,真的需要
__private
成员,但仍然真的需要打败__private
成员的整个目的......好吧,在那种情况下,我撒了谎; you actually can access them, by manually mangling the names. 你实际上可以通过手动修改名称来访问它们。 For example, the attribute that's named
__color
from inside class A
is named _A__color
from outside of class A
. 例如,这是命名的属性
__color
从内部类A
名为_A__color
从类以外的A
。
If you're wondering why Python lets you violate the __private
protection... well, unlike the similar feature in Java, this isn't meant to protect you against someone else's malicious code. 如果您想知道为什么Python会让您违反
__private
保护......那么,与Java中的类似功能不同,这并不是为了保护您免受其他人的恶意代码攻击。 What it protects you from is a scenario like this: You write a class A
with a an attribute __x
. 它保护你的是这样的场景:你用一个属性
__x
写一个A
类。 I write a class B
with an attribute __x
. 我写了一个带有
__x
属性的B
类。 Someone else composes our classes by inheriting from both, without telling either you or me. 其他人通过从两者继承来组成我们的类,而不告诉你或我。 My code still works, so does yours.
我的代码仍然有效,您的代码也是如此。
For further information, see the tutorial section on private variables , and the reference documentation on identifiers . 有关详细信息,请参阅有关私有变量的教程部分以及有关标识符的参考文档。
The only reason this wouldn't work exactly as you have it is because you're using attributes prefixed with __
, which makes them "private" and so not accessible to the parent class. 唯一的原因是它不能完全正常工作,因为你正在使用前缀为
__
属性,这使得它们“私有”,因此父类无法访问。 Don't do that: just use normal attribute names. 不要那样做:只使用普通的属性名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.