如何在Python类内部定义使用装饰器且不依赖functools.wraps
问题根因
原有代码报错的核心原因是:装饰器check的包装函数调用原方法func时,未传入实例对象self,导致实例方法video1的第一个参数self被u填充,后续参数匹配错位,抛出参数缺失错误。
符合需求的修复代码
以下实现完全满足你的两个要求:无需导入functools.wraps、装饰器全部定义在类内部:
from pytube import YouTube if __name__ == "__main__": class term: def check(func): def parameters(self, u, v): print(f"title:{YouTube(u).title}, views:{YouTube(u).views}, Length:{YouTube(u).length}") # 给被装饰的实例方法传入self即可解决参数错误 func(self, u, v) print("Yes done") return parameters @check def video1(self, u, v): YouTube(u).streams.first().download(v) print("Success") return u = input("Enter the video URL: ") v = input("Enter the path: ") t1 = term() t1.video1(u, v)
类内部定义装饰器的其他实现方式
- 若装饰器不需要访问类/实例属性,可声明为静态方法,用法更灵活:
class term: # 声明为静态方法后,不需要额外接收self/cls参数 @staticmethod def check(func): def parameters(self, u, v): print(f"title:{YouTube(u).title}, views:{YouTube(u).views}, Length:{YouTube(u).length}") func(self, u, v) print("Yes done") return parameters @check def video1(self, u, v): # 业务逻辑不变 pass
- 若需要在
__init__中初始化u、v,调用方法时不需要传参,调整参数逻辑即可:
from pytube import YouTube if __name__ == "__main__": class term: def __init__(self, u, v): self.url = u self.path = v def check(func): def parameters(self): print(f"title:{YouTube(self.url).title}, views:{YouTube(self.url).views}, Length:{YouTube(self.url).length}") func(self) print("Yes done") return parameters @check def video1(self): YouTube(self.url).streams.first().download(self.path) print("Success") return u = input("Enter the video URL: ") v = input("Enter the path: ") t1 = term(u, v) t1.video1()
内容的提问来源于stack exchange,提问作者shaila
相关产品推荐
相关产品推荐

