Trouple访问python超类属性 [英] Trouple accessing python superclass attributes
问题描述
我有两个类松散地采用以下形式:
I have two classes that loosely take the form below:
class Foo:
def __init__(self, foo):
self.__foo = foo
class Bar(Foo):
def bar(self):
print self.__foo
当我尝试调用栏时在
Bar
的实例上的code>方法,它失败。
When I try to invoke the bar
method on an instance of Bar
, it fails.
b = Bar('foobar')
b.bar()
结果:
Traceback (most recent call last):
File "foobar.py", line 14, in <module>
b.bar()
File "foobar.py", line 10, in bar
print self.__foo
AttributeError: Bar instance has no attribute '_Bar__foo'
My understanding is that this code should work based on two other questions, why doesn't it?
推荐答案
简单。 __ foo
在开头包含2个下划线,因此它被假定为class-private方法,并且它被转换为 _Classname__method
。
Simple. __foo
contains 2 underscores in the beginning, so it's assumed to be class-private method and it's transformed into _Classname__method
.
当您在 Bar
对象上请求访问名为此类的属性时,它会询问 Bar
类如果它有这个方法(不是 Foo
类),那么 self .__ foo
是始终与 self._Bar__foo
相同。
When you request access to the attribute named as such on Bar
object it asks Bar
class if it has this method (not Foo
class), so self.__foo
is always the same as self._Bar__foo
.
来自文档:
在类定义中以文本方式出现的标识符以两个或多个下划线字符开头
,并且不以两个或更多
下划线结尾,它被视为该类的私有名称。在为
生成代码之前,将私有
名称转换为更长的形式。转换插入类名,在
名称前面删除了前导
下划线并插入了一个下划线。例如,名为
Ham的类中出现的标识符__spam将转换为_Ham__spam。
When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier __spam occurring in a class named Ham will be transformed to _Ham__spam.
如果修改代码稍微
class Foo:
def __init__(self, foo):
self.__foo = foo
assert hasattr(self, '_Foo__foo'), 'Attribute has been just created'
class Bar(Foo):
def bar(self):
assert hasattr(self, '_Foo__foo'), 'No errors, thanks to inheritance'
assert
语句不会导致任何 AssertionError
s。
assert
statements will not cause any AssertionError
s.
添加 __ getattribute __
方法到 Bar
类来捕获对 Bar的所有请求
对象:
Add __getattribute__
method to Bar
class to capture all requests to Bar
objects:
class Bar(Foo):
def bar(self):
print('Accessing __foo from bar')
print(self.__foo)
def __getattribute__(self, name):
print('Requested', name)
return super().__getattribute__(name)
b = Bar('foobar')
b.bar()
输出中将有3行(除了 AttributeError
):
There will be 3 lines (apart from AttributeError
) in the output:
Requested bar
Accessing __foo from bar
Requested _Bar__foo # AttributeError follows
正如您所看到的,如果您要求的属性有2个前导下划线,则Python会立即重命名。
As you can see, if attribute you are requesting has 2 leading underscores, Python is renaming it on the fly.
这篇关于Trouple访问python超类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!