在类中使用装饰器

时间:2016-10-08 10:03:19

标签: python oop decorator

我正在尝试在我的应用中实现一个简单的日志记录功能。

class messages(object):

    # Implement decorator here
    def on(self):
        def wrapper():
            # Do something here
        return wrapper

    def off(self):
        def wrapper():
            # Do something here
        return wrapper


class website(object):

    @messages.on #This line can be switched on/off
    def login(self):
        # Do a whole bunch of stuff here
        self.response = "[+] Login Succeeded!"

website = website()
website.login() # prints self.response based on @messages.on/off

但我不确定我需要在装饰师身上申请什么。我尝试过创建实例并添加参数但主要是接收TypeError。我对装饰者来说相当新鲜。任何帮助将不胜感激,我希望下次能记住这一点。

2 个答案:

答案 0 :(得分:1)

  1. 如果您只想让狗吠(如示例所示),则无需启用装饰器

    this
  2. 如果要为类中的某些函数启用日志记录,可以使用以下代码执行此操作的代码

    class Dog(object):
        def __init__(self):
            self.sound = "Woof!"
    
        def bark(self):
            return self.sound
    
  3. 示例:

    from functools import wraps
    
    class Utilities(object):
    
        @staticmethod  # no default first argument in logger function
        def logger(f):  # accepts a function
            @wraps(f)  # good practice https://docs.python.org/2/library/functools.html#functools.wraps
            def wrapper(self, *args, **kwargs):  # explicit self, which means this decorator better be used inside classes only
                print("Before:", self.sound)
                result = f(self, *args, **kwargs)
                print("After:", self.sound)
                return result
            return wrapper
    
    
    class Dog(object):
        def __init__(self):
            self.sound = "Woof!"
    
        @Utilities.logger
        def run(self):
            """Perform running movement"""
            print("Running")
    

    虽然毕竟不需要在>>> dog = Dog() >>> dog.run() Before: Woof! Running After: Woof! 类中存储装饰器功能 - 但最好有一个名为Utilities的单独模块(文件)并将装饰器作为独立函数放在那里

答案 1 :(得分:0)

以下是您可以使用的示例装饰器:

class Utilities:

    @staticmethod
    def add_logger(func):
        def wrapped_func(*args, **kwargs):
            # Sample logic, feel free to update this
            try:
                func_response = func(*args, **kwargs)
            except:
                print 'I am error handled by logger'
                func_response = None
            return func_response
        return wrapped_func

让我们现在定义你的课程:

class Dog(object):

    @Utilities.add_logger 
    def bark(self):
        print 'In bark'

    @Utilities.add_logger 
    def my_error_function(self):
        print 'In my_error_function'
        raise Exception  # <--- Raises Exception

现在,我们来看看它的工作原理:

>>> dog = Dog()
>>> dog.bark()
In bark
>>> dog.my_error_function()
In my_error_function
I am error handled by logger  # Content from logger in case of exception

注意: 您不应该在这里创建class存储实用程序功能。创建一个单独的实用程序文件并在那里编写这些函数。

没有上课,你的装饰师应该是(让我们说 utility.py ):

def add_logger(func):
    def wrapped_func(*args, **kwargs):
        # Sample logic, feel free to update this
        try:
            func_response = func(*args, **kwargs)
        except:
            print 'I am error handled by logger'
            func_response = None
        return func_response
    return wrapped_func

使用它,只需:

import utility

class Dog(object):

    @utility.add_logger
    def bark(self):
        print 'In bark'