优草派  >   Python

Python装饰器代码详解

徐晨光            来源:优草派

Python装饰器是Python语言中比较重要的一个特性,也是Python编程中的一种高级技巧。Python装饰器允许程序员向一个现有的函数或类添加某些额外的功能,而不用对现有的代码进行修改。在Python开发中,装饰器被广泛应用于Web框架、日志记录、异常处理等方面。

Python装饰器代码详解

一、Python装饰器的定义

Python装饰器是一种特殊类型的函数,它可以作为其他函数的参数或返回值,实现对其他函数的扩展功能。Python装饰器本质上是一个闭包函数,它将被修饰的函数作为参数传递,并返回一个新的函数,新函数可能会调用原函数,或在原函数前后添加某些操作。Python装饰器的通用写法如下:

```

def decorator(func):

def wrapper(*args, **kwargs):

# do something before the function is called

value = func(*args, **kwargs)

# do something after the function is called

return value

return wrapper

```

其中,decorator就是装饰器,func就是被装饰的函数。

二、Python装饰器的作用

Python装饰器的作用是实现代码的可复用性和可扩展性。通过使用装饰器,我们可以将公共的功能封装在装饰器中,而不是在每个函数中都写一遍。另外,Python装饰器还可以实现函数的缓存、调用次数统计、性能分析等功能。

三、Python装饰器的使用场景

Python装饰器的应用场景非常广泛,下面列举几个常见的使用场景。

1. 日志记录

使用装饰器可以方便地记录函数的调用日志。例如,我们可以定义一个日志装饰器,在调用函数前后输出日志信息:

```

def log(func):

def wrapper(*args, **kwargs):

print(f'[INFO] {func.__name__} is called with {args}, {kwargs}')

value = func(*args, **kwargs)

print(f'[INFO] {func.__name__} returns {value}')

return value

return wrapper

def foo(x, y):

return x + y

debug_foo = log(foo)

print(debug_foo(1, 2))

```

输出结果:

```

[INFO] foo is called with (1, 2), {}

[INFO] foo returns 3

3

```

2. 函数缓存

使用装饰器可以较方便地实现函数缓存的功能,即将函数的输入参数及对应的输出结果缓存下来,下次调用时可以直接返回缓存中的结果。下面是一个简单的缓存装饰器的例子:

```

def cache(func):

memo = {}

def wrapper(*args):

if args in memo:

print(f'[INFO] {func.__name__}({args}) is in cache')

return memo[args]

result = func(*args)

memo[args] = result

print(f'[INFO] {func.__name__}({args}) is not in cache')

return result

return wrapper

def factorial(n):

if n == 0 or n == 1:

return 1

return n * factorial(n - 1)

cached_factorial = cache(factorial)

print(cached_factorial(5)) # calculate

print(cached_factorial(5)) # from cache

```

输出结果:

```

[INFO] factorial((5,)) is not in cache

[INFO] factorial((4,)) is not in cache

[INFO] factorial((3,)) is not in cache

[INFO] factorial((2,)) is not in cache

[INFO] factorial((1,)) is in cache

[INFO] factorial((2,)) is in cache

[INFO] factorial((3,)) is in cache

[INFO] factorial((4,)) is in cache

[INFO] factorial((5,)) is in cache

120

120

```

3. 方法重载

Python中不支持方法重载(Overload),也就是说,不能有两个同名的方法,参数列表不同。但是,使用装饰器,我们可以模拟出方法重载的效果。下面是一个方法重载装饰器的例子:

```

def overload(func):

registry = {}

def register(cls, *args):

def decorator(func):

name = func.__name__

registry[name] = func

return func

class Spam:

@register(int)

def foo(self, x):

return f'foo(int): {x}'

@register(str)

def foo(self, x):

return f'foo(str): {x}'

s = Spam()

print(s.foo(123))

print(s.foo('abc'))

```

输出结果:

```

foo(int): 123

foo(str): abc

```

四、Python装饰器的实现方法

Python装饰器的实现方法有多种,下面介绍两种比较常用的实现:函数装饰器和类装饰器。

1. 函数装饰器

函数装饰器是Python装饰器最常见的实现方法。函数装饰器定义一个函数,它接受一个函数作为参数,并返回一个新的函数。

下面是一个简单的函数装饰器的例子:

```

def my_decorator(func):

def wrapper(*args, **kwargs):

print('Before the function is called.')

result = func(*args, **kwargs)

print('After the function is called.')

return result

return wrapper

def greet(name):

print(f'Hello, {name}.')

greet = my_decorator(greet)

greet('John')

```

输出结果:

```

Before the function is called.

Hello, John.

After the function is called.

```

2. 类装饰器

类装饰器是Python姿势装饰器的一种实现方法。类装饰器定义一个类,它接受一个函数作为参数,并实现__call__方法,以实现对函数的装饰。

下面是一个简单的类装饰器的例子:

```

class my_decorator:

def __init__(self, func):

self.func = func

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

print('Before the function is called.')

result = self.func(*args, **kwargs)

print('After the function is called.')

return result

def greet(name):

print(f'Hello, {name}.')

greet = my_decorator(greet)

greet('John')

```

输出结果:

```

Before the function is called.

Hello, John.

After the function is called.

```

【原创声明】凡注明“来源:优草派”的文章,系本站原创,任何单位或个人未经本站书面授权不得转载、链接、转贴或以其他方式复制发表。否则,本站将依法追究其法律责任。
TOP 10
  • 周排行
  • 月排行