Python高级特性 Python

2025-07-14 约 2802 字 阅读时长6 分钟

Python高级特性

类变量、类方法、静态方法

类变量

类变量是被类的所有实例共享的变量,它在类定义内部但在任何类方法外部进行定义。其主要特点为:

  • 所有类的实例都能访问该变量。
  • 若类变量的值被修改,所有实例访问到的都是修改后的值。
  • 类变量通过类名或者实例来访问。

类方法

类方法是绑定到类而非类实例的方法,它通过@classmethod装饰器来定义,并且第一个参数通常是cls(代表类本身)。类方法的主要特点有:

  • 类方法可以访问和修改类变量。
  • 可以通过类名或者实例来调用类方法。
  • 类方法常被用作工厂方法,用于创建类的实例。

静态方法

静态方法是类中不依赖于类或实例的方法,它通过@staticmethod装饰器来定义,并且没有类似selfcls这样的特殊第一个参数。静态方法的主要特点为:

  • 静态方法不能访问或修改类变量和实例变量。
  • 可以通过类名或者实例来调用静态方法。
  • 静态方法通常用于执行与类相关但不依赖于类状态的实用函数。
python
 1class Student():
 2
 3    # 类变量
 4    student_count = 0
 5    
 6    def __init__(self,name:str,sex:str):
 7        self.name = name
 8        self.sex = sex
 9        Student.student_count += 1
10
11    # 类方法
12    @classmethod
13    def get_student_count(cls):
14        return cls.student_count
15    
16    # 类方法
17    @classmethod
18    def from_str(cls,info:str):
19        return cls(info.split(',')[0],info.split(',')[1])
20    
21    # 静态方法
22    @staticmethod
23    def get_name_len(name):
24        return len(name)
25    
26stu1=Student('张三','男')
27print(Student.student_count)
28
29stu2=Student.from_str('张三,男')
30print(Student.student_count)

推导式

在 Python 里,推导式是一种可以从一个或多个可迭代对象快速创建序列(像列表、字典、集合等)的语法结构。它的优点是代码简洁,执行效率较高。

  • 代码简洁:只需要一行代码,就能替代多行的循环和条件语句。
  • 执行效率高:推导式的执行速度通常比传统的循环语句要快。
  • 可读性强:对于熟悉推导式语法的人来说,代码的意图一目了然。

列表推导式

列表推导式是最常用的推导式,其作用是快速生成列表

python
1[表达式 for 变量 in 可迭代对象 if 条件]

字典推导式

字典推导式用于快速生成字典

python
1{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}

集合推导式

集合推导式用于快速生成集合,它的基本语法和列表推导式类似,不过使用的是花括号{}

python
1{表达式 for 变量 in 可迭代对象 if 条件}
python
 1# %%
 2# 列表推导式
 3nums = [1,2,3,4,5,6]
 4letters = ['a','b','c','d','e','f']
 5
 6#---------0----------
 7my_list = []
 8for num in nums:
 9    my_list.append(num)
10print(my_list)
11
12my_list = [num for num in nums]
13print(my_list)
14
15#---------1----------
16my_list = []
17for num in nums:
18    my_list.append(num*2)
19print(my_list)
20
21my_list = [num*2 for num in nums]
22print(my_list)
23
24#---------2----------
25my_list=[]
26for num in nums:
27    if num%2==0:
28        my_list.append(num)
29print(my_list)
30
31my_list=[num for num in nums if num%2==0]
32print(my_list)
33
34#---------3----------
35my_list=[]
36for num in nums:
37    if num%2==0:
38        my_list.append(num*2)
39    else:
40        my_list.append(num)
41print(my_list)
42
43my_list=[num*2 if num%2==0 else num for num in nums]
44print(my_list)
45
46#---------4----------
47my_list=[]
48for num1 in nums:
49    for num2 in nums:
50        my_list.append(num1+num2)
51print(my_list)
52
53my_list=[num1+num2 for num1 in nums for num2 in nums]
54print(my_list)
55
56
57# %%
58# 字典推导式
59nums = [1,2,3,4,5,6]
60letters = ['a','b','c','d','e','f']
61
62#---------0----------
63my_dict = {}
64for num,letter in zip(nums,letters):
65    my_dict[num] = letter
66print(my_dict)
67
68my_dict = {num:letter for num,letter in zip(nums,letters)}
69print(my_dict)
70
71
72# %%
73# 集合推导式
74nums = [1,2,3,1,2,3]
75
76# ----------0---------
77my_set =set()
78for num in nums:
79    my_set.add(num)
80print(my_set)
81
82my_set = { num for num in nums}
83print(my_set)

生成器

在 Python 里,生成器是一种创建迭代器的高效方式,它的实现更为简洁。

生成器特性

  • 惰性求值:只有在请求时才会生成值,减少了内存的占用。
  • 单遍迭代:生成器是不可逆的,遍历结束后就不能再次使用。
  • 状态自动保存:自动保存上一次执行的状态,简化了迭代逻辑。

停止生成器

  • 使用 StopIteration 异常
  • 使用 return 语句
  • 使用生成器对象的 close() 方法
  • 通过外部条件控制生成器

生成器函数

借助 yield 关键字,普通函数能转变为生成器函数。每次调用 next() 时,函数会运行到 yield 处并返回值,随后暂停执行,保存当前状态。待下次调用 next(),函数会从暂停的地方继续执行。

生成器表达式

语法和列表推导式相似,不过使用的是圆括号。生成器表达式采用惰性求值,更节省内存。

python
 1# %%
 2# 生成器函数
 3def square_numbers(nums:list):
 4    for num in nums:
 5        yield num**2
 6
 7# 生成器对象
 8my_generator = square_numbers([1,2,3,4,5])
 9print(my_generator)  # <generator object square_numbers at 0x00000273F74F7D30> 打印的是内存地址
10print(next(my_generator))  # 1
11print(next(my_generator))  # 4
12print(next(my_generator))  # 9
13print(next(my_generator))  # 16
14print(next(my_generator))  # 25
15
16
17# %%
18# 生成器表达式
19my_generator = (num**2 for num in [1,2,3,4,5])
20print(my_generator)  # <generator object <genexpr> at 0x0000024F2AD92A80> 打印的是内存地址
21print(next(my_generator))  # 1
22print(next(my_generator))  # 4
23print(next(my_generator))  # 9
24print(next(my_generator))  # 16
25print(next(my_generator))  # 25
26
27# %%
28# 手动停止生成器
29
30def square_numbers():
31    try:
32        yield '0'
33        yield '1'
34        raise StopIteration   # 手动报错终止生成器
35        yield '2'  # 这行代码不会执行
36    except GeneratorExit:
37        print('GeneratorExit')
38
39#-------------0 使用close关闭生成器------------------
40my_generator = square_numbers()
41print(next(my_generator))  # 0
42my_generator.close() # 关闭生成器,生成器会在当前暂停的 yield 处抛出 GeneratorExit 异常。
43# print(next(my_generator))  # 报错 StopIteration

* 号作用

运算符

数值类型的乘法运算,平方运算

字符串 / 列表 / 元组的重复

重复生成多个相同元素

打包

函数入参定义使用 * 号可以收集为一个元组, ** 可以收集为一个字典

解包

使用 * 可以将迭代对象拆分为独立的参数,** 可以拆分包字典的键值对

python
 1# %%
 2# -----------运算符-----------
 3a=5*2   # 乘号
 4b=5**2  # 指数
 5print(f'a:{a},b:{b}')  # a:10,b:25
 6
 7
 8# %%
 9# -----------生成重复元素-----------
10a = 'ha'*4
11b=[1,3]*4
12c=(1,)*4
13print(a)  # hahahaha
14print(b)  # [1, 3, 1, 3, 1, 3, 1, 3]
15print(c)  # (1, 1, 1, 1)
16
17# %%
18# -----------打包-----------
19# 使用*将入参打包成元组
20def fun_a(*args):
21    print(type(args))  # <class 'tuple'>
22    for arg in args:
23        print(arg)  # 1 2 3
24fun_a(1,2,3)
25
26def fun_b(**kwargs):
27    print(type(kwargs))  # <class 'dict'>
28    for key,value in kwargs.items():
29        print(key,value)  # a 1 b 2 c 3
30
31fun_b(a=1,b=2,c=3)   # 必须传入参数名,否则会报错
32
33# %%
34# -----------解包 注意一个*和两个*区别-----------
35def fun_c(a,b):
36    print(f'a:{a},b:{b}')
37
38a=(1,2,)
39b=[5,6]
40fun_c(*a)  # 使用*将元组/列表解包成多个参数,打印:a:1,b:2
41fun_c(*b)  # 使用*将元组/列表解包成多个参数,打印:a:5,b:6
42print([*a,*b])  # 使用*将元组/列表解包成多个参数,打印:[1, 2, 5, 6]
43
44a={
45    'a':1,
46    'b':2
47}
48b={
49    'c':3,
50    'd':4
51}
52print({**a,**b})  # 使用**将字典解包成多个参数,打印:{'a': 1, 'b': 2, 'c': 3, 'd': 4}

装饰器

装饰器(Decorator)是一种特殊的语法,用于修改或增强函数或类的功能,而无需修改其源代码。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。

装饰器主要是为了解决代码复用功能增强的问题,同时保持代码的简洁性和可读性。

当使用装饰器包装函数时,被装饰后的函数会丢失原函数的一些元信息(如函数名、文档字符串、参数列表等)。functools.wraps 是一个装饰器工具,用于解决这个问题 —— 它可以将原函数的元信息 “复制” 到装饰器内部的 wrapper 函数上,确保被装饰后的函数保留原函数的身份特征。

python
 1import time
 2import functools
 3# %%
 4# python 中函数也是一个对象,可以作为参数传递,也可以作为返回值
 5def square(x):
 6    return x**2
 7
 8def print_fun_return(fun,x):
 9    print(f'{fun.__name__} is runing')
10    return fun(x)
11
12x = print_fun_return(square,3)
13print(x)  # 9
14
15# %%
16#  装饰器
17def my_decorator(fun):
18    def wrapper(*args,**kwargs):
19        start_time=time.time()
20        fun(*args,**kwargs)
21        print(f'函数 {fun.__name__} 运行时间为:{time.time() - start_time} second')
22    return wrapper
23
24def square(x):
25    time.sleep(1)
26    return x**2
27
28# 方式一
29square = my_decorator(square)
30square(2)
31
32#方式二
33@my_decorator
34def square(x):
35    time.sleep(1)
36    return x**2
37square(2)
38
39# %%
40# 装饰器生成器(带参数的装饰器)
41def my_decorator(threshold):
42    def decorator(fun):
43        def wrapper(*args,**kwargs):
44            start_time=time.time()
45            fun(*args,**kwargs)
46            if time.time()-start_time > threshold:
47                print(f'函数 {fun.__name__} 运行时间超过阈值 {threshold}')
48        return wrapper
49    return decorator
50
51def square(x):
52    time.sleep(1)
53    return x**2
54
55# 方式一
56square = my_decorator(1)(square)
57square(3)
58
59# 方式二
60@my_decorator(1)
61def square(x):
62    time.sleep(1)
63    return x**2
64square(3)
65
66# %%
67def my_decorator(fun):
68    def wrapper(*args,**kwargs):
69        start_time=time.time()
70        fun(*args,**kwargs)
71        print(f'函数 {fun.__name__} 运行时间为:{time.time() - start_time} second')
72    return wrapper
73
74@my_decorator
75def square(x):
76    time.sleep(1)
77    return x**2
78
79print(f'function name is {square.__name__}')   # wrapper ,丢失了原来函数的属性
80
81# ======= 使用 functools.wraps 装饰器将原函数的元信息 “复制” 到装饰器内部的 wrapper 函数上
82def my_decorator(fun):
83    @functools.wraps(fun)
84    def wrapper(*args,**kwargs):
85        start_time=time.time()
86        fun(*args,**kwargs)
87        print(f'函数 {fun.__name__} 运行时间为:{time.time() - start_time} second')
88    return wrapper
89
90@my_decorator
91def square(x):
92    time.sleep(1)
93    return x**2
94
95print(f'function name is {square.__name__}')   # wrapper ,丢失了原来函数的属性
使用滚轮缩放
按住拖动