以___开头和结尾的方法

时间:2012-03-03 18:44:14

标签: python

我注意到在Python中,一些基本类型有两种类型的方法:被__包围的方法和不包含方法的方法。

例如,如果我有一个名为float的{​​{1}}类型的变量,我可以在IPython中看到它有以下方法:

my_number
  1. my_number.__abs__ my_number.__pos__ my_number.__add__ my_number.__pow__ my_number.__class__ my_number.__radd__ my_number.__coerce__ my_number.__rdiv__ my_number.__delattr__ my_number.__rdivmod__ my_number.__div__ my_number.__reduce__ my_number.__divmod__ my_number.__reduce_ex__ my_number.__doc__ my_number.__repr__ my_number.__eq__ my_number.__rfloordiv__ my_number.__float__ my_number.__rmod__ my_number.__floordiv__ my_number.__rmul__ my_number.__format__ my_number.__rpow__ my_number.__ge__ my_number.__rsub__ my_number.__getattribute__ my_number.__rtruediv__ my_number.__getformat__ my_number.__setattr__ my_number.__getnewargs__ my_number.__setformat__ my_number.__gt__ my_number.__sizeof__ my_number.__hash__ my_number.__str__ my_number.__init__ my_number.__sub__ my_number.__int__ my_number.__subclasshook__ my_number.__le__ my_number.__truediv__ my_number.__long__ my_number.__trunc__ my_number.__lt__ my_number.as_integer_ratio my_number.__mod__ my_number.conjugate my_number.__mul__ my_number.fromhex my_number.__ne__ my_number.hex my_number.__neg__ my_number.imag my_number.__new__ my_number.is_integer my_number.__nonzero__ my_number.real 包围的那些与不包含的那些之间有什么区别?
  2. 这是其他编程语言中使用的某种标准吗?在类似的语言中它通常意味着相同吗?

6 个答案:

答案 0 :(得分:3)

  1. 通常,Python内部使用“双下划线”方法用于某些内置函数或运算符(例如__add__定义+的行为)。没有双下划线的那些只是运算符或内置函数不会使用的常规方法。现在,这些方法仍然是“普通”方法,因为你可以像任何其他方法一样调用它们,但是Python核心的一部分会特别对它们进行处理。
  2. 不,据我所知,这是Python独有的,虽然许多其他语言支持类似的想法(内置/运算符重载)但是通过不同的机制。
  3. 无耻的插件:去年我写了一篇关于Python这个方面的指南非常全面,你可以在http://rafekettler.com/magicmethods.html阅读有关如何在你自己的对象上使用这些方法的内容。

答案 1 :(得分:2)

来自文档:

  

某些类别的标识符(除了关键字)有特殊之处   含义。这些类由领导和模式识别   尾随下划线字符:

     

_ *

     

未从模块导入*导入。特殊标识符_在交互式解释器中用于存储最后一个的结果   评价;它存储在内置模块中。什么时候不在   交互模式,_没有特殊含义,也没有定义。看到   section import语句。

     

注意名称_通常与国际化一起使用;请参阅gettext的文档   模块以获取有关此约定的更多信息。

     

__ * __

     

系统定义的名称。这些名称由解释器及其实现(包括标准库)定义。当前   系统名称在特殊方法名称部分和   别处。更多可能会在未来的Python版本中定义。   在任何上下文中都不使用 * 名称   明确记录使用,可能会在没有警告的情况下破损。

     

__ *

     

班级私人名称。当在类定义的上下文中使用时,此类别中的名称将被重写以使用损坏的表单   帮助避免基础和“私有”属性之间的名称冲突   派生类。请参阅标识符(名称)部分。

http://docs.python.org/reference/lexical_analysis.html#reserved-classes-of-identifiers

答案 2 :(得分:1)

这些是在特定上下文中调用的特殊方法。

Read the documentation for the details.

  

一个类可以实现特殊调用的某些操作   语法(如算术运算或下标和切片)   定义具有特殊名称的方法。这是Python的方法   运算符重载,允许类定义自己的行为   关于语言运营者。例如,如果一个类定义了一个   名为__getitem__()的方法,然后x是此类的实例   对于旧式类,x[i]大致相当于x.__getitem__(i)   和type(x).__getitem__(x, i)用于新式课程。除外   提到,尝试执行操作会在没有时引发异常   定义了适当的方法(通常为AttributeErrorTypeError)。

答案 3 :(得分:1)

要回答第二个问题,此约定在C中使用,其中包含__FILE__等宏。 Python的创建者Guido van Rossum明确表示这是他blog on the history of Python中的灵感。

答案 4 :(得分:1)

1)你所说的__ * __变量是系统变量或方法。

引用Python参考指南:

  

系统定义的名称。这些名称由解释器及其实现(包括标准库)定义;应用程序不应期望使用此约定定义其他名称。 Python定义的这个类的名称集可以在将来的版本中扩展。

基本上它们是系统预先定义的变量或方法。例如,系统变量__name__可以在任何函数中使用,并且始终包含该函数的名称。您可以找到更全面的信息和示例here

2)系统保留变量的概念在大多数编程语言中都是基础。例如,PHP将它们称为Magic Constants。上面的Python示例获取函数名称可以使用__FUNCTION__在PHP中实现。更多示例here

答案 5 :(得分:-2)

用于表示属性是内部的。 python中没有实际的隐私,因此这些用作提示,表示内部而不是api方法。