【问题标题】:decorate specific methods of a class装饰类的特定方法
【发布时间】:2023-03-15 18:54:01
【问题描述】:

我阅读了关于装饰器的文章,我正在尝试装饰一个没有静态方法的类的所有方法。

现在我只是使用我为非静态的特定函数编写的装饰器,所以我想知道是否有一种方法可以同时装饰很多方法但避免使用静态方法

我的装饰器得到了什么:

TypeError: unbound method test() must be called with ClassTest instance as first argument (got nothing instead)

我的装饰器:

def decorator(func):
    def wrapper(self, *args, **kwargs):
        print "test"
        return func(self, *args, **kwargs)
    return wrapper

【问题讨论】:

    标签: python decorator static-methods


    【解决方案1】:

    首先,装饰一个类非常简单:

    def class_decorator(cls):
        # modify cls
        return cls
    

    为了向方法添加/删除/修改功能,您可以使用方法(或变量)的修饰版本调用setattr

    setattr(some_class, some_attribute, decorator(some_callable))
    

    关于区分不同类型的方法,您可以使用几个属性 判断一个方法是否是实例/类/静态方法。

    一个完整的工作示例:

    def _is_instance_method(var):
        if not hasattr(var, '__call__'): # It's not a callable
            return False
        if not hasattr(var, 'im_self'): # It's a callable, but it's not a bound method
            return False
        if getattr(var, 'im_self') is not None: # At this point, if it's a class method,
                                                # it will be bound to the class, while
                                                # the instance method is still unbound
                                                # return False if it's bound (i.e. a class method)
            return False
        return True # All that remains is a callable, that's boundable, but not yet -- an instance method!
    
    def func_decorator(func):
        def func_wrapper(self, *args, **kwargs):
            print "Inside %s!" % (func.__name__,)
            return func(self, *args, **kwargs)
        return func_wrapper
    
    def class_decorator(cls):
        for attr in cls.__dict__:
            var = getattr(cls, attr)
            if _is_instance_method(var): # Determine whether the attribute is an instance method
                setattr(cls, attr, func_decorator(var)) # Replace the function with a decorated one
        return cls # Return the class with its new decorated instance methods
    
    @class_decorator
    class B(object):
    
        @staticmethod
        def static_method():
            return "static method"
    
        @classmethod
        def cls_method(cls):
           return "cls method"
    
        def instance_method(self):
           return "instance method"
    
    print B.static_method() 
    print B.cls_method()
    b = B()
    print b.instance_method()
    

    【讨论】:

      猜你喜欢
      • 2014-01-14
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 2012-01-28
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 2013-05-23
      相关资源
      最近更新 更多