Ste*_*ini 42 language-agnostic name-mangling
请解释什么是名称修改,它是如何工作的,它解决了什么问题,以及使用了哪些上下文和语言.名称修改策略(例如编译器选择的名称和原因)加号.
Nor*_*sey 37
在您选择的编程语言中,如果标识符是从单独编译的单元导出的,则它需要一个在链接时通知它的名称.名称修改解决了编程语言中重载标识符的问题.(如果在多个上下文中使用相同的名称或具有多个含义,则标识符将"重载".)
一些例子:
在C++中,函数或方法get
可能会以多种类型重载.
在Ada或Modula-3中,功能get
可能出现在多个模块中.
多种类型和多个模块涵盖了通常的上下文.
典型策略:
将每种类型映射到字符串,并使用组合的高级标识符和"type string"作为链接时名称.在C++中很常见(特别容易,因为只允许对函数/方法进行重载,而且只允许在参数类型上使用)和Ada(在这里你也可以重载结果类型).
如果在多个模块或命名空间中使用标识符,请使用标识符的名称加入模块的名称,例如,List_get
而不是List.get
.
根据链接时名称中哪些字符合法,您可能需要进行额外的修改; 例如,可能需要使用下划线作为"转义"字符,以便您可以区分
List_my.get
- > List__my_get
从
List.my_get
- > List_my__get
(不可否认,这个例子已经到了,但作为编译器编写者,我必须保证源代码中的不同标识符映射到不同的链接时名称.这就是名称修改的全部原因和目的.)
在python中,名称修改是一个系统,通过该系统,类变量在类内外具有不同的名称。程序员通过在变量名的开头放置两个下划线来“激活”它。
例如,我可以定义一个包含一些成员的简单类:
>>> class Foo(object):
... def __init__(self):
... self.x = 3
... self._y = 4
... self.__z = 5
...
Run Code Online (Sandbox Code Playgroud)
在 Python 实践中,以下划线开头的变量名是“内部的”,而不是类接口的一部分,因此程序员不应依赖它。但是,它仍然可见:
>>> f = Foo()
>>> f.x
3
>>> f._y
4
Run Code Online (Sandbox Code Playgroud)
以两个下划线开头的变量名仍然是公开的,但它是名称混乱的,因此更难访问:
>>> f.__z
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__z'
Run Code Online (Sandbox Code Playgroud)
但是,如果我们知道名称修改的工作原理,我们就可以了解它:
>>> f._Foo__z
5
Run Code Online (Sandbox Code Playgroud)
即类名在变量名前面加上一个额外的下划线。
Python 没有“私有”成员与“公共”成员的概念;一切都是公开的。名称修改是程序员可以发送的最强信号,表明不应从类外部访问该变量。