### Python中的下划线详解
在Python编程语言中,下划线(`_`)是一个非常灵活且具有多种用途的符号。虽然Python本身并没有强制规定下划线的用途,但在社区中存在许多约定俗成的惯例来指导如何使用下划线。本篇文章将详细介绍Python中下划线的各种使用场景。
#### 一、单个下划线直接做变量名(_)
单个下划线在Python中有几种不同的用法:
1. **解释器中**:在交互式的Python解释器中,`_`符号通常用于保存上一次表达式计算的结果。这是一种由CPython解释器引入并被其他解释器广泛采纳的特性。例如:
```python
>>> 42
42
>>> _
42
```
2. **作为名称使用**:在某些情况下,`_`可以用作临时或不重要的变量名。这种做法向其他开发者表明该变量是一个被丢弃的名称,意味着它不会被再次使用。例如,在遍历列表的过程中,如果只关心列表中的元素而不关心索引,则可以使用`_`作为计数器:
```python
for _ in range(10):
print("Hello")
```
3. **i18n**:`_`还常被用作国际化和本地化字符串翻译查询的函数名。例如,在Django框架中,通常会这样定义:
```python
from django.utils.translation import ugettext as _
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)
```
这里需要注意的是,为了避免与作为丢弃变量名的`_`发生冲突,在使用`_`作为翻译函数的情况下,不应同时将其用作丢弃变量。
#### 二、单下划线前缀的名称(例如:_shahriar)
以单个下划线开头的变量名或函数名,通常被视为“私有”的或“非公开”的。这意味着这些名称主要用于内部实现细节,外部不应该直接访问它们。例如,当在一个模块中定义了`_private_function`时,这表明这是一个内部使用的函数,而不是供用户调用的公共接口。
根据Python官方文档,“以单个下划线开头的名称(例如`_spam`)应被视为API的非公开部分(无论是函数、方法还是数据成员)。应将其视为实现细节,并可能在不通知的情况下更改。”
在某些场景下,当使用`import *`语法时,单下划线开头的名称会被忽略,除非它们被显式地包含在模块的`__all__`属性中。例如:
```python
from module import *
```
这里`module`中的所有非下划线开头的名称都会被导入,而以单下划线开头的名称则不会被导入。这种行为有助于防止潜在的命名冲突,并保持代码的清晰度。
#### 三、双下划线前缀的名称(例如:__shahriar)
双下划线开头的名称(如`__private_method`)具有特殊的含义,它们会被解释器自动重命名,以避免子类与父类中同名方法之间的冲突。具体来说,对于任何形如`__spam`(以双下划线开头并且通常以一个下划线结尾)的标识符,Python会在文本上将其替换为`_classname__spam`,其中`classname`是当前类的名称。
这种机制称为“名称改写”(name mangling),主要用于解决类继承过程中可能出现的方法名冲突问题。例如:
```python
class A:
def __method_name(self):
pass
print(dir(A())) # 输出:['_A__method_name']
```
这里可以看到`__method_name`被改写为了`_A__method_name`。如果有一个名为`B`的子类继承自`A`,那么即使`B`中也定义了一个名为`__method_name`的方法,也不会与`A`中的`__method_name`冲突。
单个下划线和双下划线在Python中有不同的约定和用途,理解这些约定有助于编写更加清晰和易于维护的代码。