将当前类传递给装饰器功能

时间:2014-01-07 14:36:06

标签: python types decorator typechecking python-decorators

我有一个装饰器方法来检查传递给函数的参数类型。

def accepts(*types):
    def check_accepts(f):
        assert len(types) == f.func_code.co_argcount
        def new_f(*args, **kwds):
            for (a, t) in zip(args, types):
                assert isinstance(a, t), \
                       "arg %r does not match %s" % (a,t)
            return f(*args, **kwds)
        new_f.func_name = f.func_name
        return new_f
    return check_accepts

现在,在一个类(在classA.py中),我想要一个方法只接受同一个类的参数:

class ClassA:
    @accepts(WHATTOPUTHERE)
    def doSomething(otherObject):
        # Do something

在其他课程中,我可以放ClassA代替WHATTOPUTHERE,但在classA.py内,ClassA未知。如何将当前类传递给@accepts()函数?

2 个答案:

答案 0 :(得分:1)

使用基于函数的装饰器版本并在类定义之后应用它:

class ClassA:
    def doSomething(otherObject):
        # Do something
ClassA.doSomething = accepts(ClassA)(ClassA.doSomething)

另一种方法是写一个Metaclass,它会在创建类后自动应用它:

class Meta(type):

    def __new__(cls, clsname, bases, dct):
       fields = ('doSomething', ) #Fields on which you want to apply the decorator
       for name, val in dct.items():
           if name in fields:
               dct[name] = accepts(cls)(val)
       return type.__new__(cls, clsname, bases, dct)


class ClassA(object):
    __metaclass__ = Meta
    def doSomething(otherObject):
        pass

不要手动执行new_f.func_name = f.func_name之类的操作,而是使用functools.wraps。这也可以保留文档字符串,参数列表等内容。

from functools import wraps
def accepts(*types):
    def check_accepts(f):
        print "inside"
        assert len(types) == f.func_code.co_argcount
        @wraps(f)
        def new_f(*args, **kwds):

答案 1 :(得分:0)

不会在函数self中添加doSomething变量,然后在args[0]内引用check_accepts(前提是您添加(*args)或额外参数定义)解决你的问题?如果函数doSomething应该是类方法,那么您仍可以将此self外包。怎么样?

  • self添加到类
  • 中的某个虚拟方法
  • 制作一个装饰器,用于填充accepts可以某种方式到达的变量(如元数据)
  • 请务必在doSomething()
  • 之前调用此其他方法
  • 你有班级实例!请享用!

注意:这不是存储此类元数据并在以后使用的唯一方法,您可以按照自己的意愿进行操作。