Python中5种下划线的含义,你都知道吗

news2024/9/27 12:18:27

前言

大家早好、午好、晚好吖 ❤ ~欢迎光临本文章

话不多说,直接开搞,如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码

1.单前导下划线:_var

当涉及到变量和方法名称时,单个下划线前缀有一个约定俗成的含义。

它是对程序员的一个提示 - 意味着Python社区一致认为它应该是什么意思,但程序的行为不受影响。

下划线前缀的含义是告知其他程序员:以单个下划线开头的变量或方法仅供内部使用。

该约定在PEP 8中有定义。

这不是Python强制规定的。 Python不像Java那样在“私有”和“公共”变量之间有很强的区别。

这就像有人提出了一个小小的下划线警告标志,说:

“嘿,这不是真的要成为类的公共接口的一部分。不去管它就好。“

2.单末尾下划线 var_

有时候,一个变量的最合适的名称已经被一个关键字所占用。

因此,像class或def这样的名称不能用作Python中的变量名称。

在这种情况下,你可以附加一个下划线来解决命名冲突:

>>> def make_object(name, class):
SyntaxError: "invalid syntax"

>>> def make_object(name, class_):
...    pass

总之,单个末尾下划线(后缀)是一个约定,用来避免与Python关键字产生命名冲突。 PEP 8解释了这个约定。

3. 双前导下划线 __var

到目前为止,我们所涉及的所有命名模式的含义,来自于已达成共识的约定。

而对于以双下划线开头的Python类的属性(包括变量和方法),情况就有点不同了。

双下划线前缀会导致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']

以上是这个对象属性的列表。 让我们来看看这个列表,并寻找我们的原始变量名称foo,_bar和__baz - 我保证你会注意到一些有趣的变化。

self.foo变量在属性列表中显示为未修改为foo。

self._bar的行为方式相同 - 它以_bar的形式显示在类上。

就像我之前说过的,在这种情况下,前导下划线仅仅是一个约定。 给程序员一个提示而已。

然而,对于self.__baz而言,情况看起来有点不同。

当你在该列表中搜索__baz时,你会看不到有这个名字的变量。

__baz出什么情况了?

如果你仔细观察,你会看到此对象上有一个名为_Test__baz的属性。

这就是Python解释器所做的名称修饰。 它这样做是为了防止变量在子类中被重写。

让我们创建另一个扩展Test类的类,并尝试重写构造函数中添加的现有属性:

class ExtendedTest(Test):
   def __init__(self):
       super().__init__()
       self.foo = 'overridden'
       self._bar = 'overridden'
       self.__baz = 'overridden'

现在,你认为foo,_bar和__baz的值会出现在这个ExtendedTest类的实例上吗? 我们来看一看:

>>> t2 = ExtendedTest()
>>> t2.foo
'overridden'
>>> t2._bar
'overridden'
>>> t2.__baz
AttributeError: "'ExtendedTest' object has no attribute '__baz'"

等一下,当我们尝试查看t2 .__ baz的值时,为什么我们会得到AttributeError?

名称修饰被再次触发了!

事实证明,这个对象甚至没有__baz属性:

>>> 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']

正如你可以看到__baz变成_ExtendedTest__baz以防止意外修改:

>>> t2._ExtendedTest__baz
'overridden'

但原来的_Test__baz还在:

>>> 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'"

名称修饰是否也适用于方法名称?

是的,也适用。

名称修饰会影响在一个类的上下文中,以两个下划线字符(“dunders”)开头的所有名称:

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

这是另一个也许令人惊讶的运用名称修饰的例子:

_MangledGlobal__mangled = 23

class MangledGlobal:
   def test(self):
       return __mangled

>>> MangledGlobal().test()
23

在这个例子中,我声明了一个名为_MangledGlobal__mangled的全局变量。

然后我在名为MangledGlobal的类的上下文中访问变量。

由于名称修饰,我能够在类的test()方法内,以__mangled来引用_MangledGlobal__mangled全局变量。

Python解释器自动将名称__mangled扩展为_MangledGlobal__mangled,因为它以两个下划线字符开头。

这表明名称修饰不是专门与类属性关联的。

它适用于在类上下文中使用的两个下划线字符开头的任何名称。

有很多要吸收的内容吧。

老实说,这些例子和解释不是从我脑子里蹦出来的。

我作了一些研究和加工才弄出来。

我一直使用Python,有很多年了,但是像这样的规则和特殊情况并不总是浮现在脑海里。

有时候程序员最重要的技能是“模式识别”,而且知道在哪里查阅信息。

如果您在这一点上感到有点不知所措,请不要担心。

慢慢来,试试这篇文章中的一些例子。

让这些概念完全沉浸下来,以便你能够理解名称修饰的总体思路,以及我向您展示的一些其他的行为。

如果有一天你和它们不期而遇,你会知道在文档中按什么来查。

4.双前导和双末尾下划线 var

也许令人惊讶的是,如果一个名字同时以双下划线开始和结束,则不会应用名称修饰。

由双下划线前缀和后缀包围的变量不会被Python解释器修改:

class PrefixPostfixTest:
   def __init__(self):
       self.__bam__ = 42

>>> PrefixPostfixTest().__bam__

但是,Python保留了有双前导和双末尾下划线的名称,用于特殊用途。

这样的例子有,init__对象构造函数,或__call — 它使得一个对象可以被调用。

这些dunder方法通常被称为神奇方法 - 但Python社区中的许多人(包括我自己)都不喜欢这种方法。

最好避免在自己的程序中使用以双下划线(“dunders”)开头和结尾的名称,以避免与将来Python语言的变化产生冲突。

5.单下划线 _

按照习惯,有时候单个独立下划线是用作一个名字,来表示某个变量是临时的或无关紧要的。

例如,在下面的循环中,我们不需要访问正在运行的索引,我们可以使用“_”来表示它只是一个临时值:

>>> for _ in range(32):
...    print('Hello, World.')

你也可以在拆分(unpacking)表达式中将单个下划线用作“不关心的”变量,以忽略特定的值。

同样,这个含义只是“依照约定”,并不会在Python解释器中触发特殊的行为。

单个下划线仅仅是一个有效的变量名称,会有这个用途而已。

在下面的代码示例中,我将汽车元组拆分为单独的变量,但我只对颜色和里程值感兴趣。

但是,为了使拆分表达式成功运行,我需要将包含在元组中的所有值分配给变量。

在这种情况下,“_”作为占位符变量可以派上用场:

'''
学习中遇到问题没人解答?小编创建了一个Python学习交流QQ群:926207505
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
>>> car = ('red', 'auto', 12, 3812.4)
>>> color, _, _, mileage = car

>>> color
'red'
>>> mileage
3812.4
>>> _
12

除了用作临时变量之外,“_”是大多数Python REPL中的一个特殊变量,它表示由解释器评估的最近一个表达式的结果。

这样就很方便了,比如你可以在一个解释器会话中访问先前计算的结果,或者,你是在动态构建多个对象并与它们交互,无需事先给这些对象分配名字:

>>> 20 + 3
23
>>> _
23
>>> print(_)
23

>>> list()
[]
>>> _.append(1)
>>> _.append(2)
>>> _.append(3)
>>> _
[1, 2, 3]

尾语 💝

好了,今天的分享就差不多到这里了!

文章提供的十二道编程题,大家都可以自己研究研究,有不理解的地方也是可以点击文章名片领取解答和大量的学习资料以及部分案例的源码哦

对下一篇大家想看什么,可在评论区留言哦!看到我会更新哒(ง •_•)ง

喜欢就关注一下博主,或点赞收藏评论一下我的文章叭!!!

最后,宣传一下呀~👇👇👇更多源码、资料、素材、解答、交流皆点击下方名片获取呀👇👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/889611.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【04 英语语法:非谓语动词(不定式、分词、动名词)详解】

非谓语动词 非谓语动词:不定式,分词,动名词1. 不定式:动词原形(do/原形不定式),带 to 不定式 (to do)1.1 带 to 不定式(to do)的功能:…

Apipost预执行脚本如何调用外部jar包

近期版本更新中Apipost推出插件管理,可以直接在预、后执行脚本中调用本地的脚本文件 导入脚本 在「系统设置」—「插件管理」中打开目录将要执行的脚本文件拖入到文件夹下 执行脚本 需要获取请求参数: const requestData request.request_bodys; 在…

版本控制工具Git集成IDEA的学习笔记(第二篇GitHub)

目录 一、团队内协作和跨团队协作讲述 1、团队内协作 2、跨团队协作 二、团队内合作交互方式 1、初始化本地库 2、创建远程库 3、在本地创建远程库地址的别名 4、推送操作 5、克隆操作 6、邀请加入团队,push操作 7、远程库修改的拉取操作 8、远程库修改…

【Vue】yarn 安装包时权限不足或者文件夹被占用导致安装失败

在一个 Vue3 项目中,用 yarn 安装 Vue 插件或者 Vue-Router 时,出现同样的 error ,如下: An unexpected error occurred: “EPERM: operation not permitted, unlink ‘C:\Codefield\项目\yupao-frontend\node_modules\esbuild\w…

zabbix配置微信报警

如有错误,敬请谅解! 此文章仅为本人学习笔记,仅供参考,如有冒犯,请联系作者删除!! 6.1 注册企业微信 企业微信注册地址:https://work.weixin.qq.com 设置总部门名称添加成员 也可以…

小程序项目组件的基本应用

宿主环境:程序运行必须依赖的环境 小程序的宿主环境 ---->手机微信(定位、扫码、支付等) 小程序的通信模型: 渲染层和逻辑层之间的通信(微信客户端转发)逻辑层和第三方服务器之间的通信(微信客户端转发) 小程序的运行机制: 启动&#xff1…

chrome屏幕共享插件的获取和配置

文章目录 1. 下载插件2. 加载插件3. 打开这个文件4. 关掉开发者模式 1. 下载插件 https://github.com/webrtc/samples/blob/gh-pages/release/desktopCaptureExtension.zip 不过我下载不了,找别人要了这个文件 解压 2. 加载插件 选择 扩展程序—》管理扩展程序 加…

拥抱变革 展现PMO力量 | 易趋受邀出席2023第十二届中国PMO大会

2023年8月12-13日,由PMO评论主办的第十二届中国PMO大会(以下简称PMO大会)在北京成功落幕。 (主论坛一现场) 本届大会以“拥抱变革 展现PMO力量”为主题,设置了“PMO与组织变革”、“PMO与组织战略”2个主论…

vueuse常用方法

useDateFormat 时间格式化 <script setup lang"ts">import { useNow, useDateFormat } from vueuse/coreconst formatted useDateFormat(useNow(), YYYY-MM-DD HH:mm:ss)</script><template><div>{{ formatted }}</div> </templa…

【爱书不爱输的程序猿】公网访问本地搭建的WEB服务器之详细教程

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本地电脑搭建Web服务器并用cpolar发布至公网访问 前言1. 首先将PHPStudy、WordPress、cpolar下载到电脑2. 安装PHPStudy3. 安装cpolar&#xff0c;进入Web-UI界面4.安装wordpress5.…

赋能智慧零售,美格智能助力升级科技感购物体验

近期&#xff0c;一段消费者在商场使用智能购物车的视频冲上社交平台热搜榜&#xff0c;获得百万点赞&#xff0c;网友纷纷感慨科技进步的速度。许多人会好奇智能购物车和普通购物车有什么区别呢&#xff1f;智能购物车具有用户识别、室内定位、数据采集、精准营销、自助结算、…

低代码PaaS平台源码:基于Kubernetes云原生技术,快速构建企业级应用程序

低代码PaaS平台 低代码PaaS平台可以在云端开发、部署、运行低代码应用程序。使用独立数据库模型&#xff0c;基于Kubernetes云原生技术&#xff0c;每个租户均可拥有一套独立的存储、数据库、代码和命名空间&#xff0c;实现了100%的租户数据隔离&#xff0c;并可以随时迁移到…

【RP2040】香瓜树莓派RP2040之LED

本文最后修改时间&#xff1a;2022年09月05日 11:02 一、本节简介 本节介绍如何编写一个LED驱动。 二、实验平台 1、硬件平台 1&#xff09;树莓派pico开发板 ①树莓派pico开发板*2 ②micro usb数据线*2 2&#xff09;电脑 2、软件平台 1&#xff09;VS CODE 三、版权声…

ppt转pdf免费的工具哪个好用?免费PPT转换为PDF的方法分享

在我们的工作和学习中&#xff0c;将PPT文件转换为PDF格式对于分享和储存具有重要意义。PPT文件是一种常用的演示工具&#xff0c;用于展示和传达信息。然而&#xff0c;PPT文件在不同的平台和设备上可能存在格式兼容性的问题&#xff0c;而且文件大小较大&#xff0c;不方便共…

C#__使用Type类反射数据的基本用法

// 简单介绍 // 元数据&#xff08;metadata&#xff09;&#xff1a;与程序及其类型有关的数据。 // 反射&#xff1a;一个运行的程序查看本身元数据或其他程序集中的元数据的行为 // Assembly类&#xff1a;允许访问给定程序集的元数据&#xff0c;包含了可以加载和执行程序…

爬虫IP时效问题:优化爬虫IP使用效果实用技巧

目录 1. 使用稳定的代理IP服务提供商&#xff1a; 2. 定期检测代理IP的可用性&#xff1a; 3. 配置合理的代理IP切换策略&#xff1a; 4. 使用代理IP池&#xff1a; 5. 考虑代理IP的地理位置和速度&#xff1a; 6. 设置合理的请求间隔和并发量&#xff1a; 总结 在爬虫过…

Max Compute 操作记录

编译 max compute-spark git clone https://github.com/aliyun/MaxCompute-Spark cd spark-3.x mvn clean package -DskipTests在 target 目录下生成 以下两个文件。 spark-examples_2.12-1.0.0-SNAPSHOT-shaded.jar spark-examples_2.12-1.0.0-SNAPSHOT.jar2. DataWorks 上传…

计组 | 中断是什么?中断流程有哪些?什么情况下响应中断?

前言 记录一些计组相关联的题集与知识点&#xff0c;方便记忆与理解。 中断 总结 IBM370系统&#xff1a; IBM370计算机将中断类分为机器校验、访管、程序性、外部、输入/输出、重新启动6类。 中断响应优先级级别最低的是 重新启动中断 中断响应优先级级别最高的中断类型是…

ARouter基本使用及原理分析

作者&#xff1a;愿天深海 ARouter简介 ARouter是阿里开源的一款帮助Android App进行组件化改造的路由框架&#xff0c;是Android平台中对页面和服务提供路由功能的中间件&#xff0c;可以实现在不同模块的Activity之间跳转。 ARouter的特点是灵活性强还能帮助项目解耦。 除…

SpringCloud Gateway:status: 503 error: Service Unavailable

使用SpringCloud Gateway路由请求时&#xff0c;出现如下错误 yml配置如下&#xff1a; 可能的一种原因是&#xff1a;yml配置了gateway.discovery.locator.enabledtrue&#xff0c;此时gateway会使用负载均衡模式路由请求&#xff0c;但是SpringCloud Alibaba删除了Ribbon的…