Python通过装饰类将装饰器动态添加到类的方法中 [英] Python dynamically add decorator to class' methods by decorating class

查看:909
本文介绍了Python通过装饰类将装饰器动态添加到类的方法中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有课:

class x:

    def first_x_method(self):
        print 'doing first_x_method stuff...'

    def second_x_method(self):
        print 'doing second_x_method stuff...'

和这个装饰器

class logger:
    @staticmethod
    def log(func):
        def wrapped(*args, **kwargs):
            try:
                print "Entering: [%s] with parameters %s" % (func.__name__, args)
                try:
                    return func(*args, **kwargs)
                except Exception, e:
                    print 'Exception in %s : %s' % (func.__name__, e)
            finally:
                print "Exiting: [%s]" % func.__name__
        return wrapped

我将如何编写另一个装饰器otherdecorator,以便:

how would I write another decorator otherdecorator so that:

@otherdecorator(logger.log)
class x:

    def first_x_method(self):
        print 'doing x_method stuff...'

    def first_x_method(self):
        print 'doing x_method stuff...'

class x:
      @logger.log
      def first_x_method(self):
          print 'doing first_x_method stuff...'

      @logger.log
      def second_x_method(self):
        print 'doing second_x_method stuff...'

或实际上替换

@otherdecorator(logger.log)
class x:

@otherdecorator 
class x:

otherdecorator包含所有功能 (我不是Python的人,所以要保持温柔)

where otherdecorator contains all the functionality (I'm not a python person so be gentle)

推荐答案

除非有明确的理由将类用作装饰器,否则我认为使用函数定义装饰器通常会更容易.

Unless there is a definite reason to use a class as a decorator, I think it is usually easier to use functions to define decorators.

这是创建类装饰器trace的一种方法,该类使用log装饰器装饰类的所有方法:

Here is one way to create a class decorator trace, which decorates all methods of a class with the log decorator:

import inspect


def log(func):
    def wrapped(*args, **kwargs):
        try:
            print("Entering: [%s] with parameters %s" % (func.__name__, args))
            try:
                return func(*args, **kwargs)
            except Exception as e:
                print('Exception in %s : %s' % (func.__name__, e))
        finally:
            print("Exiting: [%s]" % func.__name__)
    return wrapped


def trace(cls):
    # https://stackoverflow.com/a/17019983/190597 (jamylak)
    for name, m in inspect.getmembers(cls, lambda x: inspect.isfunction(x) or inspect.ismethod(x)):
        setattr(cls, name, log(m))

    return cls


@trace
class X(object):
    def first_x_method(self):
        print('doing first_x_method stuff...')

    def second_x_method(self):
        print('doing second_x_method stuff...')


x = X()
x.first_x_method()
x.second_x_method()

产量:

Entering: [first_x_method] with parameters (<__main__.X object at 0x7f19e6ae2e80>,)
doing first_x_method stuff...
Exiting: [first_x_method]
Entering: [second_x_method] with parameters (<__main__.X object at 0x7f19e6ae2e80>,)
doing second_x_method stuff...
Exiting: [second_x_method]

这篇关于Python通过装饰类将装饰器动态添加到类的方法中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆