Python为类方法和属性提供了private name mangling。
是否有任何需要此功能的具体情况,或者它只是Java和C ++的延续?
请描述一个应该使用Python名称修改的用例,如果有的话?
另外,我对作者仅仅试图阻止意外外部属性访问的情况不感兴趣。我相信这个用例与Python编程模型不一致。
答案 0 :(得分:24)
部分原因是为了防止意外的内部属性访问。这是一个例子:
在您的代码中,它是一个库:
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
如果没有私人名称错误,我意外重复使用您的名字会破坏您的图书馆。
答案 1 :(得分:16)
来自PEP 8:
如果您的类要进行子类化,并且您具有不希望使用子类的属性,请考虑使用双前导下划线和没有尾随下划线来命名它们。这将调用Python的名称修改算法,其中类的名称被修改为属性名称。 如果子类无意中包含具有相同名称的属性,这有助于避免属性名称冲突。
(强调补充)
答案 2 :(得分:2)
所有先前的答案都是正确的,但这是另一个例子。在python中需要名称重整,因为可以避免由于覆盖属性而引起的问题。换句话说,为了重写,Python解释器必须能够为子方法和父方法建立不同的id,并使用__(双下划线)使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")
答案 3 :(得分:0)
名称mangling用于防止意外的外部属性访问。大多数情况下,它确保没有名称冲突。