相关文章推荐
玩滑板的皮带  ·  帮助系统·  4 月前    · 
不敢表白的葫芦  ·  excel 80080005 ...·  1 年前    · 
淡定的充电器  ·  Auto.js ...·  1 年前    · 
非常酷的大象  ·  Mr. LAM Ho Yan Walter ...·  2 年前    · 

为什么python在某些事情上使用两个下划线?

我对实际的编程语言还很陌生,而Python是我的第一个。 我对Linux有一点了解,足以应付暑假(我还在读高中),而且在工作中,我有很多空闲时间用来学习Python。

一件事一直让我迷失。 当您拥有以下表达式时,Python中到底有什么不同?

x.__add__(y) <==> x+y

x.__getattribute__('foo') <==> x.foo

我知道什么方法可以做什么,我知道它们可以做什么,但是我的问题是:上面的双下划线方法和它们看上去更简单的等效方法有什么不同?

附言:我不介意关于编程历史的讲座,实际上,我发现了解它非常有用:)如果这些主要是Python的历史方面,请随时开始学习。

7个解决方案

29 votes

这是Python的创建者对其进行解释:

...而不是为   特殊的类方法(例如   作为初始化程序和析构函数),我   决定这些功能可能是   只需要求用户即可处理   用特殊的方法来实现   名称,例如__getattr__、__add__和   等等。 该命名约定是   取自C where标识符   下划线开头保留   由编译器执行,通常会有特殊的   含义(例如,诸如   C预处理程序中的__call__)。

我也使用这种技术来允许   用户类以重新定义行为   Python的运算符。 如从前那样   注意,Python是用C实现的,   使用函数指针表   实现各种功能   内置对象(例如“ get   属性”,“添加”和“通话”)。 至   允许定义这些功能   在用户定义的类中,我将   各种特殊的功能指针   方法名称,例如__getattr__,   __add__和__call__。有一个   这些之间的直接对应   名称和功能表   指针必须定义何时   在C中实现新的Python对象。

Steven Rumbalski answered 2020-01-20T23:45:18Z

16 votes

当您使用两个下划线(而没有下划线)启动方法时,将应用Python的名称处理规则。 这是一种从其他OO语言(例如C ++和Java)大致模拟private关键字的方法。 (即使如此,该方法在技术上仍然不像Java和C ++方法是私有的那样是私有的,但是从实例外部“很难达到”。)

具有两个前导下划线和两个下划线的方法被认为是“内置”方法,也就是说,它们由解释器使用,并且通常是重载运算符或其他内置功能的具体实现。

mipadi answered 2020-01-20T23:45:44Z

7 votes

好吧,对于程序员来说,力量是件好事,因此应该有一种自定义行为的方法。 像运算符重载(__add__、__div__、__ge__,...),属性访问(__getattribute__、__getattr__(这两个是不同的),__delattr__,...)等。在许多情况下,例如运算符,通常的语法映射为1:1 相应的方法。 在其他情况下,存在一个特殊的过程,该过程有时涉及调用相应的方法-例如,仅当对象不具有请求的属性并且__getattribute__没有实现或引发AttributeError时才调用__getattr__。 其中一些是真正的高级主题,可让您深入了解对象系统的勇气,而很少需要它们。 因此,无需全部学习,只需在需要/想要知道时参考参考。 说到参考,就在这里。

answered 2020-01-20T23:44:43Z

4 votes

它们用于指定Python解释器在特定情况下应使用它们。

例如,__add__函数允许+运算符为自定义类工作。 否则,尝试添加时会出现某种未定义的错误。

Paul Nathan answered 2020-01-20T23:46:08Z

3 votes

从历史的角度来看,前导下划线经常被用作向程序员指示将名称视为定义它们的包/模块/库内部的一种方法。 在不能为私有名称空间提供良好支持的语言中,使用下划线是一种模拟惯例。 在Python中,当您定义一个名为“ __foo__”的方法时,维护程序员会从名称中得知发生了一些特殊的事情,而使用“ foo”的方法并没有发生这种情况。 如果Python选择使用'add'作为内部方法来重载'+',那么您将永远不会有一个带有'add'方法的类而不会引起很多混乱。 下划线提示某些魔术会发生。

William Pursell answered 2020-01-20T23:46:30Z

1 votes

现在,还有许多其他问题被标记为该问题的重复项,并且至少有两个问题询问了__add__方法的调用方式或约定的名称,而现有的答案都没有涵盖这一点,因此:

两者实际上都没有正式名称。

许多开发人员非正式地将它们称为“双重方法”,即“双UNDERscore”。

有些人使用“魔术方法”一词,但这在含糊的含义方法,特殊方法(请参阅下文)或两者之间的某些含义之间有些歧义。

有一个官方术语“特殊属性”,与dunder方法紧密但不完全重叠。 参考资料中的“数据模型”一章从不完全解释什么是特殊属性,但基本思想是至少具有以下一项:

由解释器本身或其内置代码提供的属性,例如函数上的__add__。

属性是解释程序本身实现的协议的一部分,例如+运算符的__add__或用于索引和切片的pickle。

通过忽略实例并直接转到类,允许解释器专门查找的属性,例如再次返回pickle。

大多数特殊属性是方法,但不是全部(例如,不是pickle)。 而且大多数都使用“ dunder”约定,但不是全部(例如,Python 2.x中的迭代器上的next方法)。

同时,大多数dunder方法都是特殊属性,但不是全部-特别是,stdlib或外部库希望定义自己的以相同方式工作的协议(例如2711639430519019063552协议)并不少见。

abarnert answered 2020-01-20T23:47:32Z

0 votes

[推测] Python受Algol68的影响,Guido可能在阿姆斯特丹大学使用过Algol68,其中Algol68具有类似的“踩踏状态”,称为“ Quote踩踏”。 在Algol68中,运算符,类型和关键字可以使用不同的字体显示(通常是**或__underlined__),在源代码文件中,该字体使用引号来实现,例如 'abs'(引用类似于'wikitext'中的引用)

Algol68⇒Python(运算符映射到成员函数)

'和'⇒__and__

'或'⇒__或__

'不'⇒不

'整个'⇒__trunc__

'shl'⇒__lshift__

'shr'⇒__rshift__

'upb'⇒__sizeof__

'long'⇒__long__

'int'⇒__int__

'真实'⇒__float__

'格式'⇒__格式__

'repr'⇒__repr__

'abs'⇒__abs__

负号⇒负__

减号⇒__sub__

加号⇒__添加__

'时间'⇒__mul__

'mod'⇒__mod__

'div'⇒__truediv__

'结束'⇒__div__

'上'⇒__pow__

'im'⇒意象

're'⇒真实

'conj'⇒共轭

在Algol68中,这些被称为粗体名称,例如 abs,但在python中是“ under-under-abs” __ abs__。

我的2分:¢有时,就像幽灵一样,当您将python类剪切并粘贴到Wiki中时,您会神奇地重新生成Algol 68粗体关键字。 ¢

NevilleDNZ answered 2020-01-20T23:49:50Z

在看一些 Python 开源代码时,经常会看到以 下划线 或者双 下划线 开头的方法或者属性,到底它们有什么作用,又有什么样的区别呢?今天我们来总结一下(注:下文中的代码在 Python 3下测试通过) _ 的含义 在 python 的类中没有真正的私有属性或方法,没有真正的私有化。 但为了编程的需要,我们常常需要区分私有方法和共有方法以方便管理和调用。那么在 Python 中如何做呢? 一般 Python 约定加了 下划线 _ 的属性和方法为私有方法或属性,以提示该属性和方法不应在外部调用,也不会被from ModuleA import * 导入。如果真的调用了也不会出错,但不符合规范。 下面的代码演示加了_ 的方法, 这篇文章给大家介绍 python 中单 下划线 _,具体内容如下所示: 我们在阅读源码的时候经常会看到各种单 下划线 _的 使用 ,所以今天特地做一个总结,而且其实很多(不是所有)关于 下划线 使用 都是一些约定俗成的惯例,而不是真正对 python 解释器有影响。 0x1存储上一条语句的执行结果 在 python 的解释器中,_是上一条语句的执行结果,最早是C Python 施行,到现在其他类型的解释器也在 使用 0x02作为一个无关紧要的变量 例如下面这个例子: for _ in range(10): print 'hello world!' 上面的语句执行结果是在屏幕上打印十行hello world,我们并不 下标在 Python 编程中是从0开始依次按顺序向后分配的,比如一个字符串str1 = ’abcde’,那么字符a的下标就是0,字符b的下标是1,字符c的下标是2,字符d的下标是3,字符e的下标是4。 1.常识字符编码问题 python 3兼容utf-8编码,支持中文,但 python 2不支持,如果想兼容 python 2,则需要在程序开头写入:#--coding=utf-8--安装 python 后运行栏输入 python 进入 python 交互式环境输入exit()退出 python 环境运行py文件任何一个文本编辑器都可以写 python 创建一个后缀名为py的文件就是 python 的标准的文件可以在命令行输入pyth... 下标所谓下标就是编号,就好比超市中存储柜的编号,通过这个编号就能找到相应的存储空间。 Python 中字符串,列表,元祖均支持下标索引。例如:# 如果想取出部分字符,可 使用 下标name="abcd"print(name[0])print(name[1])print(name[2])print(name[3])# 输出结果为:# a# b# c# d切片切片是指对操作的对象截取一部分的操作,字符串,列表... 1. 概述 在 Python 经常能见到含 下划线 (underscore)修饰的的变量和方法(如__name__,_var等),这些 下划线 的作用称之为名字修饰(name decoration)。在 Python 中,名字修饰通常有以下几种情况: 单前缀 下划线 (single leading underscore):_var 单后缀 下划线 (single trailingunderscore):var_ 双前缀 下划线 (double leading underscores):__var 双前缀+双后缀 下划线 (dou 原文地址:https://dbader.org/blog/meaning-of-underscores-in- python 作者:Dan Bader译者:首席IT民工本文介绍了 Python 中单 下划线 和双 下划线 ("dunder")的各种含义和命名约定,名称修饰(name mangling)的工作原理,以及它如何影响你自己的 Python 类。单 下划线 和双 下划线 Python 变量和方法名称中都各有其含义。有...