Python核心编程详解:函数参数、类继承与装饰器

Python核心编程详解:函数参数、类继承与装饰器

1 函数参数传递机制

Python函数参数传递采用的是”传对象引用”的方式,具体表现根据传递的对象类型而有所不同。

1.1 可变对象与不可变对象的影响

不可变对象(数字、字符串、元组)在函数内部修改时不会影响外部变量:

1
2
3
4
5
6
7
8
9
10
11
def test_int(param):
print(f"函数内修改前id: {id(param)}")
param += 10 # 创建新对象
print(f"函数内修改后id: {id(param)}")
return param

a = 5
print(f"函数外修改前id: {id(a)}")
result = test_int(a)
print(f"函数外修改后id: {id(a)}")
print(f"a的值: {a}") # 输出5,未改变

可变对象(列表、字典)在函数内部修改时会直接影响外部变量:

1
2
3
4
5
6
7
8
9
def test_list(param_list):
print(f"函数内修改前id: {id(param_list)}")
param_list.append(4) # 直接修改原对象
print(f"函数内修改后id: {id(param_list)}")

my_list = [1, 2, 3]
print(f"函数外修改前id: {id(my_list)}")
test_list(my_list)
print(f"函数外修改后列表: {my_list}") # 输出[1, 2, 3, 4]

1.2 参数传递方式详解

1.2.1 位置参数传递

按照参数定义顺序进行传递:

1
2
3
4
def introduce(name, age, city):
print(f"我叫{name},今年{age}岁,来自{city}")

introduce("张三", 25, "北京") # 参数顺序必须匹配

1.2.2 关键字参数传递

通过参数名指定值,顺序可以任意:

1
2
introduce(age=25, city="北京", name="张三")  # 顺序可打乱
introduce("张三", city="北京", age=25) # 混合使用

1.2.3 默认参数传递

为参数设置默认值,调用时可省略:

1
2
3
4
5
def introduce(name, age=30, city="北京"):  # 默认参数必须在后
print(f"我叫{name},今年{age}岁,来自{city}")

introduce("李四") # 使用默认年龄和城市
introduce("王五", 28) # 仅使用默认城市

1.2.4 可变参数传递

使用*args**kwargs接收不定数量参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 包裹传递
def print_args(*args, **kwargs):
print(f"位置参数: {args}")
print(f"关键字参数: {kwargs}")

print_args(1, 2, 3, name="张三", age=25)

# 解包裹传递
def func(a, b, c):
print(a, b, c)

args = (1, 2, 3)
kwargs = {'a': 1, 'b': 2, 'c': 3}
func(*args) # 元组解包裹
func(**kwargs) # 字典解包裹

2 类继承关系构建

2.1 基本继承语法

Python通过括号表示继承关系:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Animal:  # 父类/基类
def __init__(self, name):
self.name = name

def speak(self):
return "动物叫声"

class Dog(Animal): # 子类/派生类
def __init__(self, name, breed):
super().__init__(name) # 调用父类构造方法
self.breed = breed

# 方法重写
def speak(self):
return "汪汪!"

# 使用示例
dog = Dog("小黑", "拉布拉多")
print(dog.name) # 继承自父类
print(dog.speak()) # 子类重写的方法

2.2 多重继承与方法解析顺序(MRO)

Python支持一个类继承多个父类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Flyable:
def fly(self):
return "飞行中..."

def action(self):
return "飞行"

class Swimmable:
def swim(self):
return "游泳中..."

def action(self):
return "游泳"

class Duck(Flyable, Swimmable): # 多重继承
def __init__(self, name):
self.name = name

# 方法解析顺序(MRO)决定调用哪个父类的方法
def show_action(self):
return f"鸭子{self.name}正在{self.action()}"

duck = Duck("唐纳德")
print(duck.show_action()) # 输出:鸭子唐纳德正在飞行
print(Duck.__mro__) # 查看方法解析顺序

2.3 继承中的访问控制

Python通过命名约定实现访问控制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class BankAccount:
def __init__(self, balance):
self.balance = balance # 公有属性
self._account_id = "12345" # 保护属性(约定)
self.__password = "secret" # 私有属性(名称修饰)

def get_balance(self):
return self.balance

def _internal_method(self): # 保护方法
pass

def __private_method(self): # 私有方法
pass

class SavingsAccount(BankAccount):
def __init__(self, balance, interest_rate):
super().__init__(balance)
self.interest_rate = interest_rate

def show_account_info(self):
print(f"余额: {self.balance}")
print(f"账户ID: {self._account_id}") # 可以访问保护属性
# print(self.__password) # 错误!无法访问私有属性

account = SavingsAccount(1000, 0.03)
account.show_account_info()

3 装饰器原理及实际应用

3.1 装饰器基本原理

装饰器本质上是高阶函数,接受一个函数作为参数并返回一个新函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
def simple_decorator(func):
def wrapper():
print("函数执行前")
result = func()
print("函数执行后")
return result
return wrapper

@simple_decorator
def say_hello():
print("Hello!")

say_hello() # 自动添加了前后打印功能

3.2 实用装饰器示例

3.2.1 计时装饰器

测量函数执行时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time

def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} 执行时间: {end_time - start_time:.4f}秒")
return result
return wrapper

@timer
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))

3.2.2 缓存装饰器

避免重复计算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def cache(func):
cached_results = {}

def wrapper(*args):
if args in cached_results:
print(f"使用缓存结果: {args}")
return cached_results[args]
result = func(*args)
cached_results[args] = result
return result
return wrapper

@cache
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)

print(factorial(5))
print(factorial(5)) # 第二次调用使用缓存
关键特性:独立性

每个被 @cache 装饰的函数,都会拥有 独立的 cached_results 字典

3.2.3 权限验证装饰器

控制函数访问权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def require_login(func):
def wrapper(user, *args, **kwargs):
if not user.get('is_authenticated', False):
raise PermissionError("用户未登录")
return func(user, *args, **kwargs)
return wrapper

def require_admin(func):
def wrapper(user, *args, **kwargs):
if user.get('role') != 'admin':
raise PermissionError("需要管理员权限")
return func(user, *args, **kwargs)
return wrapper

@require_login
@require_admin # 装饰器链式调用
def delete_user(user, username):
return f"用户{username}已被删除"

admin_user = {'is_authenticated': True, 'role': 'admin'}
print(delete_user(admin_user, "test_user"))

3.3 带参数的装饰器

创建可配置的装饰器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def repeat(n):
"""执行函数n次的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
results = []
for i in range(n):
print(f"第{i+1}次执行")
result = func(*args, **kwargs)
results.append(result)
return results
return wrapper
return decorator

@repeat(3)
def greet(name):
return f"Hello, {name}!"

print(greet("World"))

4 完整面向对象编程案例:图形绘制系统

结合参数传递、类继承和装饰器的完整示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import math
import time
from abc import ABC, abstractmethod

# 装饰器:性能监控
def performance_monitor(func):
def wrapper(self, *args, **kwargs):
start_time = time.time()
result = func(self, *args, **kwargs)
end_time = time.time()
print(f"{self.__class__.__name__}.{func.__name__} 执行时间: {end_time-start_time:.6f}秒")
return result
return wrapper

# 抽象基类
class Shape(ABC):
def __init__(self, name, **kwargs):
self.name = name
self.color = kwargs.get('color', 'black')

@abstractmethod
def area(self):
pass

@abstractmethod
def perimeter(self):
pass

@performance_monitor
def display_info(self):
print(f"图形: {self.name}")
print(f"颜色: {self.color}")
print(f"面积: {self.area():.2f}")
print(f"周长: {self.perimeter():.2f}")

# 继承:圆形类
class Circle(Shape):
def __init__(self, name, radius, **kwargs):
super().__init__(name, **kwargs)
self.radius = radius

def area(self):
return math.pi * self.radius ** 2

def perimeter(self):
return 2 * math.pi * self.radius

# 继承:矩形类
class Rectangle(Shape):
def __init__(self, name, width, height, **kwargs):
super().__init__(name, **kwargs)
self.width = width
self.height = height

def area(self):
return self.width * self.height

def perimeter(self):
return 2 * (self.width + self.height)

# 多重继承:正方形类
class Square(Rectangle):
def __init__(self, name, side, **kwargs):
# 调用父类构造函数,但将width和height都设为side
super().__init__(name, side, side, **kwargs)
self.side = side

# 重写显示方法
@performance_monitor
def display_info(self):
print(f"图形: {self.name} (正方形)")
print(f"颜色: {self.color}")
print(f"边长: {self.side}")
print(f"面积: {self.area():.2f}")
print(f"周长: {self.perimeter():.2f}")

# 图形管理器类
class ShapeManager:
def __init__(self):
self.shapes = []

def add_shape(self, shape):
self.shapes.append(shape)

@performance_monitor
def display_all_shapes(self):
for shape in self.shapes:
print("-" * 30)
shape.display_info()

def total_area(self):
return sum(shape.area() for shape in self.shapes)

# 使用示例
if __name__ == "__main__":
manager = ShapeManager()

# 使用不同参数传递方式创建图形
circle = Circle("圆形1", radius=5, color="red")
rectangle = Rectangle("矩形1", width=4, height=6, color="blue")
square = Square("正方形1", side=5, color="green")

manager.add_shape(circle)
manager.add_shape(rectangle)
manager.add_shape(square)

manager.display_all_shapes()
print(f"\n所有图形总面积: {manager.total_area():.2f}")

这个完整案例展示了: 1. 函数参数传递:使用关键字参数、默认参数等不同方式 2. 类继承关系:抽象基类、单继承、多重继承 3. 装饰器应用:性能监控装饰器 4. 面向对象特性:封装、继承、多态

核心组件说明:
  • ABC:是一个特殊的基类(Abstract Base Class 的缩写),所有自定义的抽象基类都需要继承它。它的作用是标记一个类为 “抽象类”,使其无法被直接实例化,只能作为父类被继承。
  • abstractmethod:是一个装饰器,用于标记抽象类中的 “抽象方法”。被该装饰器标记的方法必须在子类中被重写实现,否则子类仍然是抽象类,无法被实例化。

通过这个教程,你应该对Python函数参数传递、类继承和装饰器有了深入的理解。这些概念是Python面向对象编程的核心,掌握它们将大大提高你的编程能力。