单下划线和双下划线在Python变量和方法名称中都有含义。其中一些含义仅仅是按照惯例,作为给程序员的提示,而另外一些则由Python解释器执行。

在本文中,主要讨论以下五种下划线模式和命名约定,以及它们如何影响Python程序的行为:

1.单前置下划线:_var

单下划线前缀是一个提示,即以单个下划线开头的变量或方法将用于内部使用。PEP 8中定义了这种约定。Python不像java对公共变量和私有变量有着严格的区分,单下划线前缀不会影响程序的行为。

class Test:

def __init__(self):

self.foo = 11

self._bar = 23

>>> t = Test()

>>> t.foo

11

>>> t._bar

23

可以看到,_bar没有阻止进入类的内部并获取相应的变量值,在Python中,一个下划线前缀只是一种约定,至少在变量和方法名中是这样。

但是,前导下划线确实影响从模块导入名称的方式。假设有一个模块叫my_module:

# This is my_module.py:

def external_func():

return 23

def _internal_func():

return 42

如果使用通配符进行导入my_module中所有名称(在PEB 8中建议避免使用通配符的导入方式),则Python不会导入带有前导下划线的名称(除非模块定义了覆盖此行为的__all__列表):

>>> from my_module import *

>>> external_func()

23

>>> _internal_func()

NameError: "name '_internal_func' is not defined"

而常规的导入方式不会受到单前导下划线约定的影响:

>>> import my_module

>>> my_module.external_func()

23

>>> my_module._internal_func()

42

总结就是:单下划线是一种Python命名约定,指示名称用于内部使用。Python解释器通常不会强制执行它,只是作为对程序员的一个提示。

2.单后置下划线:var_

有时候一个变量最适合的名称已经被关键字所使用,在Python中类似def、class等关键字不能被用作变量名,可以在这些名称后面加单下划线以解决冲突。

>>>def make_object(name, class):

SyntaxError: "invalid syntax"

>>>def make_object(name, class_):

... pass

总之,单后置下划线是为了与Python关键字命名冲突而约定的。

3.双前置下划线:__var

前面两种命名模式都是一种约定,而双下划线前缀会导致Python解释器重写属性名,以避免子类中的命名冲突。这也被称为名称修饰( name mangling)——解释器在某种程度上更改变量名使得以后扩展类时更难产生冲突。

class Test:

def __init__(self):

self.foo = 11

self._bar = 23

self.__baz = 23

可以用dir()方法看一下对象的属性:

>>>t = Test()

>>>dir(t)

['_Test__baz', '__class__', '__delattr__', '__dict__', '__dir__',

'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',

'__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__',

'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',

'__setattr__', '__sizeof__', '__str__', '__subclasshook__',

'__weakref__', '_bar', 'foo']

在这个列表里面没有__baz属性,但是可以看到有一个_Test__baz属性,这就叫做名称修饰,可以避免该属性被子类所覆盖。

现在创建一个类继承Test类,然后尝试覆盖Test类中的__baz属性:

class ExtendedTest(Test):

def __init__(self):

super().__init__()

self.foo = 'overridden'

self._bar = 'overridden'

self.__baz = 'overridden'

>>>t2 = ExtendedTest()

>>>t2.foo

'overridden'

>>>t2._bar

'overridden'

>>>t2.__baz

AttributeError: "'ExtendedTest' object has no attribute '__baz'"

在执行t2.__baz时出现了AttributeError,我们看一下t2里面的属性:

>>>dir(t2)

['_ExtendedTest__baz', '_Test__baz', '__class__', '__delattr__',

'__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',

'__getattribute__', '__gt__', '__hash__', '__init__', '__le__',

'__lt__', '__module__', '__ne__', '__new__', '__reduce__',

'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',

'__subclasshook__', '__weakref__', '_bar', 'foo', 'get_vars']

可以发现,t2里面有_ExtendedTest__baz和_Test__baz,_Test__baz是继承自Test对象的属性,而_ExtendedTest__ba则是t2里面通过名称修饰得到的属性。

>>>t2._ExtendedTest__baz

'overridden'

>>>t2._Test__baz

42

双下划线前缀对编程者来说是完全透明的,如下面的一个例子:

class ManglingTest:

def __init__(self):

self.__mangled = 'hello'

def get_mangled(self):

return self.__mangled

>>>ManglingTest().get_mangled()

'hello'

>>>ManglingTest().__mangled

AttributeError: "'ManglingTest' object has no attribute '__mangled'"

>>>ManglingTest()._ManglingTest__mangled

'hello'

名称修饰也会应用到方法上:

class MangledMethod:

def __method(self):

return 42

def call_it(self):

return self.__method()

>>>MangledMethod().__method()

AttributeError: "'MangledMethod' object has no attribute '__method'"

>>>MangledMethod().call_it()

42

>>>MangledMethod()._MangledMethod__method()

42

下面是另一个名称修饰的例子:

_MangledGlobal__mangled = 23

class MangledGlobal:

def test(self):

return __mangled

>>>MangledGlobal().test()

23

在这里设置了一个全局变量_MangledGlobal__mangled,然后在创建一个MangledGlobal对象去调用test方法时,test方法返回的时_MangledGlobal__mangled,这说明名称修饰不是专门与类属性绑定的。它适用于类上下文中以两个下划线开头的任何名称。

4.双前置和后置下划线:__var__

名称修饰并不会作用于双下划线前缀和后缀的变量:

class PrefixPostfixTest:

def __init__(self):

self.__bam__ = 42

>>>PrefixPostfixTest().__bam__

42

双前置和后置下划线命名在Python语言中保留为特殊用途,这条规则包括如__init__用于对象构造函数或__call__使对象可调用。最好避免在自己的代码中使用双下划线前缀和后缀的名称,以防止未来Python语言的新变化。

5.单下划线:_

根据惯例,一个单独的下划线有时用作一个名称,表示变量是临时的或不重要的。

>>>for _ in range(32):

... print('Hello, World.')

可以在解包表达式时使用单个下划线作为不需要关心的变量,来忽略特定的值。同样,这个用法只是按照约定,在Python解释器中没有触发特殊的行为。单个下划线只是一个有效的变量名,有时用于此目的。

>>>car = ('red', 'auto', 12, 3812.4)

>>>color, _, _, mileage = car

>>>color

'red'

>>>mileage

3812.4

>>>_

12

除了用作临时变量之外,在大多数Python REPLs中,“_”是一个特殊的变量,表示解释器对最后一个表达式求值的结果。

>>> 20 + 3

23

>>> _

23

>>> print(_)

23

>>> list()

[]

>>> _.append(1)

>>> _.append(2)

>>> _.append(3)

>>> _

[1, 2, 3]

Quick Summary:

原文链接:https://blog.csdn.net/Aray1234/article/details/106558655

python中下划线的5种含义_python中的下划线含义相关推荐

  1. python中下划线开头的命名_Python 中各种下划线的骚操作:_、_xx、xx_、__xx、__xx__、_classname_...

    我们在定义一些变量或者方法的时候,常常会用到下划线,在 Python 中,下划线可是很有用处的哟,比如变量,有些是一个下划线开头的(_xx),有些是两个下划线开头的(__xx),有些是在名称的结尾添加 ...

  2. python中的下划线_Python中的下划线详解

    这篇文章讨论Python中下划线_的使用.跟Python中很多用法类似,下划线_的不同用法绝大部分(不全是)都是一种惯例约定. 一. 单个下划线直接做变量名(_) 主要有三种情况: 1. 解释器中 _ ...

  3. python中长下划线_Python中的下划线详解

    这篇文章讨论Python中下划线_的使用.跟Python中很多用法类似,下划线_的不同用法绝大部分(不全是)都是一种惯例约定. 一. 单个下划线直接做变量名(_) 主要有三种情况: 1. 解释器中 _ ...

  4. python 下划线变量_Python中的下划线详解

    这篇文章讨论Python中下划线_的使用.跟Python中很多用法类似,下划线_的不同用法绝大部分(不全是)都是一种惯例约定. 一. 单个下划线直接做变量名(_) 主要有三种情况: 1. 解释器中 _ ...

  5. python中变量和函数的区别_python中带下划线的变量和函数的意义

    Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下,不同程序员编写的 Python 代码可以保持最大程度的相似风格.这样就易于阅读, ...

  6. html 超链接下划线的距离,浅谈超链接中的下划线

    网站中哪里是用户可以点击的呢?我把鼠标移上去,如果箭头变成一只手,那就表示可以点击.这并不需要费多大功夫.但如果我们迫使用户去思考本来通过下意识就能知道的东西,这纯粹是在浪费人们对你网站的好感度. 人 ...

  7. python前后两个下划线_Python中一个下划线_和两个下划线__的区别

    通常Python类中会有_和__的方法,是指什么意思呢?如下: __表示内部不允许访问,_表示这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,"虽然 ...

  8. python库的调用三种方法_python中调用库的方法

    python中调用库的方法 发布时间:2020-09-02 11:41:21 来源:亿速云 阅读:93 作者:小新 小编给大家分享一下python中调用库的方法,希望大家阅读完这篇文章后大所收获,下面 ...

  9. python中双下划线_python中的下划线及双下划线

    一.Python 用下划线作为变量前缀和后缀指定特殊变量 1. 单下划线开头: _xxx:弱"内部使用"标识,如:"from Module import *", ...

最新文章

  1. npm 卸载_GitHub 收购 npm:天下开源是一家,有个爸爸叫微软
  2. Linux内核源代码情景分析-fork()
  3. mybatis 一对多查询_Java自学之mybatis:使用注解方式多对一查询
  4. linux stdin STDIN_FILENO 区别
  5. Dataset:(公交车、恐龙、大象、花朵、骏马)六类图片数据集(AutoKeras测试)的简介、下载、使用方法之详细攻略
  6. reactjs错误边界:用来捕获后代组件的错误,渲染出备用页面
  7. Android 通知栏Notification
  8. 天池 在线编程 旅行计划(暴力回溯)
  9. sort函数_MATLAB--数字图像处理 sort()函数
  10. srsLTE源码学习:协议数据单元PDU:pdu.h
  11. matlab不用hist画直方图,matlab可以画直方图
  12. 硬盘属于计算机的主存吗,.硬盘装在主机箱内,因此硬盘属于主存对吗
  13. 如何用好 Google 等搜索引擎
  14. centos 搭建 SVN
  15. oracle 物化视图 on demand,【案例】Oracle物化视图 on prebuilt table故障常见解决办法...
  16. 计算机老师教育感言,66句震撼人心的老师教育感言
  17. HTML标记由尖括号和,HTML标记
  18. 银行业务--负债业务
  19. 批量修改UWP版bilibili下载的视频文件名
  20. Android实现支付宝AR功能,Android接入支付宝实现支付功能实例

热门文章

  1. ipad分屏功能怎么开启_率土之滨叫阵功能怎么出现的 开启叫阵方法一览
  2. 正则提取字符串中内容
  3. android屏蔽系统按键精灵,安卓按键精灵的,关闭app程序问题!
  4. 基于深度学习的自动上色程序,以及其实际应用
  5. 升级cpolar内网穿透套餐:如何升级cpolar套餐 1/4
  6. vue:父子组件通信
  7. 网络经济与企业管理【二】之企业战略管理
  8. xavier内存满了,无法开机解决方案
  9. 快手的成功可以给我们什么启示
  10. js取出两个数组中id相同的对象