如果有一个,如何从装饰器的参数中删除 self 参数
How to remove the self argument from a decorator's arguments if there is one
假设我有一个简单的装饰器,一个 类 方法和一个函数,我都用那个装饰器装饰:
import functools
def decorator(func):
@functools.wraps(func)
def call(*args):
print(args)
func(*args)
return call
class cls:
@decorator
def meth(self, a):
pass
@decorator
def func(c):
pass
cls().meth("a")
func("c")
我得到以下输出:
(<__main__.cls object at 0x7f4665c50130>, 'a')
('c',)
但是我想在方法上使用装饰器时删除 self
参数,以便输出变为:
('a',)
('c',)
但是,如果我简单地添加 args.pop(0)
,我将删除第一个参数,即使它不是 self
。如果第一个参数是 self
,我如何才能删除它?
注意:我使用 inspect
阅读了一些带有长代码的解决方案 - 但在这个伟大且易于使用的方法中必须有更短、更简单的方法编程语言 ?
编辑:使用@staticmethod
对我来说不是一个选项,因为我需要方法本身的self
参数。我只是不想印刷.
实现此目的的最简单方法是明确告诉您的装饰器它正在装饰一个 class 方法。您的装饰器将采用一个关键字参数来表示。
def decorator(is_classmethod=False):
def wrapper(func):
@functools.wraps(func)
def call(*args):
if is_classmethod:
print(args[1:]) # omit args[0]
else:
print(args)
return func(*args) # pass all the args to the function
return call
return wrapper
class cls:
@decorator(is_classmethod=True)
def meth(self, a):
pass
@decorator
def func(c):
pass
cls().meth("a")
func("c")
既然用户已经知道他们在装饰什么,你可以避免装饰器中复杂的内省代码,并让用户灵活地处理或不处理第一个参数。
请查看我对这个 SO 问题的回答:Decorators with parameters? 以更简洁(恕我直言)的方式编写带参数的装饰器。 post.
中有一些非常好的答案
您可以通过某些 python 魔法过滤 args
输出。例如:
import functools
def decorator(func):
@functools.wraps(func)
def call(*args):
print(list(filter(lambda x: not hasattr(x, '__dict__'), args)))
func(*args)
return call
class cls:
@decorator
def meth(self, a):
pass
@decorator
def func(c):
pass
cls().meth("a") # ['a']
func("c") # ['c']
假设我有一个简单的装饰器,一个 类 方法和一个函数,我都用那个装饰器装饰:
import functools
def decorator(func):
@functools.wraps(func)
def call(*args):
print(args)
func(*args)
return call
class cls:
@decorator
def meth(self, a):
pass
@decorator
def func(c):
pass
cls().meth("a")
func("c")
我得到以下输出:
(<__main__.cls object at 0x7f4665c50130>, 'a')
('c',)
但是我想在方法上使用装饰器时删除 self
参数,以便输出变为:
('a',)
('c',)
但是,如果我简单地添加 args.pop(0)
,我将删除第一个参数,即使它不是 self
。如果第一个参数是 self
,我如何才能删除它?
注意:我使用 inspect
阅读了一些带有长代码的解决方案 - 但在这个伟大且易于使用的方法中必须有更短、更简单的方法编程语言 ?
编辑:使用@staticmethod
对我来说不是一个选项,因为我需要方法本身的self
参数。我只是不想印刷.
实现此目的的最简单方法是明确告诉您的装饰器它正在装饰一个 class 方法。您的装饰器将采用一个关键字参数来表示。
def decorator(is_classmethod=False):
def wrapper(func):
@functools.wraps(func)
def call(*args):
if is_classmethod:
print(args[1:]) # omit args[0]
else:
print(args)
return func(*args) # pass all the args to the function
return call
return wrapper
class cls:
@decorator(is_classmethod=True)
def meth(self, a):
pass
@decorator
def func(c):
pass
cls().meth("a")
func("c")
既然用户已经知道他们在装饰什么,你可以避免装饰器中复杂的内省代码,并让用户灵活地处理或不处理第一个参数。
请查看我对这个 SO 问题的回答:Decorators with parameters? 以更简洁(恕我直言)的方式编写带参数的装饰器。 post.
中有一些非常好的答案您可以通过某些 python 魔法过滤 args
输出。例如:
import functools
def decorator(func):
@functools.wraps(func)
def call(*args):
print(list(filter(lambda x: not hasattr(x, '__dict__'), args)))
func(*args)
return call
class cls:
@decorator
def meth(self, a):
pass
@decorator
def func(c):
pass
cls().meth("a") # ['a']
func("c") # ['c']