我想这就是它们的调用方式,但我会举例说明以防万一.
装饰者类:
class decorator(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print 'something'
self.func(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
装饰功能:
def decorator(func):
def wrapper(*args, **kwargs):
print 'something'
return func(*args, **kwargs)
return wrapper
Run Code Online (Sandbox Code Playgroud)
使用其中一个只是一个品味的问题?有什么实际区别吗?
我在包装类方面遇到问题,并且无法弄清楚我做错了什么。我如何让该包装器与带有“self”参数的任何类函数一起使用?
这是针对 Python 3.7.3 的。问题是我记得包装器以前工作过,但似乎有些东西发生了变化……也许我现在只是做了一些错误的事情,而以前没有。
class SomeWrapper:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
# this fails because self is not passed
# ERROR: __init__() missing 1 required positional argument: 'self'
func_ret = self.func(*args, **kwargs)
# this is also wrong, because that's the wrong "self"
# ERROR: 'SomeWrapper' object has no attribute 'some_func'
# func_ret = self.func(self, *args, **kwargs)
return func_ret
class SomeClass:
SOME_VAL = False
def __init__(self):
self.some_func()
print("Success")
@SomeWrapper
def some_func(self):
self.SOME_VAL = True
def …Run Code Online (Sandbox Code Playgroud) 虽然有很多关于使用类作为装饰器的资源,但我还没有找到任何处理装饰方法问题的资源。这个问题的目标是解决这个问题。我将发布我自己的解决方案,但当然也邀请其他所有人发布他们的解决方案。
标准装饰器类实现的问题在于,python 不会创建被装饰函数的绑定方法:
class Deco:
def __init__(self, func):
self.func= func
def __call__(self, *args):
self.func(*args)
class Class:
@Deco
def hello(self):
print('hello world')
Class().hello() # throws TypeError: hello() missing 1 required positional argument: 'self'
Run Code Online (Sandbox Code Playgroud)
方法装饰器需要克服这个障碍。
从前面的示例中获取类,预计以下事情会起作用:
>>> i= Class()
>>> i.hello()
hello world
>>> i.hello
<__main__.Deco object at 0x7f4ae8b518d0>
>>> Class.hello is Class().hello
False
>>> Class().hello is Class().hello
False
>>> i.hello is i.hello
True
Run Code Online (Sandbox Code Playgroud)
理想情况下,函数__doc__和签名以及类似的属性也被保留。
需要一些帮助来实现/理解装饰器作为一个类如何在 Python 中工作。我发现的大多数例子要么装饰一个类,但将其实现为一个函数,要么实现一个类,但装饰一个函数。我的目标是创建作为类实现的装饰器并装饰类。
更具体地说,我想创建一个@Logger装饰器并在我的一些类中使用它。这个装饰器要做的只是self.logger在类中注入一个属性,所以每次我用它装饰一个类时,@Logger我都可以self.logger.debug()在它的方法中插入一个属性。
一些初步问题:
__init__接收什么参数?我它只会收到装饰类和一些最终的装饰器参数,这实际上是大多数情况下发生的情况,但请查看下面的DOMElementFeatureExtractor. 为什么它会收到所有这些参数?__call__?它将收到什么?@Logger(x='y')) 提供参数?它会被传递给__init__方法吗?__call__?(我能让它发挥作用的唯一方法)@Logger @Counter MyClass:?请看一下这个示例代码。我创建了一些虚拟示例,但最终您可以看到我真实项目中的一些代码。
您可以在最后找到输出。
任何有助于理解作为类实现的 Python 类装饰器的帮助将不胜感激。
谢谢
from abc import ABC, abstractmethod
class ConsoleLogger:
def __init__(self):
pass
def info(self, message):
print(f'INFO {message}')
def warning(self, message):
print(f'WARNING {message}')
def error(self, message):
print(f'ERROR {message}')
def debug(self, message):
print(f'DEBUG {message}')
class Logger(object):
""" Logger decorator, adds a …Run Code Online (Sandbox Code Playgroud)