装饰器 是一种 Python 中强大的工具,允许您在不修改函数或类代码的情况下,动态地扩展或修改其行为。 可以将装饰器理解为一种包装器,它接收一个函数(或其他可调用对象)作为输入,并返回一个新的函数(或其他可调用对象),新的函数在调用原始函数前后,可以执行额外的操作。
下面是一个函数装饰器的例子,用于记录函数的调用:
def log_calls(func):
def wrapper(*args, **kwargs):
print(f"Calling function: {func.__name__} with args: {args} and kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"Function {func.__name__} returned: {result}")
return result
return wrapper
@log_calls
def add(a, b):
return a + b
add(5, 3) # 输出函数调用信息
这个例子中,log_calls 就是一个装饰器,他接收函数add作为参数,并返回一个新函数wrapper,新函数除了调用原始函数外,还多了记录函数调用信息的功能。@log_calls 语法糖等效于add = log_calls(add)
装饰器不仅可以装饰函数,还可以装饰类。类装饰器可以用于在类创建后修改类的行为,例如添加属性或方法。
def add_attr(cls):
cls.new_attr = "This is a new attribute"
return cls
@add_attr
class MyClass:
def __init__(self, value):
self.value = value
obj = MyClass(10)
print(obj.new_attr) # 输出 "This is a new attribute"
类装饰器 add_attr 给被装饰的类 MyClass 添加了一个新的类属性 new_attr。
装饰器本身还可以接受参数,这使得装饰器可以更加灵活。
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(num_times=3)
def greet(name):
print(f"Hello, {name}!")
greet("Alice") # 执行三次 greet 函数
装饰器 repeat 接受一个参数 num_times,然后返回一个装饰器函数。然后这个装饰器函数会被应用到 greet 函数上,使得 greet 函数执行多次。
生成器 是一种特殊的函数,它不是一次性返回所有值,而是按需生成值。 这在处理大型数据集或无限序列时非常有用,因为它可以避免将所有数据加载到内存中。
生成器函数使用 yield 关键字来生成值,每当调用生成器的 next() 函数时,生成器函数会从上次 yield 的地方继续执行,直到遇到下一个 yield。
def my_generator(n):
for i in range(n):
yield i
gen = my_generator(3)
print(next(gen)) # 输出 0
print(next(gen)) # 输出 1
print(next(gen)) # 输出 2
# print(next(gen)) # 抛出 StopIteration 异常
在上述代码中,my_generator 函数通过 yield 关键字,每次返回一个值。当没有更多值可生成时,会抛出 StopIteration 异常。
生成器表达式是一种更简洁的方式来创建生成器,其语法类似于列表推导式,但是使用括号 () 而不是方括号 []。
squares = (x**2 for x in range(5))
print(next(squares)) # 输出 0
print(next(squares)) # 输出 1
print(next(squares)) # 输出 4
这个例子创建了一个生成器 squares,可以按需生成 0 到 4 的平方。
上下文管理器 是一种对象,它定义了在 with 语句中使用时,如何管理资源的上下文。
它可以确保在代码块执行前后,资源被正确地分配和释放,例如文件句柄、数据库连接等。
要使用类实现上下文管理器,你需要定义 __enter__ 和 __exit__ 方法。__enter__ 方法在 with 代码块开始时被调用,__exit__ 方法在代码块结束时被调用,即使代码块中抛出了异常。
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
with FileManager("test.txt", "w") as f:
f.write("Hello, context manager!")
这个例子中,FileManager 类实现了上下文管理协议,确保文件在 with 代码块结束后被正确关闭。
使用 @contextmanager 装饰器可以更方便地创建上下文管理器,只需使用 yield 关键字。
from contextlib import contextmanager
@contextmanager
def timer():
start_time = time.time()
yield
end_time = time.time()
print(f"Time taken: {end_time - start_time} seconds")
import time
with timer():
time.sleep(1) # 模拟一些耗时操作
print("done")
在这个例子中,我们定义了一个 timer 上下文管理器来计算代码块的运行时间。
可迭代对象 是指任何可以用 for 循环进行遍历的对象,例如列表、元组、字符串等。
迭代器 是一个可以记住遍历位置的对象,它实现了迭代器协议,即包含 __iter__ 和 __next__ 方法。
可迭代对象通过调用 iter() 方法返回一个迭代器对象,迭代器对象通过 next() 方法逐个返回元素。当没有更多元素时,next() 方法会抛出 StopIteration 异常。
my_list = [1, 2, 3]
my_iterator = iter(my_list)
print(next(my_iterator)) # 输出 1
print(next(my_iterator)) # 输出 2
print(next(my_iterator)) # 输出 3
# print(next(my_iterator)) # 抛出 StopIteration 异常
上述代码展示了如何从一个可迭代对象中获得迭代器,然后使用迭代器进行遍历
你可以通过实现 __iter__ 和 __next__ 方法来创建自定义迭代器。
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.data):
raise StopIteration
value = self.data[self.index]
self.index += 1
return value
my_list = [10,20,30]
my_iterator = MyIterator(my_list)
for item in my_iterator:
print(item)
上述代码中 MyIterator 是一个自定义迭代器,可以遍历一个数组。
函数式编程是编程范式的一种,它将计算视为函数求值的过程,并避免改变状态和使用可变数据。在Python中,可以应用一些函数式编程的概念
lambda 表达式是一种匿名函数,可以在需要函数对象的任何地方使用,lambda 表达式的语法如下:
lambda arguments: expression
add = lambda x, y: x + y
print(add(2, 3)) # Output: 5
lambda 表达式通常和高阶函数一起使用
map函数接受一个函数和一个可迭代对象作为参数,将函数应用于可迭代对象的每一个元素。
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))
print(squares) # Output: [1, 4, 9, 16, 25]
filter函数接受一个函数和一个可迭代对象作为参数,filter函数可以筛选出可迭代对象中满足条件的元素
numbers = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4]
reduce函数接受一个函数和一个可迭代对象作为参数,将可迭代对象的元素累积计算,返回最终的结果。
from functools import reduce
numbers = [1, 2, 3, 4, 5]
sum_of_numbers = reduce(lambda x, y: x + y, numbers)
print(sum_of_numbers) # Output: 15
这只是 Python 高级知识的冰山一角,后续还会继续补充其他主题,敬请期待!