系统学习Python——装饰器:基础知识-[函数装饰器:方法装饰器]

发布时间:2023年12月22日

分类目录:《系统学习Python》总目录


前文基于类的代码的微妙之处是,尽管它对于拦截简单函数调用有效,但当它应用于类级别的方法函数的时候,并不是很有效:

def decorator(F):
	def __init__(self, func):
		self.func = func
	def __call__(self, *args):
		pass	# 使用self.func和*args
	
class A():
	@decorator
	def method(self, x, y):    # F = decorator(F)
		pass

这一点带来的问题是,当装饰器的__call__方法随后运行的时候,其中的self接收decorator类实例,并且类A的实例不会包含到一个args中。这使得把调用分派给最初的方法变得不可能,即保持了最初的方法函数的装饰器对象,但是没有实例传递给它。

为了支持函数和方法,嵌套函数这一替代方案将有更好的效果:

def decorator(F):
	def wrapper(*args):
		
		return wrapper

@decorator
def func(x, y):
	pass

func(1, 1)

class A():
	@decorator
	def method(self, x, y):    # F = decorator(F)
		pass

X = A()
X.method(1, 1)

当按照这种方法编写时,wrapper在其第一个参数里接收了类的实例,因此它可以分发到最初的方法和访问状态信息。

从技术上讲,这种嵌套函数版本是有效的,因为Python创建了一个绑定的方法对象,并且只有当一个方法属性引用简单函数的时候,才把主体类实例传递给该方法的self参数;当方法引用可调用类的一个实例时,将可调用类的实例传递给self参数,以允许可调用类访问自己的状态信息。

我们在后续的文章中还将看到这一细微的区别在实际案例中的作用。还需要注意的是,嵌套函数可能是支持函数和方法装饰的最直接方式,但是不一定是唯一方式。例如,之前的文章中提到的描述符,调用的时候接收了描述符和主体类实例。

参考文献:
[1] Mark Lutz. Python学习手册[M]. 机械工业出版社, 2018.

文章来源:https://blog.csdn.net/hy592070616/article/details/135139472
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。