哈喽大家好,我是咸鱼

当我们在学习 Python 的时候,可能会经常遇到单下划线 _ 和双下划线 __ 这两种命名方式

单下划线 _ 和双下划线 __ 不仅仅是只是一种简单的命名习惯,它们在 Python 中有着特殊的含义,对于代码的可读性和功能实现有着关键的作用。

那么今天我们来看一看在 Python 中单下划线和双下划线的用法和意义

前导单下划线

前导单下划线(Leading Single Underscore)通常用于命名变量、方法和属性,表示这些命名的元素是【私有】的或者说是【内部使用】的。

这种命名约定并不是严格的语言规则(即非强制性),而是一种约定,告诉开发人员该对象不应该被外部直接访问或修改

_internal_variable = 10

比如说下面的例子中,_internal_var_internal_method都以前导单下划线开头,表示它们是类的内部使用。

public_method是公共方法,可以在类外部访问。

class MyClass:
def __init__(self):
self._internal_var = 42 # 前导单下划线表示该变量是内部使用的 def _internal_method(self):
return 'This is an internal method' def public_method(self):
# 在公共方法中调用内部方法和变量
print(self._internal_method())
print(f'The internal variable is: {self._internal_var}')

虽然可以在类外部访问前导单下划线命名的变量和方法,但是按照约定,建议只在类内部使用,而避免在类外部直接访问它们。

单下划线

单下划线通常用作一个占位符,用于表示一个不重要的变量名或迭代中的临时变量,即在解构赋值或循环迭代中不需要使用的变量

例子一中,_ 用作一个占位符变量,表示在tuple_returning_function()返回的元组中的某个值,但是在解构赋值中没有被使用。

def tuple_returning_function():
return (1,1), (2,2), (3,3) _ , tuple_I_need, _ = tuple_returning_function()

例子二中,_ 用作循环迭代中的占位符,因为循环体中不需要使用循环变量的值,只是执行了三次打印操作

for _ in range(0,3):
print("打印三次")

单尾随下划线

单个后缀下划线(Single trailing underscores)通常用于避免与 Python 关键字产生命名冲突。它被用作标识符的后缀,以示与Python关键字有所区别。

比如说我想使用一个在 Python 中已经是保留关键字的变量名时,比如class、def、type等。为了避免冲突,可以添加后缀下划线

class_ = "Computer Science"
type_ = “字符串”

Dunder 方法

Dunder 方法指的是以双下划线(__)开头和结尾的特殊方法(也称为魔术方法或特殊方法)。

这些方法具有特殊的行为,可以在自定义类中重写以改变类的行为。Dunder方法的名称是Python中预定义的,例如__init____str____repr__等。

下面是一些常见的 Dunder 方法:

  1. __init__(self, ...): 初始化方法,在对象实例化时调用,用于初始化对象的属性。
  2. __str__(self): 将对象转换为字符串表示形式,当使用print()函数或str()函数时调用。
  3. __repr__(self): 返回一个包含对象信息的字符串,通常用于开发和调试,可通过repr()函数调用。
  4. __len__(self): 返回对象的长度,通过len()函数调用。
  5. __getitem__(self, key): 获取对象的元素,用于索引操作,例如obj[key]
  6. __setitem__(self, key, value): 设置对象的元素,用于索引赋值操作,例如obj[key] = value
  7. __delitem__(self, key): 删除对象的元素,用于索引删除操作,例如del obj[key]
  8. __call__(self, ...): 将对象作为函数调用,使得对象实例可调用。

我们在下面的例子中定义了 __add__ dunder 方法,并创建了两个实例

class Point:
def __init__(self, x, y):
self.x = x
self.y = y def __add__(self, other):
return Point(self.x + other.x, self.y + other.y) def __str__(self):
return f"({self.x}, {self.y})"
p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
print(p3) # Output: (4, 6)

我们定义了一个 Point 类,它有 xy 两个实例变量以及__add__ 方法和__str__ 方法

当我们使用 + 运算符对 Point 的两个实例(p1、p2)求和时,__add__ 会自动调用。它返回一个新 的 Point 对象(p3),其 xy 值是两个原始 Point对象的 xy 值的和

当使用print()函数时调用自定义的__str__ 方法

前导双下划线

前导双下划线作为前缀在对象名前使用时,表示这是一个特殊的命名约定,它在类定义中用于创建私有属性或方法。

当在类中使用双下划线作为前缀时,Python 解释器会自动修改属性名,以避免在子类中发生命名冲突。这个过程被称为名称修饰(name mangling)

比如下面这个例子:

class MyClass:
def __init__(self):
self.__private_var = 10 def get_private_var(self):
return self.__private_var # 创建类的实例
obj = MyClass() # 尝试访问私有属性
print(obj.__private_var) # 会抛出 AttributeError 错误,因为这个属性名称已被修改 # 通过调用访问私有属性的方法来获取
print(obj.get_private_var()) # 输出: 10

__private_var属性在类内部被访问,但是在类外部直接访问会导致 AttributeError 错误。

这是因为 Python 对 __private_var 进行了名称修饰,实际名称变成了 obj._MyClass__private_var,这样避免了外部直接访问

但是我们可以通过调用类内部方法 get_private_var() 在类外部访问私有属性。

通过使用前导双下划线,以确保类的某些属性或方法只能从类本身内部访问。这有助于防止意外修改重要的内部数据,并使代码更加可靠和可维护

但如果你知道修饰后的名称,你仍可以在类外部去访问

Python 中的单下划线和双下划线的更多相关文章

  1. Python中的魔术方法详解(双下方法)

    介绍 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”,中文称『魔术方法』,例如类的初始化方法 __init__ ,Python中所有的魔术方法均在官方文档中 ...

  2. python 里面的单下划线与双下划线的区别

    python 里面的单下划线与双下划线的区别 Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __ ...

  3. 测试Python类成员的单下划线,双下划线,两头下划线的区别

    首先原谅一个菜鸟叫他“两头下划线”.记得在windows编程中,很多宏定义使用下划线+大写,给人逼格很高的错觉.对于Python下划线的认识,大概是从__dict__这个属性开始的,看__dict__ ...

  4. Python笔记_第三篇_面向对象_4.单下划线和双下划线

    说道这里我们需要稍微暂停一下.前面我们说到了类是作为一个对象存放容器.这个容器里面有属性和方法.最好的理解类的方式就是把类想想成一个容器. 然后构造了一个析构函数和构造函数,然后又对object和se ...

  5. Python里的单下划线,双下划线,以及前后都带下划线的意义

    Python里的单下划线,双下划线,以及前后都带下划线的意义: 单下划线如:_name 意思是:不能通过from modules import * 导入,如需导入需要:from modules imp ...

  6. python单下划线、双下划线、头尾双下划线说明:

      单下划线.双下划线.头尾双下划线说明: __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的. _foo: 以单下划线开头的表示的是 protected 类 ...

  7. python(七) Python中单下划线和双下划线

    Python中单下划线和双下划线: 一.分类 (1).以单下划线开头,表示这是一个保护成员,只有类对象和子类对象自己能访问到这些变量. 以单下划线开头的变量和函数被默认是内部函数,使用from mod ...

  8. Python反射和内置方法(双下方法)

    Python反射和内置方法(双下方法) 一.反射 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发 ...

  9. Python 中 logging 日志模块在多进程环境下的使用

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,Python 中 logging 日志模块在多进程环境下的使用 使用 Pytho ...

  10. python中基于descriptor的一些概念(下)

    @python中基于descriptor的一些概念(下) 3. Descriptor介绍 3.1 Descriptor代码示例 3.2 定义 3.3 Descriptor Protocol(协议) 3 ...

随机推荐

  1. [nginx]防范空主机头

    空主机头防范主要是防止别人恶意将域名解析到服务器IP上. 配置示例 方式一,增加vhost # http的空主机头防范 server { listen 80 default; server_name ...

  2. 【技术积累】Linux中的命令行【理论篇】【九】

    blkid命令 命令介绍 blkid命令是一个用于查看块设备属性的Linux命令.它可以识别和显示块设备的文件系统类型.UUID.LABEL.PARTUUID等信息. 命令说明 在Linux下可以使用 ...

  3. 几种常用到的 Hybrid App 技术框架

    移动操作系统在经历了诸神混战之后,BlackBerry OS.Symbian OS.Windows Phone 等早期的移动操作系统逐渐因失去竞争力而退出.目前,市场上主要只剩下安卓和 iOS 两大阵 ...

  4. ATtiny88初体验(二):呼吸灯

    ATtiny88初体验(二):呼吸灯 前面的"点灯"实验实现了间隔点亮/熄灭LED,但是间隔时间和亮度都没法控制,为了解决这个问题,可以使用ATtiny88的定时器模块. ATti ...

  5. 【译】Silverlight 不会消亡 XAML for Blazor 到来

    Userware 正在使用早已消失的.令人怀念的微软 Silverlight Web 开发平台的遗留来支持其新的"XAML for Blazor"产品,该产品允许 .NET 开发人 ...

  6. [htmlayout] picture标签替代img, 解决更新图片数据后依然显示原图片数据

    在hl中, 你可能遇到过这样的情况.   给img标签设置了一个图片路径.   在软件使用过程中对这个路径的数据进行过重写, 删除等等 但img依然还是显示最初载入的图片数据. 解决办法: 用&quo ...

  7. 【NET 7.0、OpenGL ES】使用Silk.NET渲染MMD,并实时进行物理模拟。

    有关mmd播放器,网上也有许多非常漂亮的实现,如 pmxeditor.saba.blender_mmd_tools等等.. 首先我想先介绍下我参考实现的仓库: sselecirPyM/Coocoo3D ...

  8. SpringCloud搭建保姆级教程

    一.搭建服务注册与发现中⼼ 使⽤Spring Cloud Netflix 中的 Eureka 搭建服务注册与发现中⼼ 1.创建SpringBoot应用添加依赖 1.spring web 2.eurek ...

  9. Ds100p -「数据结构百题」61~70

    61.P5355 [Ynoi2017]由乃的玉米田 由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美. 这排玉米一共有 \(N\) 株,它们的高度参差不齐. 由乃认为玉米田不美,所以她决定出 ...

  10. xftp 7必须更新最新版本怎么解决

    下载可以查看16进制的软件: Sublime Text 运行XFTP7 双击打开是:这样的 解决方案 用Sublime Text进行打开nslicense.dll, 打开之后查找"0f88 ...