Python命名规范与最佳实践
立即解锁
发布时间: 2025-08-18 00:44:31 阅读量: 1 订阅数: 4 

### Python 命名规范与最佳实践
#### 1. 私有方法与函数命名争议
在 Python 里,通常会给私有方法和函数加上一个前导下划线。不过,由于 Python 存在名称修饰(name mangling)特性,这一规则颇具争议。当一个方法有两个前导下划线时,解释器会动态地对其重命名,以避免与任何子类的方法发生名称冲突。
有些人为避免子类中的名称冲突,会给私有属性使用两个前导下划线,示例如下:
```python
>>> class Base(object):
... def __secret(self):
... print "don't tell"
... def public(self):
... self.__secret()
>>> Base.__secret
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Base' has no attribute '__secret'
>>> dir(Base)
['_Base__secret', ..., 'public']
>>> class Derived(Base):
... def __secret(self):
... print "never ever"
>>> Derived().public()
don't tell
```
Python 中名称修饰的初衷并非像 C++ 那样提供私有机制,而是确保某些基类能隐式避免在子类中出现冲突,特别是在多重继承的场景下。但对每个属性都使用名称修饰会让代码变得晦涩,这完全不符合 Python 的风格。
因此,有人认为应始终使用显式的名称修饰:
```python
>>> class Base(object):
... def _Base_secret(self): # don't do this !!!
... print "you told it ?"
```
不过,这种做法会在代码里重复类名,所以还是更推荐使用双下划线。
最佳实践是,在子类中编写方法前,查看类的 `__mro__`(方法解析顺序)值,以此避免使用名称修饰。修改基类的私有方法时要格外谨慎。
#### 2. 特殊方法
特殊方法(http://docs.python.org/ref/specialnames.html)以双下划线开头和结尾,普通方法不应采用这种命名方式。它们用于运算符重载、容器定义等。为了提高可读性,应将它们集中放在类定义的开头,示例如下:
```python
>>> class weirdint(int):
... def __add__(self, other):
... return int.__add__(self, other) + 1
... def __repr__(self):
... return '<weirdo %d>' % self
... #
... # public API
... #
... def do_this(self):
... print 'this'
... def do_that(self):
... print 'that'
```
普通方法绝不能使用这类名称,例如不要这样命名方法:
```python
>>> class BadHabits(object):
... def __my_method__(self):
... print 'ok'
```
#### 3. 参数命名
参数使用小写字母,必要时可使用下划线,其命名规则与变量相同。
#### 4. 属性命名
属性名称使用小写字母,必要时可加下划线。多数情况下,它们代表对象的状态,可以是名词、形容词,必要时也可以是一个短短语,示例如下:
```python
>>> class Connection(object):
... _connected = []
... def connect(self, user):
... self._connected.append(user)
... def _connected_people(self):
... return '\n'.join(self._connected)
... connected_people = property(_connected_people)
>>> my = Connection()
>>> my.connect('Tarek')
>>> my.connect('Shannon')
>>> print my.connected_people
Tarek
Shannon
```
#### 5. 类命名
类名始终采用驼峰命名法(CamelCase),若类对模块是私有的,可加一个前导下划线。类和实例变量通常是名词短语,与作为动词短语的方法名形成使用逻辑,示例如下:
```python
>>> class Database(object):
... def open(self):
... pass
>>> class User(object):
... pass
>>> user = User()
>>> db = Database()
>>> db.open()
```
#### 6. 模块和包命名
除了特殊模块 `__init__` 外,模块名使用小写字母,且不带下划线。标准库中的一些示例如下:
- os
- sys
- shutil
当模块对包是私有的,会加一个前导下划线。编译后的 C 或 C++ 模块通常以一个下划线命名,并在纯 Python 模块中导入。包遵循相同规则,因为在命名空间里它们的作用和模块类似。
#### 7. 命名指南
一套通用的命名规则可应用于变量、方法、函数和属性。类和模块的名称在命名空间构建中也起着重要作用,进而影响代码的可读性。以下是一些常见的命名模式和反模式:
- **布尔元素使用 “has” 或 “is” 前缀**:当元素持有布尔值时,“is” 和 “has” 前缀能让其在命名空间中更易读,示例如下:
```python
>>> class DB(object):
... is_connected = False
... has_cache = False
>>> database = DB()
>>> database.has_cache
False
>>> if database.is_connected:
... print "That's a powerful class"
... else:
... print "No wonder..."
No wonder...
```
- **序列元素使用复数形式**:当元素持有一个序列时,使用复数形式是个不错的选择。有些映射在像序列一样暴露时也能从中受益,示例如下:
```python
>>> class DB(object):
... connected_users = ['Tarek']
... tables = {'Customer': ['id', 'first_name',
... 'last_name']}
```
- **字典使用显式名称**:当变量持有一个映射时,应尽可能使用显式名称。例如,如果一个字典保存着一些人的地址,可将其命名为 `person_address`,示例如下:
```python
>>> person_address = {'Bill': '6565 Monty Road',
... 'Pamela': '45 Python street'}
>>> person_address['Pamela']
'45 Python street'
```
- **避免使用通用名称**:除非代码正在构建新的抽象数据类型,否则即使是局部变量,使用如 `list`、`dict`、`sequence` 或 `elements` 等术语也是不可取的,这会让代码难以阅读、理解和使用。同时,要避免使用内置名称,以免在当前命名空间中遮蔽它们。通用动词也应避免使用,除非它们在命名空间中有特定含义。相反,应使用特定领域的术语,示例如下:
```python
>>> def compute(data): # too generic
... for element in data:
... yield element * 12
>>> def display_numbers(numbers): # better
... for number in numbers:
... yield number * 12
```
- **避免使用已存在的名称**:使用上下文中已存在的名称是不好的做法,因为这会让阅读,尤其是调试变得非常混乱,示例如下:
```python
>>> def bad_citizen():
... os = 1
... import pdb; pdb.set_trace()
... return os
>>> bad_citizen()
> <stdin>(4)bad_citizen()
(Pdb) os
1
(Pdb) import os
(Pdb) c
<module 'os' from '/Library/Frameworks/Python.framework/Versions/2.5/
lib/python2.5/os.
pyc'>
```
在这个例子中,`os` 名称被代码遮蔽了。应避免使用内置名称和标准库中的模块名称。尽量创建原创名称,即使它们只在局部上下文中使用。对于关键字,可加一个后缀下划线来避免冲突,示例如下:
```python
>>> def xapian_query(terms, or_=True):
... """if or_ is true, terms are combined
... with the OR clause"""
... pass
```
注意,`class` 通常会被替换为 `klass` 或 `cls`
0
0
复制全文
相关推荐








