【问题标题】:What does underscoring methods connote?强调方法意味着什么?
【发布时间】:2011-06-28 09:15:46
【问题描述】:
我对 Python 语言比较陌生,在执行以下操作时遇到了这个问题:
help(list)
这是我遇到的:
__add__(...)
| x.__add__(y) <==> x+y
|
| __contains__(...)
| x.__contains__(y) <==> y in x
|
| __delitem__(...)
| x.__delitem__(y) <==> del x[y]
关于这些,下划线是干什么用的?因为当您正常使用方法时(据我所知)它们不会被使用,所以我很难理解为什么他们会花时间在文档中用下划线写出来。
【问题讨论】:
标签:
python
double-underscore
【解决方案1】:
这里是 Python 的创建者 Guido van Rossum,explaining the use of double underscores:
... 而不是设计一种新的语法
用于特殊类型的类方法
(例如初始化程序和
析构函数),我决定这些
功能可以简单地处理
要求用户实施
具有特殊名称的方法,例如
init、del 等等。此命名约定取自 C
其中标识符以
下划线由
编译器并且经常有特殊的
含义(例如,FILE 等宏
在 C 预处理器中)。
...
我还使用这种技术来允许用户类重新定义
Python 运算符的行为。作为
前面提到过,Python 是
用 C 实现并使用表
实现各种功能的函数指针
内置对象的能力
(例如,“获取属性”、“添加”和
“称呼”)。允许这些功能
在用户定义的类中定义,
我映射了各种函数指针
到特殊的方法名称,例如
getattr、add 和 call。这些之间有直接的对应关系
名称和功能表
指针必须定义何时
在 C 中实现新的 Python 对象。
另请参阅special method names 上的 Python 文档,其中部分内容如下:
一个类可以实现某些
由特殊调用的操作
语法(例如算术运算
或下标和切片)由
定义具有特殊名称的方法。
这是 Python 的操作符方法
重载,允许类
尊重地定义自己的行为
语言操作员。
【解决方案3】:
请参阅the Python style guide 以获得全面的解释。
在实践中:
the following special forms using leading or trailing
underscores are recognized (these can generally be combined with any case
convention):
- _single_leading_underscore: weak "internal use" indicator. E.g. "from M
import *" does not import objects whose name starts with an underscore.
- single_trailing_underscore_: used by convention to avoid conflicts with
Python keyword, e.g.
Tkinter.Toplevel(master, class_='ClassName')
- __double_leading_underscore: when naming a class attribute, invokes name
mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).
- __double_leading_and_trailing_underscore__: "magic" objects or
attributes that live in user-controlled namespaces. E.g. __init__,
__import__ or __file__. Never invent such names; only use them
as documented.
【解决方案4】:
在某种程度上,这些下划线并没有什么特别之处;它们只是方法名称的一部分。
但是,它们用于表示“神奇”的方法,例如构造函数和重载运算符。您不应该在自己的方法名称中使用它们。来自PEP 8:
-
__double_leading_and_trailing_underscore__:“魔法”物体或
存在于用户控制的命名空间中的属性。例如。 __init__,
__import__ 或 __file__。永远不要发明这样的名字;只使用它们
记录在案。
您很少需要直接调用其中任何一个。例如:
-
MyClass(...) 会打电话给MyClass.__init__(...),
-
a + b 会打电话给a.__plus__(b),
-
str(a) 将调用 a.__str__()。
【解决方案5】:
They are special methods(不是“dunder”(双下划线)使它们特别,但大多数情况下它们具有特殊含义)。使用运算符时通常会调用它们。您可以覆盖类中的行为。
例如,如果你有一个类C,通过定义
class C:
def __add__(self, other):
#....
return something
你可以定义如果你从类中添加两个实例会发生什么:
val = instance1 + instance2
【解决方案6】:
用下划线包裹方法名称只是分隔命名空间的一种方式。如果方法以下划线开头和结尾,这只是一种约定,表明该方法不打算由外部代码使用。
您发布的help(list) 的简介仅意味着当您使用 Python 的语法说 e in lst 时,您实际上是在调用 lst.__contains__(e)。