python私有属性可以被继承吗_Python中私有和受保护方法的继承

I know, there are no 'real' private/protected methods in Python. This approach isn't meant to hide anything; I just want to understand what Python does.

class Parent(object):

def _protected(self):

pass

def __private(self):

pass

class Child(Parent):

def foo(self):

self._protected() # This works

def bar(self):

self.__private() # This doesn't work, I get a AttributeError:

# 'Child' object has no attribute '_Child__private'

So, does this behaviour mean, that 'protected' methods will be inherited but 'private' won't at all?

Or did I miss anything?

解决方案

Python has no privacy model, there are no access modifiers like in C++, C# or Java. There are no truly 'protected' or 'private' attributes.

Names with a leading double underscore and no trailing double underscore are mangled to protect them from clashes when inherited. Subclasses can define their own __private() method and these will not interfere with the same name on the parent class. Such names are considered class private; they are still accessible from outside the class but are far less likely to accidentally clash.

Mangling is done by prepending any such name with an extra underscore and the class name (regardless of how the name is used or if it exists), effectively giving them a namespace. In the Parent class, any __private identifier is replaced (at compilation time) by the name _Parent__private, while in the Child class the identifier is replaced by _Child__private, everywhere in the class definition.

The following will work:

class Child(Parent):

def foo(self):

self._protected()

def bar(self):

self._Parent__private()

See Reserved classes of identifiers in the lexical analysis documentation:

__*

Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes.

Private name mangling: 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. This transformation is independent of the syntactical context in which the identifier is used.

Don't use class-private names unless you specifically want to avoid having to tell developers that want to subclass your class that they can't use certain names or risk breaking your class. Outside of published frameworks and libraries, there is little use for this feature.

The PEP 8 Python Style Guide has this to say about private name mangling:

If your class is intended to be subclassed, and you have attributes

that you do not want subclasses to use, consider naming them with

double leading underscores and no trailing underscores. This invokes

Python's name mangling algorithm, where the name of the class is

mangled into the attribute name. This helps avoid attribute name

collisions should subclasses inadvertently contain attributes with the

same name.

Note 1: Note that only the simple class name is used in the mangled

name, so if a subclass chooses both the same class name and attribute

name, you can still get name collisions.

Note 2: Name mangling can make certain uses, such as debugging and

__getattr__(), less convenient. However the name mangling algorithm

is well documented and easy to perform manually.

Note 3: Not everyone likes name mangling. Try to balance the need to

avoid accidental name clashes with potential use by advanced callers.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值