Python高级编程笔记
01.Python 装饰器
方式1:使用函数的方式给函数定义装饰器
from functools import wraps #无参数装饰器示例代码 def simple_decorator(func): @wraps(func) # 使用了@wraps(func)来装饰wrapper函数,这样可保留greet函数的原始元数据,则greet.__name__返回值为greet,无此句greet.__name__返回值为wrapper def wrapper(*args, **kwargs): print(f"执行函数 {func.__name__} 之前") result = func(*args, **kwargs) print(f"执行函数 {func.__name__} 之后") return result return wrapper @simple_decorator def greet(name): """向指定的人问好""" print(f"你好, {name}!") if __name__ == "__main__": greet("Alice") print(f"函数名: {greet.__name__}") print(f"文档字符串: {greet.__doc__}")
from functools import wraps ''' 带参数的装饰器示例: 定义了一个名为custom_decorator的装饰器工厂函数,它接受两个参数prefix和suffix。custom_decorator函数返回一个实际的装饰器decorator, 该装饰器又返回一个包装函数wrapper。wrapper函数在调用被装饰的函数之前打印prefix,在调用之后打印suffix ''' def custom_decorator(prefix, suffix): def decorator(func): # 注意无参数装饰器和有参数装饰器这里的变化 @wraps(func) def wrapper(*args, **kwargs): print(prefix) result = func(*args, **kwargs) print(suffix) return result return wrapper return decorator @custom_decorator(prefix="开始调用函数", suffix="结束调用函数") def greet(name): """向指定的人问好""" print(f"你好, {name}!") if __name__ == "__main__": greet("Alice") print(f"函数名: {greet.__name__}") print(f"文档字符串: {greet.__doc__}")
方式2:使用类的方式给一个函数定义装饰器
主要需要实现__init__ 和 __call__ 方法,类装饰器带参数和不带参数实现略有不同,主要在不带参数,调用方法func在__init__中传入,如带参数,则参数在__init__方法传入,调用方法func则在__call__中传入.
import time class TimerDecorator: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): start_time = time.time() result = self.func(*args, **kwargs) end_time = time.time() print(f"Function '{self.func.__name__}' took {end_time - start_time:.6f} seconds to execute") return result @TimerDecorator def slow_function(): time.sleep(2) slow_function() # 输出: Function 'slow_function' took 2.001234 seconds to execute
02 生成器
生成器是一种特殊的迭代器,使用yield关键字来产生值,而不是一次性返回所有值。这样可以节省内存,特别是在处理大数据集时。
不适用生成器,使用迭代器达到迭代效果的样例
class Square: def __init__(self,count): self.count = count self.current = 1 ''' __iter__ 方法返回迭代器对象本身。这意味着 Square 类的实例可以被用作迭代器。 ''' def __iter__(self): return self ''' __next__ 方法返回序列中的下一个值 ''' def __next__(self): result = self.current ** 2 if self.current >= self.count: raise StopIteration self.current += 1 return result s1=Square(5) for i in s1: print(i) #打印结果 1 4 9 16
使用生成器替代迭代器 :以下代码和上数迭代器代码功能相同
def squares(count: int): for n in range(1, count): yield n ** 2 for num in squares(5): print(num)
#打印结果 1 4 9 16
生成器完整示例代码
def simple_generator(n): """生成从0到n-1的数字""" for i in range(n): yield i def main(): # 创建生成器对象,返回一个生成器对象 gen,而不是直接执行函数体 gen = simple_generator(5) # 使用生成器对象 使用 for 循环遍历生成器对象,每次迭代时生成器函数会执行到下一个 yield 语句,并返回生成的值 for value in gen: print(value) #打印 0 1 2 3 4 # 重新创建生成器对象,因为之前的已经迭代完毕 gen = simple_generator(5) # 使用生成器表达式 生成器表达式类似于列表推导式,但使用圆括号 () 而不是方括号 []。生成器表达式会生成一个生成器对象,按需生成值 gen_expr = (x * x for x in gen) for value in gen_expr: print(value) # 打印 0 1 4 9 16 if __name__ == "__main__": main()
3.Python上下文管理器
上下文管理器使用with content_manager as cm 语法实现对象在进行和退出时自动完成一些动作,每一个上下文管理器都需要实现__enter__ 方法和__exit__方法
import time class Timer: def __init__(self): self.elapsed_time = 0 def __enter__(self): self.start_time = time.time() return self def __exit__(self, exc_type, exc_value, traceback): self.end_time = time.time() self.elapsed_time = self.end_time - self.start_time print(f"Elapsed time: {self.elapsed_time:.4f} seconds") # 使用 Timer 上下文管理器 with Timer() as timer: # 模拟一些耗时操作 time.sleep(2) print(f"Total elapsed time: {timer.elapsed_time:.4f} seconds")
4. 使用Type 创建动态类
Type可以动态生成一个类,可用于实现插件式开发,动态类的代码可来自外部的文件文本,示例如下:
method_code = ''' def greet(self): return f"Hello, I'm a DynamicClass" ''' # 创建一个字典来存储动态生成的方法 methods_dict = {} # 使用 exec 动态加载方法定义 exec(method_code, globals(), methods_dict) # 使用 type 动态创建一个类 DynamicClass = type( 'DynamicClass', # 类名 (object,), # 父类元组 methods_dict # 类的属性和方法 ) # 创建类的实例 instance = DynamicClass() # 调用类的方法 print(instance.greet()) # 输出: Hello, I'm a DynamicClass
5.Metaclass 元类
元类是用于创建类的“类”。在 Python 中,类本身是对象,而元类是创建这些类对象的类。默认情况下,所有类都是由 type 元类创建的。通过自定义元类,你可以在类创建时自定义类的行为,例如添加属性、修改方法、注册类等。
类的继承 主要用于类之间的代码重用和多态性。
元类 主要用于自定义类的创建过程和行为,提供更高的灵活性和控制力。
class Human(type): @staticmethod def __new__(mcs, *args, **kwargs): class_ = super().__new__(mcs, *args) if kwargs: for name, value in kwargs.items(): setattr(class_, name, value) return class_ class Person(object, metaclass=Human, country='USA', freedom=True): def __init__(self, name, age): self.name = name self.age = age # 测试代码 if __name__ == "__main__": print(Person.country) # 输出: USA print(Person.freedom) # 输出: True person = Person("Alice", 30) print(person.name) # 输出: Alice print(person.age) # 输出: 30 print(person.country) # 输出: USA
6. DataClass 数据类
Dataclasses 模块提供了一种简洁的方式来定义数据类(Data Classes),这些类主要用于存储和管理数据. dataclass 装饰器自动生成了一些特殊方法,如 __init__、__repr__ 等,使得创建和打印对象更加方便
from dataclasses import dataclass, field @dataclass class Person: name: str age: int address: str = "Unknown" # 默认值 # 创建实例 person1 = Person("Alice", 30) person2 = Person("Bob", 25, "New York") print(person1) # 输出: Person(name='Alice', age=30, address='Unknown') print(person2) # 输出: Person(name='Bob', age=25, address='New York')
7. global 和 nonlocal 关键字控制变量范围
global 关键字用于在函数内部声明一个变量是全局变量。这意味着你可以在函数内部访问和修改定义在函数外部的全局变量。
nonlocal 关键字用于在嵌套函数中声明一个变量是非局部变量(即它既不是局部变量也不是全局变量,而是外层函数中的变量)。这使得你可以在内层函数中访问和修改外层函数中的变量。
# 定义一个全局变量 x = 10 def modify_global(): global x # 声明 x 是全局变量 x = 20 # 修改全局变量 x 的值 print(x) # 输出: 10 modify_global() print(x) # 输出: 20 # -------------------- def outer_function(): y = 5 # 外层函数中的变量 def inner_function(): nonlocal y # 声明 y 是非局部变量 y = 10 # 修改外层函数中的变量 y print(y) # 输出: 5 inner_function() print(y) # 输出: 10 outer_function()
8.Mixin模式
Mixin 模式是一种设计模式,它允许你通过组合多个类来创建新的功能。在 Python 中,Mixin 类通常是一些小的、可重用的类,它们提供特定的功能,但不完整到可以独立使用。这些 Mixin 类可以通过多重继承的方式被其他类使用。
# LoggingMixin 提供日志记录功能 class LoggingMixin: def log(self, message): print(f"LOG: {message}") # PermissionMixin 提供权限验证功能 class PermissionMixin: def has_permission(self, permission): return permission in self.permissions # 基本的 User 类 class User: def __init__(self, name): self.name = name # 使用 Mixin 组合新的类 class AdminUser(User, LoggingMixin, PermissionMixin): def __init__(self, name, permissions): super().__init__(name) self.permissions = permissions def perform_action(self, action): if self.has_permission(action): self.log(f"{self.name} is performing {action}") # 执行操作... print(f"{self.name} performed {action}") else: self.log(f"{self.name} does not have permission to perform {action}") # 创建 AdminUser 实例并测试 admin = AdminUser("Alice", ["read", "write", "delete"]) admin.perform_action("read") # 输出: LOG: Alice is performing read # Alice performed read admin.perform_action("execute") # 输出: LOG: Alice does not have permission to perform execute
9. 正则表达式
基本匹配: 使用 re.findall 和正则表达式模式来查找文本中的匹配项。
替换文本: 使用 re.sub 来替换文本中的匹配项。
分割文本: 使用 re.split 来根据正则表达式模式分割文本。
搜索和匹配: 使用 re.search 和 re.findall 来搜索和查找所有匹配项。
编译正则表达式: 使用 re.compile 来编译正则表达式,以便多次使用。
处理多行文本: 使用 re.MULTILINE 标志来处理多行文本。
import re text = "Hello, my email is example@example.com and my phone number is 123-456-7890." # 匹配电子邮件地址 email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' emails = re.findall(email_pattern, text) print("Emails found:", emails) # 输出: Emails found: ['example@example.com'] # 匹配电话号码 phone_pattern = r'\d{3}-\d{3}-\d{4}' phones = re.findall(phone_pattern, text) print("Phone numbers found:", phones) # 输出: Phone numbers found: ['123-456-7890']