【问题标题】: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

... 而不是设计一种新的语法 用于特殊类型的类方法 (例如初始化程序和 析构函数),我决定这些 功能可以简单地处理 要求用户实施 具有特殊名称的方法,例如 initdel 等等。此命名约定取自 C 其中标识符以 下划线由 编译器并且经常有特殊的 含义(例如,FILE 等宏 在 C 预处理器中)。

...

我还使用这种技术来允许用户类重新定义 Python 运算符的行为。作为 前面提到过,Python 是 用 C 实现并使用表 实现各种功能的函数指针 内置对象的能力 (例如,“获取属性”、“添加”和 “称呼”)。允许这些功能 在用户定义的类中定义, 我映射了各种函数指针 到特殊的方法名称,例如 getattraddcall。这些之间有直接的对应关系 名称和功能表 指针必须定义何时 在 C 中实现新的 Python 对象。

另请参阅special method names 上的 Python 文档,其中部分内容如下:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案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)

            【讨论】:

              猜你喜欢
              • 2014-02-23
              • 2013-04-11
              • 1970-01-01
              • 2023-03-10
              • 2011-08-28
              • 2021-11-04
              • 2018-07-05
              • 1970-01-01
              • 2020-06-01
              相关资源
              最近更新 更多