翼度科技»论坛 编程开发 python 查看内容

Python 中的单下划线和双下划线

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
哈喽大家好,我是咸鱼
当我们在学习 Python 的时候,可能会经常遇到单下划线 _  和双下划线 __ 这两种命名方式
单下划线 _  和双下划线 __ 不仅仅是只是一种简单的命名习惯,它们在 Python 中有着特殊的含义,对于代码的可读性和功能实现有着关键的作用。
那么今天我们来看一看在 Python 中单下划线和双下划线的用法和意义
前导单下划线

前导单下划线(Leading Single Underscore)通常用于命名变量、方法和属性,表示这些命名的元素是【私有】的或者说是【内部使用】的。
这种命名约定并不是严格的语言规则(即非强制性),而是一种约定,告诉开发人员该对象不应该被外部直接访问或修改
  1. _internal_variable = 10
复制代码
比如说下面的例子中,_internal_var和_internal_method都以前导单下划线开头,表示它们是类的内部使用。
而public_method是公共方法,可以在类外部访问。
  1. class MyClass:
  2.     def __init__(self):
  3.         self._internal_var = 42  # 前导单下划线表示该变量是内部使用的
  4.     def _internal_method(self):
  5.         return 'This is an internal method'
  6.     def public_method(self):
  7.         # 在公共方法中调用内部方法和变量
  8.         print(self._internal_method())
  9.         print(f'The internal variable is: {self._internal_var}')
复制代码
虽然可以在类外部访问前导单下划线命名的变量和方法,但是按照约定,建议只在类内部使用,而避免在类外部直接访问它们。
单下划线

单下划线通常用作一个占位符,用于表示一个不重要的变量名或迭代中的临时变量,即在解构赋值或循环迭代中不需要使用的变量
例子一中,_ 用作一个占位符变量,表示在tuple_returning_function()返回的元组中的某个值,但是在解构赋值中没有被使用。
  1. def tuple_returning_function():
  2.     return (1,1), (2,2), (3,3)
  3. _ , tuple_I_need, _ = tuple_returning_function()
复制代码
例子二中,_ 用作循环迭代中的占位符,因为循环体中不需要使用循环变量的值,只是执行了三次打印操作
  1. for _ in range(0,3):
  2.   print("打印三次")
复制代码
单尾随下划线

单个后缀下划线(Single trailing underscores)通常用于避免与 Python 关键字产生命名冲突。它被用作标识符的后缀,以示与Python关键字有所区别。
比如说我想使用一个在 Python 中已经是保留关键字的变量名时,比如class、def、type等。为了避免冲突,可以添加后缀下划线
  1. class_ = "Computer Science"
  2. type_ = “字符串”
复制代码
Dunder 方法

Dunder 方法指的是以双下划线(__)开头和结尾的特殊方法(也称为魔术方法或特殊方法)。
这些方法具有特殊的行为,可以在自定义类中重写以改变类的行为。Dunder方法的名称是Python中预定义的,例如__init__、__str__、__repr__等。
下面是一些常见的 Dunder 方法:

  • __init__(self, ...): 初始化方法,在对象实例化时调用,用于初始化对象的属性。
  • __str__(self): 将对象转换为字符串表示形式,当使用print()函数或str()函数时调用。
  • __repr__(self): 返回一个包含对象信息的字符串,通常用于开发和调试,可通过repr()函数调用。
  • __len__(self): 返回对象的长度,通过len()函数调用。
  • __getitem__(self, key): 获取对象的元素,用于索引操作,例如obj[key]。
  • __setitem__(self, key, value): 设置对象的元素,用于索引赋值操作,例如obj[key] = value。
  • __delitem__(self, key): 删除对象的元素,用于索引删除操作,例如del obj[key]。
  • __call__(self, ...): 将对象作为函数调用,使得对象实例可调用。
我们在下面的例子中定义了 __add__  dunder 方法,并创建了两个实例
  1. class Point:
  2.     def __init__(self, x, y):
  3.         self.x = x
  4.         self.y = y
  5.     def __add__(self, other):
  6.         return Point(self.x + other.x, self.y + other.y)
  7.     def __str__(self):
  8.         return f"({self.x}, {self.y})"
  9. p1 = Point(1, 2)
  10. p2 = Point(3, 4)
  11. p3 = p1 + p2
  12. print(p3)  # Output: (4, 6)
复制代码
我们定义了一个 Point 类,它有 x、y 两个实例变量以及__add__ 方法和__str__ 方法
当我们使用 + 运算符对 Point 的两个实例(p1、p2)求和时,__add__ 会自动调用。它返回一个新 的 Point 对象(p3),其 x 和 y 值是两个原始 Point对象的 x和 y 值的和
当使用print()函数时调用自定义的__str__ 方法
前导双下划线

前导双下划线作为前缀在对象名前使用时,表示这是一个特殊的命名约定,它在类定义中用于创建私有属性或方法。
当在类中使用双下划线作为前缀时,Python 解释器会自动修改属性名,以避免在子类中发生命名冲突。这个过程被称为名称修饰(name mangling)
比如下面这个例子:
  1. class MyClass:
  2.     def __init__(self):
  3.         self.__private_var = 10
  4.     def get_private_var(self):
  5.         return self.__private_var
  6. # 创建类的实例
  7. obj = MyClass()
  8. # 尝试访问私有属性
  9. print(obj.__private_var)  # 会抛出 AttributeError 错误,因为这个属性名称已被修改
  10. # 通过调用访问私有属性的方法来获取
  11. print(obj.get_private_var())  # 输出: 10
复制代码
__private_var属性在类内部被访问,但是在类外部直接访问会导致 AttributeError 错误。
这是因为 Python 对 __private_var 进行了名称修饰,实际名称变成了 obj._MyClass__private_var,这样避免了外部直接访问
但是我们可以通过调用类内部方法 get_private_var() 在类外部访问私有属性。
通过使用前导双下划线,以确保类的某些属性或方法只能从类本身内部访问。这有助于防止意外修改重要的内部数据,并使代码更加可靠和可维护
但如果你知道修饰后的名称,你仍可以在类外部去访问

来源:https://www.cnblogs.com/edisonfish/p/17865662.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具