私有名称改名有什么好处?
Python为类的方法和属性提供了一种叫做“私有名称改名”的功能。
那么,有没有具体的例子说明这个功能是必须的,还是说它只是从Java和C++那边带过来的?
请描述一个使用Python名称改名的场景,如果有的话?
另外,我不想讨论那种作者只是想防止外部意外访问属性的情况。我觉得这种用法和Python的编程模型不太一致。
4 个回答
4
之前的所有回答都是对的,但这里还有一个原因和例子。名字改编(Name Mangling)在Python中是必要的,因为它可以避免因为重写属性而引发的问题。换句话说,为了能够重写,Python解释器需要能够为子类的方法和父类的方法生成不同的标识符,而使用双下划线(__)可以让Python做到这一点。在下面的例子中,如果没有__help,这段代码就无法正常工作。
class Parent:
def __init__(self):
self.__help("will take child to school")
def help(self, activities):
print("parent",activities)
__help = help # private copy of original help() method
class Child(Parent):
def help(self, activities, days): # notice this has 3 arguments and overrides the Parent.help()
self.activities = activities
self.days = days
print ("child will do",self.activities, self.days)
# the goal was to extend and override the Parent class to list the child activities too
print ("list parent & child responsibilities")
c = Child()
c.help("laundry","Saturdays")
15
来自 PEP 8 的内容:
如果你的类是为了让其他类来继承的,并且你有一些属性不希望被子类使用,那么可以考虑用两个下划线开头的名字来命名这些属性,而不要在名字后面加下划线。这样做会触发Python的名字改编机制,也就是说,类的名字会被加到属性的名字前面。 这样可以避免子类不小心使用了相同名字的属性,从而造成名字冲突。
(强调部分)
30
这样做部分是为了防止不小心访问到内部属性。这里有个例子:
在你的代码中,也就是一个库:
class YourClass:
def __init__(self):
self.__thing = 1 # Your private member, not part of your API
在我的代码中,我是从你的库类继承过来的:
class MyClass(YourClass):
def __init__(self):
# ...
self.__thing = "My thing" # My private member; the name is a coincidence
如果没有私有名称的处理,我不小心用了你的名字,就会导致你的库出问题。