飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 Python简介

    • Python是什么
    • 安装与运行
    • 交互式解释器
    • 注释与编码规范
  • 第2章 变量与数据类型

    • 变量与对象
    • 整数 int
    • 浮点数 float
    • 复数 complex
    • 布尔值 bool
    • 字符串 str
    • 空值 None
    • 类型转换
  • 第3章 运算符与表达式

    • 算术运算符
    • 比较运算符
    • 赋值运算符
    • 逻辑运算符
    • 位运算符
    • 身份与成员运算符
    • 海象运算符
    • 运算符优先级
  • 第4章 流程控制

    • if 语句
    • if-else 语句
    • if-elif-else 语句
    • match-case 语句
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 函数
    • break 与 continue
    • 循环的 else 子句
    • pass 语句
  • 第5章 数据结构

    • 列表创建与索引
    • 列表方法
    • 列表推导式
    • 元组
    • 序列解包
    • 集合
    • 字典创建与访问
    • 字典方法
    • 字典推导式
    • range 对象
  • 第6章 函数

    • 定义函数
    • 位置参数与关键字参数
    • 默认参数
    • 可变参数
    • 解包实参
    • 函数返回值
    • lambda 表达式
    • 文档字符串与注解
    • 作用域与命名空间
    • global 与 nonlocal
  • 第7章 模块与包

    • 模块导入
    • 模块搜索路径
    • 包与相对导入
    • 标准库概览
  • 第8章 文件与输入输出

    • 文件读写
    • 上下文管理器
    • 字符串格式化
    • JSON 与 CSV
  • 第9章 面向对象

    • 类与对象
    • 方法
    • 实例变量与类变量
    • 私有变量
    • 继承
    • 多重继承
    • 魔术方法
    • 属性装饰器
    • 数据类 dataclass
  • 第10章 异常处理

    • 语法错误与异常
    • try-except
    • 异常链与 raise
    • 清理操作
    • 自定义异常
  • 第11章 迭代器与生成器

    • 迭代器协议
    • 生成器
    • 生成器表达式
    • 迭代工具
  • 第12章 高级特性

    • 装饰器
    • 函数式编程
  • 第13章 工程实践

    • 测试与调试
    • 代码质量
    • 虚拟环境

注释与编码规范

Python 的注释以 # 开头,从 # 开始到该物理行结束的所有内容都会被解释器忽略。注释可以出现在行首,也可以跟在代码之后,但不能出现在字符串内部——字符串中的 # 就是普通字符。

# 这是整行注释
x = 1  # 这是行尾注释,解释器只处理 x = 1
text = "# 这不是注释"  # 引号内的 # 是普通字符
print(text)  # 输出: # 这不是注释

注释的实用写法

Python 没有专门的多行注释语法,但可以用连续的单行注释,或利用未赋值的字符串字面值(解释器会将其当作无操作语句执行,但通常不推荐):

# 推荐:连续单行注释
# 计算圆的面积
# 输入:半径 r
# 输出:面积 s

# 不推荐:未赋值字符串虽有效,但可能被某些工具误报
"""
这看起来像注释
但其实是字符串表达式
"""

行尾注释与代码之间应至少留两个空格,这是 PEP 8 的硬性要求:

# 正确
x = x + 1  # 计数器加一

# 错误:空格不足,阅读体验差
x = x + 1 # 计数器加一

注释内容应当解释"为什么"而非"做什么"——代码本身已经说明了做什么:

# 差注释:重复代码语义
x = x + 1  # x 增加 1

# 好注释:解释业务原因
x = x + 1  # 补偿上一步的索引偏移

文档字符串

模块、函数、类和方法的第一条语句如果是字符串字面值,Python 会将其视为文档字符串(docstring),存入对象的 __doc__ 属性,供 help() 和自动化文档工具提取。

def calculate_area(radius):
    """计算圆的面积。

    参数:
        radius (float): 圆的半径,必须为非负数。

    返回:
        float: 圆的面积。

    示例:
        >>> calculate_area(1)
        3.141592653589793
    """
    import math
    return math.pi * radius ** 2

print(calculate_area.__doc__)  # 输出文档字符串

文档字符串使用三重引号,即使只有一行也建议用三重引号,以便后续扩展。单行文档字符串的引号与内容之间不留空格:

def noop():
    """Do nothing."""  # 正确
    pass

def bad():
    """ Do nothing. """  # 错误:多余空格
    pass

源文件编码声明

Python 3.12 源码文件默认采用 UTF-8 编码,无需声明即可使用中文、日文、emoji 等字符。但为保证跨平台一致性,可移植代码应限制标识符为 ASCII 字符。

若文件必须使用其他编码(如遗留系统的 Windows-1252),需在文件第一行声明:

# -*- coding: cp1252 -*-
# 此文件使用 Windows-1252 编码保存
city = "São Paulo"  # 葡萄牙语字符

如果文件以 shebang 行开头,编码声明必须放在第二行:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
print("编码声明在 shebang 之后")

编码声明错误是常见的陷阱。例如,文件实际以 UTF-8 保存却声明为 cp1252,中文字符会被错误解码:

# -*- coding: cp1252 -*-
# 若文件实际包含 UTF-8 编码的中文
name = "中文"  # 可能触发 SyntaxError: encoding problem

PEP 8:代码风格指南

PEP 8 是 Python 官方的代码风格指南,核心目标是提高代码的可读性和一致性。它不是语法规则,不遵守不会导致程序报错,但团队协作中应严格执行。

缩进与空白

Python 用缩进表示代码块层级,PEP 8 规定使用 4 个空格,禁止使用 Tab 键。混用空格和 Tab 会导致 TabError:

# 正确:4 空格缩进
def check(value):
    if value > 0:
        return "positive"
    return "non-positive"

# 错误:混用 Tab 和空格
def broken(value):
\tif value > 0:  # Tab
        return "positive"  # 4 空格
    # TabError: inconsistent use of tabs and spaces

每行代码最长 79 个字符,文档字符串或注释最长 72 个字符。超过长度应使用括号隐式续行:

# 正确:括号内换行
result = some_function(
    first_argument, second_argument,
    third_argument)

# 错误:行尾反斜杠续行,脆弱且难读
result = some_function(first_argument, second_argument, \
                       third_argument)

函数和类之间用两个空行分隔,类的方法之间用一个空行分隔:

class Calculator:

    def add(self, a, b):
        return a + b

    def sub(self, a, b):
        return a - b


def helper():
    pass

命名约定

PEP 8 定义了四种命名风格,每种对应不同的语义层级:

snake_case(小写加下划线)用于变量、函数和模块名。名称应当见名知意,避免单字母变量(循环索引 i、j、k 除外):

# 正确
user_name = "Alice"
def calculate_total(price, tax):
    return price * (1 + tax)

# 错误
n = "Alice"  # n 是什么?
def calc(p, t):  # 缩写过度
    return p * (1 + t)

PascalCase(大写驼峰)用于类名:

class DataProcessor:
    pass

class HttpResponse:
    pass

UPPER_SNAKE_CASE(全大写加下划线)用于常量:

MAX_CONNECTIONS = 100
DEFAULT_TIMEOUT = 30.0
PI = 3.141592653589793

_leading_underscore(单前导下划线)表示"内部使用"的弱私有约定,不会阻止外部访问,但提示调用者不应直接依赖:

class Buffer:
    def __init__(self):
        self._data = []  # 内部状态,不建议外部直接修改

    def append(self, item):
        self._data.append(item)

__double_leading_underscore(双前导下划线)触发名称改写(name mangling),用于避免子类意外覆盖:

class Base:
    def __init__(self):
        self.__secret = 42  # 被改写为 _Base__secret

class Derived(Base):
    def __init__(self):
        super().__init__()
        self.__secret = 99  # 被改写为 _Derived__secret,不会冲突

b = Base()
print(b._Base__secret)  # 42,通过改写后的名称仍可访问

导入规范

导入应分行书写,避免一行导入多个模块。标准库、第三方库、本地模块之间用空行分隔:

# 正确
import os
import sys

import requests

from myproject import utils

# 错误:一行导入多个
import os, sys

# 错误:通配导入,污染命名空间
from os import *

from module import * 应当避免,因为它会导入模块中所有不以下划线开头的名称,可能覆盖现有变量且难以追踪来源。如果模块设计了 __all__ 列表,通配导入会受限制,但仍不推荐在生产代码中使用。

运算符与表达式空格

赋值运算符、比较运算符两侧应各留一个空格,但关键字参数和默认参数值的 = 两侧不留空格:

# 正确
x = 1
y = x + 2
if x == y:
    pass

def connect(timeout=30):  # 默认参数值不留空格
    pass

# 错误
x=1
y = x+2

括号内侧不留空格,逗号后留一个空格:

# 正确
spam(ham[1], {eggs: 2})

# 错误
spam( ham[ 1 ], { eggs: 2 } )

常见风格错误与修正

初学者常犯的错误包括:混用 Tab 和空格、行尾缺少空格、注释与代码对齐不一致、命名风格混乱。以下是一个综合修正示例:

# 修正前:风格混乱
def calc(a,b):
\t#this adds
\treturn a+b

# 修正后:符合 PEP 8
def calculate_sum(first, second):
    """返回两数之和。"""
    return first + second

编码规范和注释不是束缚,而是让代码在数月后仍能被自己读懂的保险。养成在保存文件前检查风格的习惯,配合编辑器插件(如 VS Code 的 Python 扩展或 flake8 工具),可以在编码阶段就消灭大部分风格问题。

上一页
交互式解释器