Python(考试基础)- 语法

226 阅读18分钟

1. 注释

单行注释

# 这是一个单行注释
print("Hello, World!")  # 输出 'Hello, World!'

多行注释

# 使用多行单行注释
# 这是第一行注释
# 这是第二行注释

# 使用三引号字符串作为多行注释(实际上是一个字符串)
"""
这是一个多行注释,
它跨越了多行。
"""

'''这也是一个多行注释,
   它同样跨越了多行。'''

文档字符串

风格:google

def add(a, b):
    """这是一个示例函数的文档字符串

    Args:
        a (int): 第一个参数
        b (int): 第二个参数

    Returns:
        int: 返回两个参数的和
    """

    return a + b


class MyClass:
    """这是一个简单的类的文档字符串"""

    pass

2. 缩进与换行

缩进

规则:

  • 每个代码块必须使用相同数量的空格或制表符(Tab)。
  • 通常使用 4 个空格 作为缩进的标准(PEP 8 推荐)。
  • 不能混用空格和 Tab。
# 正确缩进
if True:
    print("正确的缩进")  # 缩进 4 个空格

# 错误缩进
if True:
  print("错误的缩进")  # 缩进 2 个空格,不符合 PEP 8

作用:用于定义代码的层级关系。

  • 控制流语句(如 ifforwhile)的代码块。
  • 函数定义类定义 中的内部逻辑。

换行

显式的换行符(反斜杠 \

# 字符串
long_text = "This is a very long " \
            "string"
print(long_text)


# 语句
a = 1
b = 2
res = a + \
      b
      
print(res)

括号隐式换行

long_text = (
    "This is a very long "
    "string."
)
print(long_text)


# 函数参数拆分
result = my_function(
    first_parameter,
    second_parameter,
    third_parameter,
    fourth_parameter
)


# 列表拆分
my_list = [
    "item1", "item2", "item3",
    "item4", "item5", "item6"
]


# 字典拆分
person_info = {
    "name": "Alice",
    "age": 30,
    "email": "alice@example.com",
    "address": {
        "city": "New York",
        "zip_code": "10001"
    }
}

3. 符号与命名

标识符

标识符是用于命名变量、函数、类或其他对象的名称。一个合法的标识符必须符合 Python 的命名规则,否则会导致语法错误。

规则

  • 只能包含字母、数字和下划线:标识符可以使用 a-zA-Z0-9 和下划线 _,但不能包含其他符号或空格。

  • 不能以数字开头:标识符必须以字母或下划线开头,不能以数字开头。

  • 区分大小写:Python 区分大小写,MyVariablemyvariable 是两个不同的标识符。

  • 不能使用保留字:Python 的保留字(或关键字)不能用作标识符。

合法和非法标识符示例

合法标识符非法标识符原因
my_varmy-var包含非法符号 -
var123123var不能以数字开头
_private_varmy var含有空格
CamelCaseclassclass 是 Python 保留字

保留字

import keyword

print(len(keyword.kwlist))  # 35
print(keyword.kwlist)  # ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

1. 控制流相关

  • if:用于条件判断,若条件为 True 则执行相关代码块。
  • elifelse if,在 if 条件不成立时进行其他条件判断。
  • else:用于在 ifelif 块中条件不满足时执行的代码块。
  • while:用于创建 while 循环,条件满足时继续执行循环体。
  • for:用于创建 for 循环,遍历序列中的每个元素。
  • break:跳出当前循环。
  • continue:跳过当前循环的剩余部分,继续执行下一次循环。

2. 函数定义和调用相关

  • def:定义一个函数。
  • return:用于从函数中返回值。
  • lambda:创建匿名函数(即没有名字的函数)。

3. 异常处理相关

  • try:用于开始一个异常处理块。
  • except:用于定义在 try 中发生异常时的处理方式。
  • finally:定义无论是否发生异常,都会执行的代码块。
  • raise:用于引发自定义异常。

4. 运算符和逻辑相关

  • and:逻辑与运算符,连接两个条件表达式。
  • or:逻辑或运算符,连接两个条件表达式。
  • not:逻辑非运算符,反转条件表达式的结果。

5. 类和对象相关

  • class:定义一个类。
  • global:用于声明全局变量,在函数内部修改全局变量。
  • nonlocal:用于声明在嵌套函数中修改外层函数的变量。

6. 标识符和命名相关

  • as:用于将模块或对象赋予一个别名,常见于 import 语句。
  • is:判断两个对象是否是同一对象(身份比较运算符)。
  • in:判断某元素是否在序列中(成员关系运算符)。

7. 其他语句

  • assert:用于调试,检查条件是否为真,若不为真则抛出异常。
  • await:用于在异步编程中等待一个 async 函数的结果。
  • async:用于定义一个异步函数。
  • del:删除对象或变量。
  • pass:占位符语句,表示“什么也不做”。
  • yield:在生成器函数中返回一个值,暂停函数的执行,并在之后继续执行。

8. 导入相关

  • import:导入模块或包。
  • from:从模块中导入特定的内容。

9. 布尔类型和常量

  • True:布尔类型的真。
  • False:布尔类型的假。
  • None:表示“无”或“空”值,常用作函数的默认返回值。

命名规范(PEP 8)

  • 变量、函数、文件

    • 使用小写字母和下划线分隔单词(snake_case)。
    • 示例:my_variable, calculate_sum.
  • 类名

    • 使用大写字母开头的单词(PascalCase)。
    • 示例:MyClass, EmployeeData.
  • 常量

    • 使用全大写字母和下划线分隔单词。
    • 示例:PI = 3.14, MAX_COUNT = 100.
  • 私有变量

    • 使用下划线开头表示变量或方法是私有的。
    • 示例:_private_var, _calculate_internal.
  • 强制私有变量

    • 使用双下划线开头使变量名重整(名称改写以避免冲突)。
    • 示例:__private_var.
  • 预定义的特殊方法或属性

    • 例如 __init__, __str__

4. 运算符

算术运算符

用于执行数学计算。

运算符描述示例
+加法3 + 2 = 5
-减法3 - 2 = 1
*乘法3 * 2 = 6
/除法(浮点数结果)3 / 2 = 1.5
//整除3 // 2 = 1
%取余(模)3 % 2 = 1
**幂运算3 ** 2 = 9

比较运算符

用于比较两个值的大小,返回布尔值 TrueFalse

运算符描述示例
==等于3 == 2 返回 False
!=不等于3 != 2 返回 True
>大于3 > 2 返回 True
<小于3 < 2 返回 False
>=大于或等于3 >= 2 返回 True
<=小于或等于3 <= 2 返回 False

逻辑运算符

用于进行布尔值(逻辑值)的运算。

运算符描述示例
and逻辑与True and False 返回 False
or逻辑或True or False 返回 True
not逻辑非not True 返回 False

位运算符

用于对整数的二进制位进行操作。

运算符描述示例
&按位与5 & 3 返回 1
|按位或5 | 3 返回 7
^按位异或5 ^ 3 返回 6
~按位取反~5 返回 -6
<<左移5 << 1 返回 10
>>右移5 >> 1 返回 2

赋值运算符

用于将值赋给变量。

运算符描述示例
=赋值x = 10
+=加法赋值x += 5 等同于 x = x + 5
-=减法赋值x -= 5 等同于 x = x - 5
*=乘法赋值x *= 5 等同于 x = x * 5
/=除法赋值(浮点数)x /= 5 等同于 x = x / 5
//=整除赋值x //= 5 等同于 x = x // 5
%=取余赋值x %= 5 等同于 x = x % 5
**=幂赋值x **= 5 等同于 x = x ** 5

身份运算符

用于比较两个对象的内存地址是否相同。

运算符描述示例
is判断两个对象是否是同一对象(身份比较)a is b 返回 True(如果 ab 是同一个对象)
is not判断两个对象是否不是同一对象a is not b 返回 True(如果 ab 不是同一个对象)

成员运算符

用于判断某个值是否是某个序列(如字符串、列表、元组、字典等)中的成员。

运算符描述示例
in判断元素是否存在于序列中3 in [1, 2, 3] 返回 True
not in判断元素是否不在序列中4 not in [1, 2, 3] 返回 True

条件表达式(三元运算符)

Python 使用三元运算符的形式来实现条件判断,并根据条件返回不同的值。

运算符描述示例
x if condition else y如果条件为 True,返回 x,否则返回 yx = 10 if a > b else 20

运算符优先级

无括号情况下(建议使用括号),优先级从高到低如下:

  1. 括号 ()
  2. 幂运算 **
  3. 一元运算符:+, -, ~(正负号,取反)
  4. 乘法、除法、整除、取余:*, /, //, %
  5. 加法、减法:+, -
  6. 位运算:<<, >>, &, ^, |
  7. 比较运算:==, !=, <, >, <=, >=
  8. 逻辑运算:not, and, or
  9. 赋值运算:=, +=, -=, *=, /=, //=, %=
  10. 身份运算符 is, is not
  11. 成员运算符 in, not in

5. 变量

赋值

Python 是动态类型语言,所以变量的类型是隐式决定的,故没有显式声明变量类型的语法。定义变量通常指的是给变量赋值。

# 简单赋值
x = 1
x = "Hello"

# 多重赋值
x, y, z = 1, 2, 3

# 交换变量的值
a = 5
b = 10
a, b = b, a

作用域

在 Python 中,变量的作用域(scope)决定了变量在程序中可以访问的范围。

Python 中的作用域通常分为四种类型:局部作用域(local)嵌套作用域(enclosing)全局作用域(global)内建作用域(built-in)

Python 使用 LEGB 规则(Local, Enclosing, Global, Built-in)来查找变量:

  • L(Local):局部作用域,指的是当前函数或方法中的作用域。
  • E(Enclosing):嵌套作用域,指的是外层函数或方法的作用域,即嵌套在当前函数外部的函数作用域。
  • G(Global):全局作用域,指的是模块级别的作用域,即函数外部的全局作用域。
  • B(Built-in):内建作用域,指的是 Python 提供的内建函数、异常和标准库函数所在的作用域。

Python 解释器按照 LEGB 顺序查找变量。如果在局部作用域中没有找到,它会向外层作用域查找,直到全局作用域和内建作用域。

局部作用域 (Local Scope)

局部作用域是指函数或其他结构内部定义的变量,只能在内部使用。

函数

def my_function():
    x = 10  # 局部变量
    print(x)

my_function()  # 输出 10
# print(x)      # 错误:x 在函数外部不可访问

推导式(如列表推导式)

x = [i * 2 for i in range(3)]  # i 是列表推导式内的局部变量

with

with open('test.txt', 'w') as f:
    f.write('Hello')  # f 是 with 块内的局部变量
# print(f)  # 错误:f 在 with 块外不可访问

Lambda

my_lambda = lambda x: x + 2  # x 是 lambda 表达式内的局部变量
print(my_lambda(5))  # 输出 7
# print(x)  # 错误:x 在 lambda 表达式外不可访问

循环(如for循环)

在 Python 3.x 中,循环内的变量在循环结束后仍然是可访问的,但通常只会保存最后一次循环的结果。

for i in range(3):
    x = i * 2  # x 是循环体内的局部变量

print(x)  # 错误:x 在循环体外不可访问

嵌套作用域 (Enclosing Scope)

嵌套作用域指的是外层函数中的变量。如果在局部作用域中找不到该变量,Python 会查找外层函数的作用域。常见于嵌套函数(函数内部定义的函数)。当你想在嵌套函数中修改外层函数的变量时,使用 nonlocal

外部访问内部

def outer_function():
    def inner_function():
        x = 10  # 内层函数的变量
        
    inner_function()
   
    print(x)

outer_function()  # 输出 NameError: name 'x' is not defined

内部访问外部

def outer_function():
    x = 10  # 外层函数的变量
    
    def inner_function():
        print(x)  # 访问外层函数的变量
        
    inner_function()

outer_function()  # 输出 10

内部修改外部

def outer_function():
    x = 10  # 外层函数的局部变量

    def inner_function():
        nonlocal x
        x = 20  # 修改外层函数的变量

    inner_function()
    print(x)  # 输出 20,因为内层函数修改了外层函数的变量

outer_function()

全局作用域 (Global Scope)

全局作用域是指整个模块范围内定义的变量。全局变量可以在函数外部和内部访问,但如果要在函数内部修改全局变量,必须使用 global 关键字。

内部访问全局

x = 10  # 全局变量

def my_function():
    print(x)  # 访问全局变量

my_function()  # 输出 10

内部修改外部

x = 10  # 全局变量

def modify_global():
    global x
    x = 20  # 修改全局变量

modify_global()
print(x)  # 输出 20

内建作用域 (Built-in Scope)

内建作用域包含了 Python 内建的标识符,如 print(), len(), int() 等,它们可以在程序中的任何地方访问。

print(len("Hello"))  # 使用内建函数 len()

6. 控制语句

占位

在 Python 中,空语句(或称为“占位符语句”)是一个不执行任何操作的语句。它通常用于结构上需要语句但实际上没有任何操作的场景。空语句在 Python 中由 pass 关键字表示。

# 在函数和方法中作为占位符
def some_function():
    pass

# 在类定义中作为占位符
class MyClass:
    pass
    
# 在 `if` 语句中作为占位符
if x > 0:
    pass
else:
    print("x is not greater than 0")
    
# 在 `while` 或 `for` 循环中作为占位符
for i in range(5):
    pass

while True:
    pass
    
# 在异常处理结构中作为占位符
try:
    x = 1 / 0  # 会抛出 ZeroDivisionError
except ZeroDivisionError:
    pass  # 捕获异常但不做任何处理

条件

条件语句:用于根据不同的条件执行不同的代码块。Python 提供了几种常见的条件控制结构,包括 ifelifelse

1. if 语句

x = 10
if x > 0:
    print("x 是正数")

2. else 语句

else 语句通常与 if 语句配合使用,表示如果 if 条件不成立(即 if 条件为 False)时,执行 else 语句块。

x = -5
if x > 0:
    print("x 是正数")
else:
    print("x 不是正数")

3. elif 语句

elifelse if 的缩写,它用于在 ifelse 之间添加更多的条件检查。elif 语句提供了一种处理多个条件的方式,可以在多个条件之间选择执行不同的代码块。

x = 15
if x > 20:
    print("x 大于 20")
elif x > 10:
    print("x 大于 10 且小于等于 20")
else:
    print("x 小于等于 10")

4. 嵌套条件

可以将 ifelifelse 语句嵌套使用,构造更复杂的条件判断。

x = 15
y = 5
if x > 10:
    if y > 3:
        print("x 大于 10 且 y 大于 3")
    else:
        print("x 大于 10 且 y 小于等于 3")
else:
    print("x 小于等于 10")

5. 多重条件判断(布尔运算符)

在条件语句中,可以使用布尔运算符(andornot)来组合多个条件。

  • and:当多个条件都为 True 时,整体为 True
  • or:只要其中一个条件为 True,整体为 True
  • not:将条件的布尔值取反。
x = 15
y = 5
if x > 10 and y < 10:
    print("x 大于 10 且 y 小于 10")

if x > 10 or y < 3:
    print("x 大于 10 或者 y 小于 3")

if not(x > 10):
    print("x 不大于 10")

6. 条件表达式(三元运算符)

Python 中的条件表达式(也叫三元运算符)提供了一种简洁的写法,用于根据条件选择值。

x = 10
y = "Positive" if x > 0 else "Negative"
print(y)  # 输出 "Positive"

循环

使用 for 循环

for 循环常用于遍历一个可迭代对象(如列表、元组、字典、集合等),它会按顺序迭代每个元素,直到结束。

# 遍历数字序列
for i in range(5):
    print(i, end=" ")  # 输出 0 1 2 3 4


# 遍历列表,输出每个元素
ls = [1, 2, 3, 4, 5]
for num in ls:
    print(num)
    
    
# 带索引
ls = [1, 2, 3, 4, 5]
for i, num in enumerate(ls):
    print(i, num)

for else

else 子句只有在循环没有通过 break 中断时才会执行。

for i in range(5):
    if i == 3:
        break
    print(i)
else:
    print("循环正常结束")  # 不会输出
for i in range(5):
    print(i)
else:
    print("循环正常结束")  # 有输出

使用 while 循环

count = 0
while count < 5:
    print(count)
    count += 1

while else

for else 一样,如果 while 循环被 break 提前终止,else 子句不会被执行。

count = 0
while count < 5:
    if count == 3:
        break  # 当 count 为 3 时,提前终止循环
    print(count)
    count += 1
else:
    print("while 循环正常结束")
count = 0
while count < 5:
    print(count)
    count += 1
else:
    print("while 循环正常结束")

跳转

break

break 用于提前退出循环,跳出当前forwhile 循环。

for i in range(3):
    for j in range(3):
        if j == 2:
            break  # 仅跳出内层循环
        print(f"i={i}, j={j}")

continue

continue 用于提前退出循环,跳过当前forwhile 循环。

for i in range(3):
   for j in range(3):
       if j == 2:
           continue  # 仅跳过内层循环
       print(f"i={i}, j={j}")

异常

Python 的异常处理机制用于捕获和处理在程序执行过程中出现的错误,确保程序可以在遇到异常时做出合适的反应,而不是直接崩溃。Python 提供了 tryexceptelsefinally 语句来实现异常处理。

基本语法

try:
    # 可能会发生异常的代码
except ExceptionType1:
    # 处理 ExceptionType1 类型的异常
except ExceptionType2:
    # 处理 ExceptionType2 类型的异常
else:
    # 如果没有发生异常,则执行的代码
finally:
    # 无论是否发生异常,都会执行的代码

try 块:

  • 功能try 块包含可能会抛出异常的代码。程序会尝试执行 try 块中的代码,如果发生异常,会跳到 except 块进行处理。
  • 使用场景:将可能出错的代码放在 try 块中进行处理。

except 块:

  • 功能:如果 try 块中的代码发生了异常,程序会跳到相应的 except 块,进行异常处理。
  • 使用场景:捕获并处理特定类型的异常。可以根据不同的异常类型编写不同的处理逻辑。

else 块:

  • 功能:如果 try 块中的代码没有抛出异常,则会执行 else 块的代码。
  • 使用场景:在没有异常发生的情况下执行特定的代码块,通常用于正常执行的后续操作。

finally 块:

  • 功能finally 块中的代码无论是否发生异常都会执行。通常用于清理资源,如关闭文件、网络连接等。
  • 使用场景:在异常处理完之后,需要进行一些清理工作,比如释放资源、关闭文件等。

示例

示例 1:捕获并处理异常

try:
    num1 = 10
    num2 = 0
    result = num1 / num2  # 这里会抛出 ZeroDivisionError
except ZeroDivisionError:
    print("不能除以零!")

输出:

不能除以零!
  • 由于 num2 为零,程序抛出了 ZeroDivisionError 异常,并在 except 块中进行了捕获和处理。

示例 2:捕获多个异常类型

try:
    number = int(input("请输入一个数字:"))
    result = 10 / number
except ValueError:
    print("输入无效,必须是一个数字!")
except ZeroDivisionError:
    print("不能除以零!")

示例:

如果用户输入的是非数字,会输出:

输入无效,必须是一个数字!

如果用户输入的是 0,则输出:

不能除以零!

示例 3:使用 else

try:
    number = int(input("请输入一个数字:"))
    result = 10 / number
except ValueError:
    print("输入无效,必须是一个数字!")
except ZeroDivisionError:
    print("不能除以零!")
else:
    print(f"结果是 {result}")

示例:

如果用户输入的是有效的数字且不为零,则输出:

请输入一个数字:5
结果是 2.0

示例 4:使用 finally

try:
    file = open("example.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("文件未找到!")
else:
    print("文件内容读取成功!")
finally:
    if 'file' in locals():
        file.close()  # 确保文件最终被关闭
    print("文件已关闭")

输出:

  • 如果文件找到了并成功读取,则会输出:

    文件内容读取成功!
    文件已关闭
    
  • 如果文件不存在,则会输出:

    文件未找到!
    文件已关闭
    

示例5. 捕获所有异常

如果不指定异常类型,except 可以捕获所有类型的异常。但是不推荐过于广泛地捕获所有异常,因为这样会掩盖代码中的潜在问题。

try:
    result = 10 / 0  # 这里会抛出 ZeroDivisionError
except:
    print("发生了一个未知的错误!")

输出:

发生了一个未知的错误!

内置异常

内置异常 — Python 3.8.20 文档

自定义异常

除了 Python 内置的异常类外,你还可以自定义异常类,继承自 Exception 类或者它的子类。自定义异常可以帮助我们更好地描述特定场景下的错误。

示例1

class MyCustomError(Exception):
    def __init__(self, message):
        super().__init__(message)

try:
    raise MyCustomError("这是一个自定义错误!")
except MyCustomError as e:
    print(f"捕获到自定义异常:{e}")

输出:

捕获到自定义异常:这是一个自定义错误!

示例2

class DetailedCustomError(Exception):
    def __init__(self, message, code):
        super().__init__(message)
        self.message = message
        self.code = code
    
    
    def get_dict(self):
        return {
            "code": self.code,
            "message": self.message
        }
    
    
    def __str__(self):
        return f"{self.code}: {self.message}"


def complex_function(value):
    if value < 0:
        raise DetailedCustomError("值不能为负数", 400)


try:
    complex_function(-1)
except DetailedCustomError as e:
    print(f"捕获到复杂自定义异常: {e}")
    print(e.get_dict())

输出

捕获到复杂自定义异常: 400: 值不能为负数
{'code': 400, 'message': '值不能为负数'}