2016-02-20 53 views
1

我读到关于装饰器,我想装饰一个类的所有方法没有静态方法。装饰一类的具体方法

现在,我只是用我写的是不是静态的特定功能的装饰,所以我想如果有一种方法既装点了很多方法,但要避免静态的

什么我与我的装饰:

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 

回答

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() 
+0

非常感谢,现在试试这个 – FalahDor