在对象名称之前,单个和双重下划线的含义是什么?
在Python中对象的名称代表之前,单个和双重领导下指标是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
在Python中对象的名称代表之前,单个和双重领导下指标是什么?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(19)
一类中的单个下划线
,带有领先下划线的名称向其他程序员表示属性或方法旨在在该类中使用。但是,隐私不是任何方式执行的。
在模块中使用领先的下划线进行功能表明不应从其他地方导入它。
来自 pep-8 样式指南:
double double dusterscore(name mangling)
并从同一页面发出警告:
示例
Single Underscore
In a class, names with a leading underscore indicate to other programmers that the attribute or method is intended to be be used inside that class. However, privacy is not enforced in any way.
Using leading underscores for functions in a module indicates it should not be imported from somewhere else.
From the PEP-8 style guide:
Double Underscore (Name Mangling)
From the Python docs:
And a warning from the same page:
Example
_foo
:只有一个约定。程序员表明该变量是私有的一种方法(无论在Python中意味着什么)。__ foo
:这具有真正的含义。解释器用_CLASSNAME__FOO
替换此名称,以确保名称不会与其他类中的类似名称重叠。__ foo __
:仅是约定。 Python系统使用不会与用户名相冲突的名称的一种方法。在Python世界中,没有其他形式的下划线具有意义。同样,在这些惯例中,类,变量,全球等之间没有区别。
_foo
: Only a convention. A way for the programmer to indicate that the variable is private (whatever that means in Python).__foo
: This has real meaning. The interpreter replaces this name with_classname__foo
as a way to ensure that the name will not overlap with a similar name in another class.__foo__
: Only a convention. A way for the Python system to use names that won't conflict with user names.No other form of underscores have meaning in the Python world. Also, there's no difference between class, variable, global, etc in these conventions.
到目前为止,出色的答案,但缺少一些花絮。单个领先的下划线不完全 一个惯例:如果您从foobar import *中使用
,而模块
foobar
不定义__所有__
列表,从模块导入的名称 不包括带有领先下划线的名称。假设这是主要是的惯例,因为这种情况是一个非常晦涩的角落;-)。领先的condent惯例不仅被广泛用于 private 名称,还用于C ++所谓的受保护的名称 - 例如,完全旨在完全旨在的方法的名称被子类(即使是已经被覆盖的子类)覆盖,因为在基类中,它们
提高noctimplementedError
! - )通常是单个Leading-underScore名称,以指示代码<强>使用该类别(或子类)的实例,该类别并非直接调用所述方法。例如,要使与FIFO不同的排队纪律制作线程安全队列,One inovers queue,subclasses queue.queue.queue和覆盖
_get> _get
和_put> _put
之类的方法; “客户端代码”从不调用这些(“钩”)方法,而是(“组织”)公共方法,例如put
和get
(这被称为< a href =“ http://en.wikipedia.org/wiki/wiki/template_method_pattern” rel =“ noreferrer”> template方法设计模式 - 请参阅eg 此处 基于关于我的主题的谈论的视频,并添加了有趣的演讲成绩单的概念)。编辑:谈判描述中的视频链接现在被打破。您可以找到前两个视频在这里 .youtube.com/watch?v = tjxhtncdbu4“ rel =“ noreferrer”>在这里。
Excellent answers so far but some tidbits are missing. A single leading underscore isn't exactly just a convention: if you use
from foobar import *
, and modulefoobar
does not define an__all__
list, the names imported from the module do not include those with a leading underscore. Let's say it's mostly a convention, since this case is a pretty obscure corner;-).The leading-underscore convention is widely used not just for private names, but also for what C++ would call protected ones -- for example, names of methods that are fully intended to be overridden by subclasses (even ones that have to be overridden since in the base class they
raise NotImplementedError
!-) are often single-leading-underscore names to indicate to code using instances of that class (or subclasses) that said methods are not meant to be called directly.For example, to make a thread-safe queue with a different queueing discipline than FIFO, one imports Queue, subclasses Queue.Queue, and overrides such methods as
_get
and_put
; "client code" never calls those ("hook") methods, but rather the ("organizing") public methods such asput
andget
(this is known as the Template Method design pattern -- see e.g. here for an interesting presentation based on a video of a talk of mine on the subject, with the addition of synopses of the transcript).Edit: The video links in the description of the talks are now broken. You can find the first two videos here and here.
._变量
是半剥夺的,仅对于惯例.__变量
通常被错误地考虑到超级私人,而其实际含义仅是namemangle到防止意外访问 [1].__
.__
您仍然可以访问
。双重下调的只是namemangles或命名,将变量添加到
instance._classname__mangled
示例:
t._b是可以访问的,因为它仅被限制
t .__ a隐藏,因为它不再存在,因为它不再存在由于
通过访问
instance._classname__variable
而不仅仅是双重下划线名称,因此您可以访问隐藏值._variable
is semiprivate and meant just for convention.__variable
is often incorrectly considered superprivate, while its actual meaning is just to namemangle to prevent accidental access[1].__variable__
is typically reserved for builtin methods or variablesYou can still access
.__mangled
variables if you desperately want to. The double underscores just namemangles, or renames, the variable to something likeinstance._className__mangled
Example:
t._b is accessible because it is only hidden by convention
t.__a isn't found because it no longer exists due to namemangling
By accessing
instance._className__variable
instead of just the double underscore name, you can access the hidden value一开始的单个下划线:
Python没有真正的私人方法。取而代之的是,一个方法或属性名称的开头一个下划线意味着您不应该访问此方法,因为它不是API的一部分。
(此代码段是从Django源代码:django/forms/forms.py取的)。在此代码中,
错误
是公共属性,但是该属性调用的方法是_get_errors,是“私有的”,因此您不应访问它。一开始两个下划线:
这引起了很多混乱。它不应用于创建私人方法。应该使用它来避免您的方法被子类覆盖或意外访问。让我们看看一个示例:
输出:
现在创建一个子类B并为__ -test方法进行自定义,
输出将为...
如我们所见,b.test()未调用b .__ test()方法,因为我们可能期望。但是实际上,这是__的正确行为。称为__test()的两种方法会自动重命名为_a__test()和_b__ -test(),因此它们不会偶然地覆盖。当您创建一个以__开头的方法时,意味着您不希望任何人能够覆盖它,而您只打算从自己的课堂内访问它。
在开始时和结尾处有两个下划线:
当我们看到类似
> __ this __
的方法时,请勿调用。这是Python打算致电的方法,而不是您。让我们看一下:总有一个称为这些魔术方法的操作员或本机功能。有时候,这只是在特定情况下打电话的钩子。例如,当
__ init __()
在__ new __()
之后创建对象时,请调用来构建实例...让我们以示例...
有关更多详细信息,以获取更多详细信息,请参阅 pep-8指南 。有关更多魔术方法,请参见 this pdf 。
Single underscore at the beginning:
Python doesn't have real private methods. Instead, one underscore at the start of a method or attribute name means you shouldn't access this method, because it's not part of the API.
(This code snippet was taken from Django source code: django/forms/forms.py). In this code,
errors
is a public property, but the method this property calls, _get_errors, is "private", so you shouldn't access it.Two underscores at the beginning:
This causes a lot of confusion. It should not be used to create a private method. It should be used to avoid your method being overridden by a subclass or accessed accidentally. Let's see an example:
Output:
Now create a subclass B and do customization for __test method
The output will be...
As we have seen, B.test() didn't call B.__test() methods, as we might expect. But in fact, this is the correct behavior for __. The two methods called __test() are automatically renamed (mangled) to _A__test() and _B__test(), so they do not accidentally override. When you create a method starting with __ it means that you don't want anyone to be able to override it, and you only intend to access it from inside its own class.
Two underscores at the beginning and at the end:
When we see a method like
__this__
, don't call it. This is a method which Python is meant to call, not you. Let's take a look:There is always an operator or native function which calls these magic methods. Sometimes it's just a hook Python calls in specific situations. For example
__init__()
is called when the object is created after__new__()
is called to build the instance...Let's take an example...
For more details, see the PEP-8 guide. For more magic methods, see this PDF.
根据 python中的
var _
):公约用来避免使用Python关键字命名冲突。__ var
):在课堂上下文中使用时触发名称杂物。由Python口译员执行。__ var __
):指示由Python语言定义的特殊方法。避免使用您自己属性的这个命名方案。_
):有时用作临时或微不足道变量的名称(“不在乎”)。另外:python中最后一个表达式的结果 repl 。According to Meaning of Underscores in Python
_var
): Naming convention indicating a name is meant for internal use. Generally not enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only.var_
): Used by convention to avoid naming conflicts with Python keywords.__var
): Triggers name mangling when used in a class context. Enforced by the Python interpreter.__var__
): Indicates special methods defined by the Python language. Avoid this naming scheme for your own attributes._
): Sometimes used as a name for temporary or insignificant variables (“don’t care”). Also: The result of the last expression in a Python REPL.由于有很多人指的是雷蒙德的谈话写下他所说的话,这要容易一些:
假设您在
circle
中不保留外围
的本地参考。现在,派生的类轮胎
覆盖了周边
的实现,而无需触摸afear
。当您调用轮胎(5).AREA()
时,理论上仍应使用circle.perimeter
进行计算,但实际上它使用的是tire.perimeter.perimeter.perimeter.perimeter。
,这不是预期的行为。这就是为什么我们需要圈子的本地参考。但是,为什么
__外围
而不是_Perimeter
?因为_Perimeter
仍然使派生类覆盖的机会:双重下划线具有换装,因此,父母类中的本地参考很少有可能在派生类中覆盖。因此,“ 使您的子类自由覆盖任何一种方法而不打破其他方法”。
如果您的课程不会继承,或者覆盖方法不会破坏任何内容,那么您简直不需要
__ double_leading_underscore
。Since so many people are referring to Raymond's talk, I'll just make it a little easier by writing down what he said:
Say you don't keep a local reference of
perimeter
inCircle
. Now, a derived classTire
overrides the implementation ofperimeter
, without touchingarea
. When you callTire(5).area()
, in theory it should still be usingCircle.perimeter
for computation, but in reality it's usingTire.perimeter
, which is not the intended behavior. That's why we need a local reference in Circle.But why
__perimeter
instead of_perimeter
? Because_perimeter
still gives derived class the chance to override:Double underscores has name mangling, so there's a very little chance that the local reference in parent class get override in derived class. thus "makes your subclasses free to override any one method without breaking the others".
If your class won't be inherited, or method overriding does not break anything, then you simply don't need
__double_leading_underscore
.有时,您有一个带有领先强调的元组,如
在这种情况下,正在发生的事情是,_()是本地化函数的别名地方。例如,狮身人面像这样做,您将在Imports
和sphinx.locale中找到_()中的发现,将其分配为某些本地化函数的别名。
Sometimes you have what appears to be a tuple with a leading underscore as in
In this case, what's going on is that _() is an alias for a localization function that operates on text to put it into the proper language, etc. based on the locale. For example, Sphinx does this, and you'll find among the imports
and in sphinx.locale, _() is assigned as an alias of some localization function.
_var
:Python中带有领先单个下划线的变量是经典变量,旨在使用您的代码通知其他变量,以便将此变量保留为内部使用。它们在一个点上与经典变量有所不同:在执行定义的对象/模块的通配符导入的通配符导入时,它们没有被导入(定义_
:单个下划线是领先的单个下划线变量的特殊情况。会议将其用作垃圾变量,以存储不打算以后访问的值。它也不是通配符进口的进口。例如:此循环打印“我必须在课堂上说话” 10次,而不需要访问_
变量。var _
:单个尾随下划线变量。它们是公约使用的经典变量,以避免与Python关键字发生冲突。例如:__ var
:双领先下划线变量(至少两个领先的下划线,最多有一个尾随下划线)。当用作类属性(变量和方法)时,这些变量将由名称进行杂交:班级之外,Python将将属性重命名为_&lt; class_name&gt; __&gt; __&lt; attribute_name&gt;
; 。示例:当类似于单个领先的下划线变量时,它们的表现是在类似的班级外部。
__ var __
:双向和尾随下划线变量(至少两个领先和尾随下划线)。也称为 dunders 。 Python使用此命名约定在内部定义变量。避免使用此约定来防止Python更新可能引起的名称冲突。 Dunder变量的行为就像单个领先的下划线变量:在类中使用时,它们不受名字的名称,而是在通配符导入中导入。_var
: variables with a leading single underscore in python are classic variables, intended to inform others using your code that this variable should be reserved for internal use. They differ on one point from classic variables: they are not imported when doing a wildcard import of an object/module where they are defined (exceptions when defining the__all__
variable). Eg:_
: the single underscore is a special case of the leading single underscore variables. It is used by convention as a trash variable, to store a value that is not intended to be later accessed. It is also not imported by wildcard imports. Eg: thisfor
loop prints "I must not talk in class" 10 times, and never needs to access the_
variable.var_
: single trailing underscore variables. They are classic variables used by convention to avoid conflicts with Python keyword. Eg:__var
: double leading underscore variables (at least two leading underscores, at most one trailing underscore). When used as class attributes (variables and methods), these variables are subject to name mangling: outside of the class, python will rename the attribute to_<Class_name>__<attribute_name>
. Example:When used as variables outside a class, they behave like single leading underscore variables.
__var__
: double leading and trailing underscore variables (at least two leading and trailing underscores). Also called dunders. This naming convention is used by python to define variables internally. Avoid using this convention to prevent name conflicts that could arise with python updates. Dunder variables behave like single leading underscore variables: they are not subject to name mangling when used inside classes, but are not imported in wildcard imports.如果一个人真的想制作一个只能读取的变量,那么恕我直言,最好的方法就是使用property(),而只通过getter将其传递给它。使用属性(),我们可以完全控制数据。
我知道OP提出了一些不同的问题,但是由于我发现了另一个问题,询问“如何设置私人变量”以此为重复,所以我想在此处添加此其他信息。
If one really wants to make a variable read-only, IMHO the best way would be to use property() with only getter passed to it. With property() we can have complete control over the data.
I understand that OP asked a little different question but since I found another question asking for 'how to set private variables' marked duplicate with this one, I thought of adding this additional info here.
很棒的答案,所有人都是正确的。我提供了简单的示例以及简单的定义/含义。
含义:
Some_variable--►是公众可以看到的。
_some_variable--►公众可以看到这一点,但这是指私人的惯例... 警告 python没有执行执行。
__SOME_VARAIBLE - ►Python用_ClassName__some_varable(又称名称mangling)替换了变量名称,并且它降低了/隐藏的视野,并且更像是私人变量。
老实说,在这里根据Python文档
示例:
Great answers and all are correct.I have provided simple example along with simple definition/meaning.
Meaning:
some_variable --► it's public anyone can see this.
_some_variable --► it's public anyone can see this but it's a convention to indicate private...warning no enforcement is done by Python.
__some_varaible --► Python replaces the variable name with _classname__some_varaible (AKA name mangling) and it reduces/hides it's visibility and be more like private variable.
Just to be honest here According to Python documentation
The example:
这是一个简单的说明性示例,介绍了双重下强度属性如何影响继承类。因此,使用以下设置:
如果然后在Python Repp中创建一个子实例,您会看到以下
内容对某些人来说可能很明显,但它使我在更复杂的环境中措手不及
Here is a simple illustrative example on how double underscore properties can affect an inherited class. So with the following setup:
if you then create a child instance in the python REPL, you will see the below
This may be obvious to some, but it caught me off guard in a much more complex environment
单一领先下划线是一个惯例。与解释器的观点没有区别,是否名称是否以单个下划线开头。
双领先和尾随下划线用于内置方法,例如
__ INIT __
,__ bool __
等。double引导下方均带有tailling对等方面的双领先底列,但是也是一个约定。类方法将为 mangled> mangled 解释者。对于变量或基本函数名称,没有差异。
Single leading underscores is a convention. there is no difference from the interpreter's point of view if whether names starts with a single underscore or not.
Double leading and trailing underscores are used for built-in methods, such as
__init__
,__bool__
, etc.Double leading underscores w/o trailing counterparts are a convention too, however, the class methods will be mangled by the interpreter. For variables or basic function names no difference exists.
您的问题很好,不仅与方法有关。模块中的功能和对象通常也以一个下划线为前缀,并且可以由两个前缀。
但是__double_underscore名称并未在模块中使用名称。发生的事情是,如果您从模块中导入全部(从模块导入 *),则不会导入一个(或更多)下划线的名称,也不会在help(模块)中显示名称。
Your question is good, it is not only about methods. Functions and objects in modules are commonly prefixed with one underscore as well, and can be prefixed by two.
But __double_underscore names are not name-mangled in modules, for example. What happens is that names beginning with one (or more) underscores are not imported if you import all from a module (from module import *), nor are the names shown in help(module).
除了从python中不存在外部对象外,无法访问的“私有”实例变量。但是,有大多数python代码之后的约定:以下划线(例如_spam)前缀的名称应视为API的非公共部分(无论是函数,方法还是数据成员) 。它应被视为实施细节,并有可能更改,恕不另行通知。
参考
https://dtps://docs.python.org /2/tutorial/classes.html#private-variables-and-class-local-references
“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.
reference
https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
获得_和__的事实非常容易;其他答案很好地表达了他们。用法难以确定。
这就是我的看法:
应使用来指示函数不用于公众使用,例如API。这和导入限制使其行为与C#中的
内部
。应使用以避免在继承的遗迹中碰撞并避免隔离。很像C#中的私人。
==&gt;
如果要指出某物不是用于公共使用的东西,但应像
受保护
使用_
一样。如果您想指出某物不是用于公共使用的东西,但应像
private
使用__
。这也是我非常喜欢的报价:
但是,我认为,如果没有IDE在超越方法时会警告您,那么发现错误可能会花费您一段时间,如果您意外地超越了基础级别的方法。
Getting the facts of _ and __ is pretty easy; the other answers express them pretty well. The usage is much harder to determine.
This is how I see it:
Should be used to indicate that a function is not for public use as for example an API. This and the import restriction make it behave much like
internal
in c#.Should be used to avoid name collision in the inheritace hirarchy and to avoid latebinding. Much like private in c#.
==>
If you want to indicate that something is not for public use, but it should act like
protected
use_
.If you want to indicate that something is not for public use, but it should act like
private
use__
.This is also a quote that I like very much:
But the problem with that is in my opinion that if there's no IDE that warns you when you override methods, finding the error might take you a while if you have accidentially overriden a method from a base-class.
对于方法,您可以使用双重下划线将私有“方法”隐藏为以下模式:
输出:
当我尝试使用double double下划线用于类方法并获得
name eRror:name'name'时,我今天偶然发现了这一点。 _&lt; class&gt;&lt;未定义
错误。In the case of methods, you can use the double underscore to hide away private 'methods' with the following pattern:
Output:
I stumbled across this today when I tried using double underscore for class methods and got the
NameError: name '_<class><method>' is not defined
error.要用简单的单词进行构架,让我们比较Python的变量的可访问性约定,以访问Java中的修饰符:
参考: https://www.tutorialsteacher.com/python/public-public-private-protected-modifiers
To frame it in simple words, let us compare python's variables' accessibility conventions to access modifiers in Java:
Reference: https://www.tutorialsteacher.com/python/public-private-protected-modifiers
_obj表示受保护(可以在定义类及其子类中访问)
- obj表示私有(它们无法从定义的班级外部直接访问它们。但是,Python并不像其他语言那样强制执行严格的私人访问;取而代之的是,它执行名称操作以使访问更加困难,但并非不可能。)
杂交是Python中的一个功能,它修改了类成员的名称,以使直接从班级外部直接访问。这是一种用于创建“伪私人”变量和方法的技术。这是通过将成员名称加上双重下划线(__)的前缀来完成
_obj means protected (can be accessed within the defining class and its subclasses)
--obj means private (They are not directly accessible from outside the class where they are defined. However, Python does not enforce strict private access like some other languages do; instead, it performs name mangling to make access more difficult but not impossible.)
Mangling is a feature in Python that modifies the name of a class member to make it harder to access directly from outside the class. It's a technique used to create "pseudo-private" variables and methods. This is done by prefixing the member name with a double underscore (__) but not ending with another double underscore