知识点回顾
1.类的装饰器
2.装饰器思想的进一步理解:外部修改、动态
3.类方法的定义:内部定义和外部定义
作业:复习类和函数的知识点,写下自己过去29天的学习心得,如对函数和类的理解,对python这门工具的理解等,未来再过几个专题部分我们即将开启深度学习部分。
类和函数在编程中具有不同的结构和用途,可以通过以下特征进行区分。
函数通常使用 def
关键字定义,而类使用 class
关键字定义。函数的定义更简单,仅包含名称和参数列表;类的定义包含名称、属性和方法。
# 函数的定义
def greet(name):
return f"Hello, {name}"
# 类的定义
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}"
函数可以直接调用,而类通常需要实例化后才能调用其方法。函数调用仅需传递参数,而类的方法调用需要通过实例对象。
# 函数调用
print(greet("Alice")) # 输出: Hello, Alice
# 类调用
person = Person("Bob")
print(person.greet()) # 输出: Hello, Bob
类可以包含多个方法(函数)和属性(变量),而函数仅包含一段独立的代码逻辑。类的方法通常通过 self
访问实例属性,函数则直接操作传入的参数。
# 函数内部结构
def add(a, b):
return a + b
# 类内部结构
class Calculator:
def __init__(self):
self.result = 0
def add(self, a, b):
self.result = a + b
return self.result
类可以维护状态(通过属性),函数是无状态的。类的实例可以保存数据,而函数每次调用都是独立的。
# 无状态的函数
def increment(x):
return x + 1
# 有状态的类
class Counter:
def __init__(self):
self.value = 0
def increment(self):
self.value += 1
return self.value
类支持继承和多态,函数不支持。类可以通过继承扩展功能,函数无法直接继承其他函数。
# 类的继承
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
# 函数无法继承
类的名称通常采用驼峰命名法(如 MyClass
),而函数名称通常采用小写和下划线(如 my_function
)。
# 函数命名
def calculate_total():
pass
# 类命名
class ShoppingCart:
pass
通过以上特征,可以清晰地区分类和函数。
函数修饰器用于修饰函数或方法,在函数定义时通过@decorator
语法对目标函数进行包装。类修饰器用于修饰类定义,通过相同语法对类进行动态修改或扩展。
# 函数修饰器示例
def log_func(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@log_func
def greet():
print("Hello")
# 类修饰器示例
def add_method(cls):
def new_method(self):
return "Added method"
cls.new_method = new_method
return cls
@add_method
class MyClass:
pass
函数修饰器通常返回一个新函数(闭包),替换原函数的执行逻辑。类修饰器可以返回修改后的类,或完全替换为新的类实现。
# 函数修饰器实现
def timer(func):
import time
def wrapped(*args):
start = time.time()
result = func(*args)
print(f"Time taken: {time.time()-start}s")
return result
return wrapped
# 类修饰器实现
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
函数修饰器常用于日志记录、权限验证、性能测试等横切关注点。类修饰器常用于单例模式、类属性修改、接口注册等类级别的操作。
# 函数修饰器应用
@login_required
def delete_item():
pass
# 类修饰器应用
@dataclass
class Point:
x: int
y: int
函数修饰器的参数默认接收函数对象,类修饰器的参数默认接收类对象。两者都支持带参数的修饰器模式,但参数传递层级不同。
# 带参数的函数修饰器
def repeat(n):
def decorator(func):
def wrapper(*args):
for _ in range(n):
func(*args)
return wrapper
return decorator
# 带参数的类修饰器
def add_attributes(**kwargs):
def decorator(cls):
for k, v in kwargs.items():
setattr(cls, k, v)
return cls
return decorator
函数修饰器在函数定义时立即执行,但包装函数在被调用时才执行。类修饰器在类定义时立即执行,通常会修改类的元信息或行为。
# 函数修饰器执行顺序
@decorator1
@decorator2
def func(): pass
# 等价于 decorator1(decorator2(func))
# 类修饰器执行顺序
@decoratorA
@decoratorB
class C: pass
# 等价于 decoratorA(decoratorB(C))
@浙大疏锦行