在 Python 中,单下划线 `_` 和双下划线 `__` 作为前缀有不同的含义和约定,以下是它们的核心区别和用法:

 

---

 

### **1. 单下划线前缀 `_xxx`**

#### **含义**

- **约定私有性**:单下划线前缀是开发者之间的约定,表示「这个变量/方法仅供内部使用」,**不会触发 Python 解释器的任何特殊行为**。

- **模块级的隐藏**:在模块中,`from module import *` 时,`_xxx` 不会被导入。

 

#### **示例**

```python

class MyClass:

    def __init__(self):

        self._internal_data = 42 # 约定为内部变量

 

    def _internal_method(self):

        return "This is internal"

```

 

#### **特点**

- **可以访问**:外部依然可以直接访问 `obj._internal_data` 或调用 `obj._internal_method()`。

- **IDE 提示**:部分 IDE 会提示「受保护的访问」。

 

---

 

### **2. 双下划线前缀 `__xxx`**

#### **含义**

- **名称修饰(Name Mangling)**:Python 解释器会自动将 `__xxx` 重命名为 `_类名__xxx`,目的是**避免子类与父类的属性名冲突**。

- **强制私有性**:实际效果是让属性更难被意外覆盖,但依然可以通过修饰后的名称访问。

 

#### **示例**

```python

class Parent:

    def __init__(self):

        self.__secret = "Parent's secret" # 会被重命名为 _Parent__secret

 

class Child(Parent):

    def __init__(self):

        super().__init__()

        self.__secret = "Child's secret" # 会被重命名为 _Child__secret

 

parent = Parent()

child = Child()

 

print(parent.__dict__) # 输出: {'_Parent__secret': "Parent's secret"}

print(child.__dict__) # 输出: {'_Parent__secret': "Parent's secret", '_Child__secret': "Child's secret"}

```

 

#### **特点**

- **无法直接访问**:尝试 `obj.__secret` 会报 `AttributeError`。

- **强制隔离**:子类和父类的 `__secret` 会被重命名为不同的名称,避免冲突。

- **依然可访问**:通过 `obj._Parent__secret` 可以强行访问(但不推荐)。

 

---

 

### **核心区别**

| **特性** | `_xxx` (单下划线) | `__xxx` (双下划线) |

|------------------------|----------------------------------|---------------------------------|

| **解释器行为** | 无特殊处理 | 名称修饰(Name Mangling) |

| **实际用途** | 约定为内部使用 | 强制避免子类命名冲突 |

| **外部直接访问** | 可以(不推荐) | 不可直接访问(需用修饰后的名称) |

| **继承中的表现** | 子类可直接覆盖 | 子类无法覆盖父类的同名属性 |

 

---

 

### **使用场景建议**

1. **单下划线 `_xxx`**:

   - 当你想提示其他开发者「这个属性/方法不要随意修改」时。

   - 模块中定义不希望被 `from module import *` 导入的变量。

 

2. **双下划线 `__xxx`**:

   - 当设计类继承结构时,**防止子类意外覆盖父类属性**。

   - 强制实现「伪私有性」(Python 没有真正的私有变量)。

 

---

 

### **反模式警告**

```python

# 反例:强行访问双下划线变量

obj = MyClass()

print(obj._MyClass__secret) # 可以访问,但破坏封装性

```

 

---

 

### **总结**

- **单下划线**:约定优于强制,是 Python 社区的「君子协定」。

- **双下划线**:解释器级保护,用于避免继承时的命名冲突。

- 遵循这些约定可以让代码更清晰、更健壮。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐