5

我对 Python 语言比较陌生,并且在执行以下操作时遇到了这个问题:

help(list)

这是我遇到的:

__add__(...)
|      x.__add__(y) <==> x+y
|  
|  __contains__(...)
|      x.__contains__(y) <==> y in x
|  
|  __delitem__(...)
|      x.__delitem__(y) <==> del x[y]

关于这些,下划线是干什么用的?因为当您正常使用方法时(据我所知)它们不会被使用,所以我很难理解为什么他们会花时间在文档中用下划线写出它们。

4

6 回答 6

10

请参阅Python 样式指南以获得全面的解释。

在实践中:

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.
于 2011-02-16T13:56:03.130 回答
3

用下划线包裹方法名称只是分隔命名空间的一种方式。如果一个方法以下划线开头和结尾,这只是一个约定,表明该方法不打算由外部代码使用。

您发布的简介help(list)只是意味着当您使用 Python 的语法说e in lst时,您实际上是在调用lst.__contains__(e).

于 2011-02-16T13:53:26.183 回答
2

这是 Python 的创建者 Guido van Rossum解释双下划线的使用

...与其为特殊类型的类方法(例如初始化程序和析构函数)设计新语法,我决定可以通过简单地要求用户实现具有特殊名称的方法(例如 initdel等)来处理这些功能向前。这种命名约定取自 C,其中以下划线开头的标识符由编译器保留,并且通常具有特殊含义(例如,宏,如C 预处理器中的FILE )。

...

我还使用这种技术来允许用户类重新定义 Python 运算符的行为。如前所述,Python 是用 C 实现的,并使用函数指针表来实现内置对象的各种功能(例如,“get attribute”、“add”和“call”)。为了允许在用户定义的类中定义这些功能,我将各种函数指针映射到特殊方法名称,例如 getattraddcall。这些名称与在 C 中实现新的 Python 对象时必须定义的函数指针表之间存在直接对应关系。

另请参阅有关特殊方法名称的 Python 文档,其中部分内容如下:

一个类可以通过定义具有特殊名称的方法来实现由特殊语法(例如算术运算或下标和切片)调用的某些操作。这是 Python 的运算符重载方法,允许类根据语言运算符定义自己的行为。

于 2011-02-16T14:58:42.303 回答
0

在这种情况下,双下划线用作表示特殊方法的约定 - 为支持语法糖目的和其他特殊接口而实现的方法。

http://docs.python.org/reference/datamodel.html#specialnames

于 2011-02-16T13:56:05.550 回答
0

它们是特殊的方法(不是“dunder”(双下划线)使它们特别,但大多数情况下它们具有特殊含义)。使用运算符时通常会调用它们。您可以覆盖类中的行为。

例如,如果你有一个类C,通过定义

class C:
    def __add__(self, other):
        #....
        return something

如果从类中添加两个实例,您可以定义会发生什么:

val = instance1 + instance2
于 2011-02-16T13:55:36.160 回答
0

在某种程度上,这些下划线并没有什么特别之处;它们只是方法名称的一部分。

但是,它们用于表示“神奇”的方法,例如构造函数和重载运算符。您不应该在自己的方法名称中使用它们。从PEP 8开始:

  • __double_leading_and_trailing_underscore__: 存在于用户控制的命名空间中的“神奇”对象或属性。例如__init____import____file__。永远不要发明这样的名字;仅按记录使用它们。

您很少需要直接调用其中任何一个。例如:

  • MyClass(...)会打电话MyClass.__init__(...)
  • a + b会打电话a.__plus__(b)
  • str(a)会打电话a.__str__()
于 2011-02-16T13:55:48.563 回答