Python中级教程 第六课:高级特性与性能优化 1/2

浏览量:26 次 发布时间:2026-01-15 19:02 作者:明扬工控商城 下载docx

最近更新:Python中级教程 第三课:面向对象编程深入与装饰器

第一部分:元类(Metaclass)

1.1 元类基础概念

python

"""

元类是创建类的类。在Python中,一切皆对象:

- 实例由类创建

- 类由type创建(type是默认的元类)

- type也是由type创建的(type是自身的元类)

"""


# type的三个参数:类名、父类元组、属性字典

# 示例:使用type动态创建类


# 1. 创建简单类

SimpleClass = type('SimpleClass', (), {'x': 10, 'y': 20})

obj1 = SimpleClass()

print(f"obj1.x = {obj1.x}, obj1.y = {obj1.y}")


# 2. 创建带有方法的类

def say_hello(self):

   return f"Hello, I'm {self.name}!"


Person = type('Person', (), {

   '__init__': lambda self, name: setattr(self, 'name', name),

   'greet': say_hello

})


p = Person("Alice")

print(p.greet())


# 3. 验证元类

print(f"SimpleClass的类是: {SimpleClass.__class__}")

print(f"SimpleClass是type的实例吗? {isinstance(SimpleClass, type)}")

print(f"type的类是: {type.__class__}")

1.2 自定义元类

python

# 自定义元类必须继承type

class MetaLogger(type):

   """记录类创建的元类"""

   

   def __new__(cls, name, bases, attrs):

       print(f"[MetaLogger] 创建类: {name}")

       print(f"[MetaLogger] 父类: {bases}")

       print(f"[MetaLogger] 属性数量: {len(attrs)}")

       

       # 添加元数据

       attrs['__meta__'] = 'Created by MetaLogger'

       attrs['__created_at__'] = __import__('datetime').datetime.now()

       

       # 调用父类创建类

       return super().__new__(cls, name, bases, attrs)

   

   def __init__(self, name, bases, attrs):

       super().__init__(name, bases, attrs)

       print(f"[MetaLogger] 初始化类: {name}")

   

   def __call__(self, *args, **kwargs):

       """当类被调用创建实例时触发"""

       print(f"[MetaLogger] 创建 {self.__name__} 的实例")

       instance = super().__call__(*args, **kwargs)

       instance.__init_time__ = __import__('datetime').datetime.now()

       return instance


# 使用自定义元类

class MyClass(metaclass=MetaLogger):

   """使用MetaLogger元类的类"""

   

   def __init__(self, value):

       self.value = value

   

   def display(self):

       return f"MyClass(value={self.value})"


print("\n使用自定义元类创建类:")

obj = MyClass(100)

print(f"实例: {obj.display()}")

print(f"元数据: {obj.__meta__}")

print(f"类创建时间: {MyClass.__created_at__}")

print(f"实例创建时间: {obj.__init_time__}")

1.3 元类应用:自动注册类

python

class RegistryMeta(type):

   """自动注册所有子类的元类"""

   

   # 类注册表

   _registry = {}

   

   def __new__(cls, name, bases, attrs):

       # 创建类

       new_class = super().__new__(cls, name, bases, attrs)

       

       # 如果不是基类(避免注册抽象基类)

       if name not in ['BaseModel', 'BasePlugin']:

           # 注册类

           RegistryMeta._registry[name] = new_class

           print(f"已注册类: {name}")

       

       return new_class

   

   @classmethod

   def get_registry(cls):

       return cls._registry


# 使用注册元类

class PluginBase(metaclass=RegistryMeta):

   """插件基类"""

   pass


class PluginA(PluginBase):

   def run(self):

       return "PluginA运行"


class PluginB(PluginBase):

   def run(self):

       return "PluginB运行"


class PluginC(PluginBase):

   def run(self):

       return "PluginC运行"


# 获取所有注册的插件

print("\n已注册的插件类:")

registry = RegistryMeta.get_registry()

for name, plugin_class in registry.items():

   print(f"  - {name}: {plugin_class}")


# 使用注册的类

print("\n创建插件实例:")

plugin_a = PluginA()

print(f"PluginA: {plugin_a.run()}")

1.4 元类应用:强制方法实现

python

class AbstractMeta(type):

   """强制子类实现特定方法的元类"""

   

   def __new__(cls, name, bases, attrs):

       # 定义必须实现的方法

       required_methods = ['save', 'load', 'validate']

       

       # 检查是否是抽象基类

       if name not in ['BaseModel', 'AbstractModel']:

           # 检查是否实现了所有必需方法

           for method in required_methods:

               if method not in attrs:

                   raise TypeError(f"类 {name} 必须实现 {method}() 方法")

               elif not callable(attrs[method]):

                   raise TypeError(f"{name}.{method} 必须是可调用方法")

       

       return super().__new__(cls, name, bases, attrs)


# 抽象基类

class BaseModel(metaclass=AbstractMeta):

   def __init__(self, name):

       self.name = name


# 正确的实现

class UserModel(BaseModel):

   def save(self):

       return f"保存 {self.name}"

   

   def load(self):

       return f"加载 {self.name}"

   

   def validate(self):

       return f"验证 {self.name}"


# 错误的使用(会抛出异常)

try:

   class BadModel(BaseModel):

       def save(self):

           return "只实现了save方法"

       # 缺少load和validate方法

except TypeError as e:

   print(f"创建BadModel时出错: {e}")


# 正确的使用

print("\n正确实现:")

user = UserModel("张三")

print(user.save())

print(user.load())

print(user.validate())

第二部分:描述符(Descriptor)

2.1 描述符基础

python

"""

描述符协议:

- __get__(self, instance, owner) - 获取属性

- __set__(self, instance, value) - 设置属性

- __delete__(self, instance) - 删除属性


描述符类型:

- 数据描述符:实现了__set__或__delete__

- 非数据描述符:只实现了__get__

"""


class SimpleDescriptor:

   """简单的描述符示例"""

   

   def __init__(self, name=None):

       self.name = name

   

   def __get__(self, instance, owner):

       if instance is None:

           return self

       print(f"获取属性 {self.name}")

       return instance.__dict__.get(self.name, "默认值")

   

   def __set__(self, instance, value):

       print(f"设置属性 {self.name} = {value}")

       instance.__dict__[self.name] = value

   

   def __delete__(self, instance):

       print(f"删除属性 {self.name}")

       del instance.__dict__[self.name]


class MyClass:

   # 类属性是描述符

   attr = SimpleDescriptor("attr")

   

   def __init__(self, value):

       self.attr = value  # 触发__set__


# 使用示例

print("描述符基础示例:")

obj = MyClass("初始值")

print(f"属性值: {obj.attr}")    # 触发__get__

obj.attr = "新值"               # 触发__set__

print(f"新属性值: {obj.attr}")

del obj.attr                   # 触发__delete__

print(f"删除后属性值: {obj.attr}")

2.2 属性验证描述符

python

class ValidatedAttribute:

   """属性验证描述符"""

   

   def __init__(self, validator=None, default=None):

       self.validator = validator

       self.default = default

       self.data = {}

   

   def __set_name__(self, owner, name):

       self.name = name

   

   def __get__(self, instance, owner):

       if instance is None:

           return self

       return self.data.get(id(instance), self.default)

   

   def __set__(self, instance, value):

       if self.validator:

           try:

               value = self.validator(value)

           except Exception as e:

               raise ValueError(f"属性 {self.name} 验证失败: {e}")

       

       self.data[id(instance)] = value

   

   def __delete__(self, instance):

       if id(instance) in self.data:

           del self.data[id(instance)]


# 验证器函数

def validate_age(age):

   if not isinstance(age, (int, float)):

       raise TypeError("年龄必须是数字")

   if age < 0 or age > 150:

       raise ValueError("年龄必须在0-150之间")

   return int(age)


def validate_email(email):

   import re

   if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):

       raise ValueError("无效的邮箱地址")

   return email


class Person:

   # 使用验证描述符

   age = ValidatedAttribute(validator=validate_age, default=0)

   email = ValidatedAttribute(validator=validate_email)

   name = ValidatedAttribute()  # 无验证

   

   def __init__(self, name, age, email):

       self.name = name

       self.age = age

       self.email = email

   

   def __repr__(self):

       return f"Person(name={self.name}, age={self.age}, email={self.email})"


# 使用示例

print("\n属性验证描述符示例:")


try:

   p1 = Person("张三", 25, "zhangsan@example.com")

   print(f"有效数据: {p1}")

   

   p2 = Person("李四", -5, "lisi@example.com")

except ValueError as e:

   print(f"错误: {e}")


try:

   p3 = Person("王五", 30, "invalid-email")

except ValueError as e:

   print(f"错误: {e}")


# 更新属性

p1.age = 26

print(f"更新后: {p1}")


# 验证属性独立存储

print(f"两个实例的age不同: {p1.age}, {Person.age.default}")

2.3 延迟加载描述符

python

class LazyProperty:

   """延迟加载描述符"""

   

   def __init__(self, func):

       self.func = func

       self.name = func.__name__

       self.cache = {}

   

   def __get__(self, instance, owner):

       if instance is None:

           return self

       

       # 检查是否已缓存

       instance_id = id(instance)

       if instance_id not in self.cache:

           print(f"计算 {self.name}...")

           self.cache[instance_id] = self.func(instance)

       else:

           print(f"使用缓存的 {self.name}")

       

       return self.cache[instance_id]

   

   def __set__(self, instance, value):

       raise AttributeError(f"{self.name} 是只读属性")


class HeavyComputation:

   """需要大量计算的类"""

   

   def __init__(self, data):

       self.data = data

   

   @LazyProperty

   def processed_data(self):

       """模拟耗时处理"""

       import time

       time.sleep(1)  # 模拟计算耗时

       return [x * 2 for x in self.data]

   

   @LazyProperty

   def statistics(self):

       """统计信息"""

       return {

           'sum': sum(self.data),

           'avg': sum(self.data) / len(self.data),

           'min': min(self.data),

           'max': max(self.data)

       }


# 使用示例

print("\n延迟加载描述符示例:")

data = list(range(1, 11))

obj = HeavyComputation(data)


print("第一次访问 processed_data:")

result1 = obj.processed_data

print(f"结果: {result1[:5]}...")  # 只显示前5个


print("\n第二次访问 processed_data:")

result2 = obj.processed_data  # 使用缓存

print(f"结果: {result2[:5]}...")


print("\n访问 statistics:")

stats = obj.statistics

print(f"统计信息: {stats}")


print("\n再次访问 statistics:")

stats2 = obj.statistics  # 使用缓存

print(f"统计信息: {stats2}")

第三部分:装饰器高级用法

3.1 参数化装饰器

python

import functools

import time


def retry(max_attempts=3, delay=1, exceptions=(Exception,)):

   """重试装饰器工厂"""

   

   def decorator(func):

       @functools.wraps(func)

       def wrapper(*args, **kwargs):

           last_exception = None

           

           for attempt in range(1, max_attempts + 1):

               try:

                   print(f"尝试 {attempt}/{max_attempts}...")

                   return func(*args, **kwargs)

               except exceptions as e:

                   last_exception = e

                   if attempt < max_attempts:

                       print(f"失败,{delay}秒后重试...")

                       time.sleep(delay)

           

           # 所有尝试都失败了

           print(f"所有 {max_attempts} 次尝试都失败了")

           raise last_exception

       

       return wrapper

   

   return decorator


# 模拟不稳定的函数

@retry(max_attempts=3, delay=0.5, exceptions=(ValueError,))

def unstable_function(x):

   import random

   if random.random() < 0.7:  # 70%概率失败

       raise ValueError("随机失败!")

   return f"成功: {x}"


# 使用示例

print("参数化装饰器示例:")

try:

   result = unstable_function("测试")

   print(f"结果: {result}")

except ValueError as e:

   print(f"最终失败: {e}")

3.2 类装饰器

python

class Singleton:

   """单例装饰器"""

   

   def __init__(self, cls):

       self.cls = cls

       self.instance = None

   

   def __call__(self, *args, **kwargs):

       if self.instance is None:

           print(f"创建 {self.cls.__name__} 的唯一实例")

           self.instance = self.cls(*args, **kwargs)

       else:

           print(f"返回 {self.cls.__name__} 的现有实例")

       

       return self.instance


@Singleton

class DatabaseConnection:

   """数据库连接类(应该是单例)"""

   

   def __init__(self, connection_string):

       self.connection_string = connection_string

       print(f"连接到: {connection_string}")

   

   def query(self, sql):

       return f"执行查询: {sql}"


print("\n类装饰器示例:")


# 创建第一个实例

db1 = DatabaseConnection("mysql://localhost:3306/mydb")

print(f"db1: {db1.query('SELECT * FROM users')}")


# 尝试创建第二个实例

db2 = DatabaseConnection("mysql://localhost:3306/mydb")

print(f"db2: {db2.query('SELECT * FROM products')}")


print(f"db1 is db2: {db1 is db2}")

3.3 装饰器堆叠与执行顺序

python

import functools


def decorator1(func):

   @functools.wraps(func)

   def wrapper(*args, **kwargs):

       print("装饰器1: 前")

       result = func(*args, **kwargs)

       print("装饰器1: 后")

       return result

   return wrapper


def decorator2(func):

   @functools.wraps(func)

   def wrapper(*args, **kwargs):

       print("装饰器2: 前")

       result = func(*args, **kwargs)

       print("装饰器2: 后")

       return result

   return wrapper


def decorator3(func):

   @functools.wraps(func)

   def wrapper(*args, **kwargs):

       print("装饰器3: 前")

       result = func(*args, **kwargs)

       print("装饰器3: 后")

       return result

   return wrapper


# 装饰器从上到下应用,从下到上执行

@decorator1

@decorator2

@decorator3

def my_function():

   print("原始函数执行")

   return "结果"


print("装饰器堆叠执行顺序:")

result = my_function()

print(f"最终结果: {result}")


"""

执行顺序说明:

装饰器应用顺序: decorator3 → decorator2 → decorator1

实际执行顺序:

 装饰器1前

   装饰器2前

     装饰器3前

       原始函数

     装饰器3后

   装饰器2后

 装饰器1后

"""

第四部分:性能优化

4.1 使用timeit进行基准测试

python

import timeit

import random


# 测试不同方法的性能

def test_list_comprehension():

   return [i**2 for i in range(1000)]


def test_map_function():

   return list(map(lambda x: x**2, range(1000)))


def test_for_loop():

   result = []

   for i in range(1000):

       result.append(i**2)

   return result


# 使用timeit测试

print("性能基准测试:")


# 测试每种方法

tests = [

   ("列表推导式", "test_list_comprehension()"),

   ("map函数", "test_map_function()"),

   ("for循环", "test_for_loop()")

]


for name, stmt in tests:

   # 使用globals()传递函数

   time_taken = timeit.timeit(

       stmt,

       setup=f"from __main__ import {stmt.split('(')[0]}",

       number=10000  # 执行10000次

   )

   print(f"{name:15} 耗时: {time_taken:.4f}秒")

4.2 使用cProfile进行性能分析

python

import cProfile

import pstats

import io


def fibonacci_recursive(n):

   """递归斐波那契(性能差)"""

   if n <= 1:

       return n

   return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)


def fibonacci_iterative(n):

   """迭代斐波那契(性能好)"""

   if n <= 1:

       return n

   

   a, b = 0, 1

   for _ in range(2, n+1):

       a, b = b, a + b

   return b


def fibonacci_memoization(n, memo={}):

   """记忆化斐波那契"""

   if n in memo:

       return memo[n]

   

   if n <= 1:

       result = n

   else:

       result = fibonacci_memoization(n-1, memo) + fibonacci_memoization(n-2, memo)

   

   memo[n] = result

   return result


def run_fibonacci_tests():

   """运行斐波那契测试"""

   print("计算fibonacci(30)...")

   

   # 递归

   result1 = fibonacci_recursive(30)

   print(f"递归结果: {result1}")

   

   # 迭代

   result2 = fibonacci_iterative(30)

   print(f"迭代结果: {result2}")

   

   # 记忆化

   result3 = fibonacci_memoization(30)

   print(f"记忆化结果: {result3}")


print("\n性能分析示例:")

print("=" * 50)


# 创建性能分析器

profiler = cProfile.Profile()


# 运行性能分析

profiler.enable()

run_fibonacci_tests()

profiler.disable()


# 分析结果

print("\n性能分析结果:")

print("=" * 50)


# 创建统计对象

stats_stream = io.StringIO()

stats = pstats.Stats(profiler, stream=stats_stream)

stats.sort_stats('cumulative')  # 按累计时间排序


# 打印统计信息

stats.print_stats(10)  # 显示前10个

print(stats_stream.getvalue())

4.3 性能优化技巧

python

import time


# 1. 使用局部变量

def test_local_vars():

   """使用局部变量提高性能"""

   upper_bound = 1000000

   total = 0

   for i in range(upper_bound):

       total += i

   return total


# 2. 避免不必要的属性访问

class Point:

   def __init__(self, x, y):

       self.x = x

       self.y = y

   

   def distance_slow(self, other):

       """慢速实现:多次访问属性"""

       import math

       return math.sqrt(

           (self.x - other.x) ** 2 +

           (self.y - other.y) ** 2

       )

   

   def distance_fast(self, other):

       """快速实现:使用局部变量"""

       import math

       x1, y1 = self.x, self.y

       x2, y2 = other.x, other.y

       return math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)


# 3. 使用内置函数和库

def process_data_slow(data):

   """慢速数据处理"""

   result = []

   for item in data:

       result.append(item * 2)

   return result


def process_data_fast(data):

   """快速数据处理"""

   return [item * 2 for item in data]


# 4. 字符串连接优化

def build_string_slow(n):

   """慢速字符串构建"""

   s = ""

   for i in range(n):

       s += str(i)

   return s


def build_string_fast(n):

   """快速字符串构建"""

   parts = []

   for i in range(n):

       parts.append(str(i))

   return "".join(parts)


# 测试性能

print("性能优化技巧示例:")

print("=" * 50)


# 测试字符串构建

n = 10000


start = time.time()

result1 = build_string_slow(n)

time_slow = time.time() - start


start = time.time()

result2 = build_string_fast(n)

time_fast = time.time() - start


print(f"字符串构建 (n={n}):")

print(f"  慢速方法: {time_slow:.4f}秒")

print(f"  快速方法: {time_fast:.4f}秒")

print(f"  速度提升: {time_slow/time_fast:.1f}倍")


# 测试属性访问

print("\n属性访问优化:")

p1 = Point(1, 2)

p2 = Point(4, 6)


# 预热

for _ in range(1000):

   p1.distance_slow(p2)

   p1.distance_fast(p2)


# 正式测试

iterations = 100000


start = time.time()

for _ in range(iterations):

   p1.distance_slow(p2)

time_slow = time.time() - start


start = time.time()

for _ in range(iterations):

   p1.distance_fast(p2)

time_fast = time.time() - start


print(f"  慢速方法: {time_slow:.4f}秒")

print(f"  快速方法: {time_fast:.4f}秒")

print(f"  速度提升: {time_slow/time_fast:.1f}倍")

第五部分:内存管理与垃圾回收

5.1 Python内存管理基础

python

import sys

import gc


# 查看对象内存使用

def show_memory_usage():

   """显示不同类型对象的内存使用"""

   

   objects = [

       ("整数 0", 0),

       ("大整数", 10**100),

       ("空列表", []),

       ("10个元素的列表", list(range(10))),

       ("空字典", {}),

       ("10个键值对的字典", {i: i for i in range(10)}),

       ("空集合", set()),

       ("10个元素的集合", set(range(10))),

   ]

   

   print("对象内存使用情况:")

   print("-" * 50)

   

   for name, obj in objects:

       size = sys.getsizeof(obj)

       print(f"{name:20} 大小: {size:5} 字节")

   

   print("-" * 50)


# 循环引用示例

class Node:

   """链表节点,可能产生循环引用"""

   

   def __init__(self, value):

       self.value = value

       self.next = None

   

   def __repr__(self):

       return f"Node({self.value})"


def create_circular_reference():

   """创建循环引用"""

   n1 = Node(1)

   n2 = Node(2)

   n3 = Node(3)

   

   n1.next = n2

   n2.next = n3

   n3.next = n1  # 循环引用

   

   return n1


print("内存管理基础:")

show_memory_usage()


print("\n循环引用示例:")

# 启用垃圾回收调试

gc.set_debug(gc.DEBUG_STATS | gc.DEBUG_SAVEALL)


# 创建循环引用

print("创建循环引用...")

circular_ref = create_circular_reference()


# 删除引用

print("删除外部引用...")

del circular_ref


# 手动触发垃圾回收

print("手动触发垃圾回收...")

collected = gc.collect()


print(f"回收了 {collected} 个对象")

print(f"垃圾对象列表长度: {len(gc.garbage)}")

5.2 弱引用(Weak Reference)

python

import weakref


class ExpensiveObject:

   """占用大量内存的对象"""

   

   def __init__(self, name):

       self.name = name

       # 模拟大量数据

       self.data = [i for i in range(10000)]

   

   def __del__(self):

       print(f"ExpensiveObject {self.name} 被销毁")

   

   def process(self):

       return f"处理 {self.name} 的数据"


def demonstrate_weakref():

   """演示弱引用的使用"""

   

   print("\n弱引用示例:")

   print("-" * 50)

   

   # 创建对象

   obj = ExpensiveObject("重要对象")

   print(f"创建对象: {obj.name}")

   

   # 创建强引用和弱引用

   strong_ref = obj

   weak_ref = weakref.ref(obj)

   

   print(f"强引用: {strong_ref.process()}")

   print(f"弱引用: {weak_ref()}")

   print(f"弱引用指向的对象: {weak_ref().process() if weak_ref() else '无'}")

   

   # 删除强引用

   print("\n删除强引用...")

   del strong_ref

   del obj

   

   # 检查弱引用

   print(f"弱引用指向的对象: {weak_ref()}")

   

   # 触发垃圾回收

   print("触发垃圾回收...")

   import gc

   gc.collect()

   

   print(f"弱引用指向的对象: {weak_ref() if weak_ref() else '无'}")


# 弱引用字典

def demonstrate_weakvaluedict():

   """演示WeakValueDictionary的使用"""

   

   print("\nWeakValueDictionary示例:")

   print("-" * 50)

   

   from weakref import WeakValueDictionary

   

   # 创建弱值字典

   cache = WeakValueDictionary()

   

   # 添加一些对象

   for i in range(5):

       obj = ExpensiveObject(f"缓存对象{i}")

       cache[f"key{i}"] = obj

       print(f"添加: key{i} -> {obj.name}")

   

   print(f"\n缓存大小: {len(cache)}")

   

   # 显示缓存内容

   print("缓存内容:")

   for key, ref in cache.items():

       obj = ref

       print(f"  {key}: {obj.name if obj else '已销毁'}")

   

   # 删除一些对象的引用

   print("\n删除对象引用...")

   for i in range(3):

       # 从局部变量中删除引用

       if f"key{i}" in cache:

           obj = cache[f"key{i}"]

           del obj

   

   # 触发垃圾回收

   import gc

   gc.collect()

   

   print(f"\n垃圾回收后缓存大小: {len(cache)}")

   print("剩余缓存内容:")

   for key, ref in cache.items():

       obj = ref

       print(f"  {key}: {obj.name if obj else '已销毁'}")


# 运行示例

demonstrate_weakref()

demonstrate_weakvaluedict()

5.3 内存分析工具


明扬工控商城

推荐阅读:

Python中级教程 第六课:高级特性与性能优化 2/2

Python中级教程 第六课:高级特性与性能优化 1/2

Python中级教程 第五课:异步编程与并发 2/2

Python中级教程 第五课:异步编程与并发 1/2

Python中级教程 第四课:上下文管理器、生成器与迭代器

Python中级教程 第三课:面向对象编程深入与装饰器

热门标签:
Python中级教程 第六课:高级特性与性能优化 1/2.docx

将本文的Word文档下载到电脑

推荐度:

下载

全部评论

请登录
产业新闻-明扬资讯网
科技资讯-明扬资讯网