为什么在名称前面有双下划线时传递 keyword/named 参数会产生错误?

Why does passing keyword/named arguments produce error when name has double underscores prior to the name?

在 运行 使用交易算法时,我 运行 遇到了以下问题,我试图通过以下方式重现:

假设我有一个名为 algo1.py 的算法和另一个名为 algo2.py.

的算法

这里是 algo2.py...

class mathOperations():

    def __init__(self):
        self.value = 0

    def sum(self, __a = 0, __b = 0):
        return (__a + __b)

这里是algo1.py...

from algo2 import mathOperations


math = mathOperations()
print(math.sum(__a = 56, __b = 44))

当我 运行 algo1.py 时,我收到以下消息:

Traceback (most recent call last):
  File "algo1.py", line 5, in <module>
    print(math.sum(__a = 56, __b = 67))
TypeError: sum() got an unexpected keyword argument '__a'

但是,当我从两种算法中的命名参数前面删除“__”或两个下划线时,此错误就会消失。有人可以向我解释为什么吗?

请参阅有关 name mangling 的文档:

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. If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen. If the class name consists only of underscores, no transformation is done.

这解释了为什么。这个奇怪的特性首先存在的原因在教程 here 中有所描述(TL;DR:避免名称与子类定义的名称冲突是一种 hack)。

解决方法很简单:在定义方法的参数时,不要使用带有两个前导下划线的名称。