2013-03-04 40 views
4

我有一个类定义如下:Python的装饰带参数和访问类的实例

class SomeViewController(BaseViewController): 
    @requires('id', 'param1', 'param2') 
    @ajaxGet 
    def create(self): 
     #do something here 

是否可以写一个装饰功能:

  1. 注意到ARGS的列表,并可能kwargs和
  2. 访问类装饰在其中定义的方法的类的实例?

所以对于@ajaxGet装饰,还有其中包含我需要检查的值称为typeself一个属性。

谢谢

+1

取决于你的意思。装饰器本身不能访问'self',因为装饰在类的定义期间发生,在任何实例存在之前。但是作为装饰器结果的包装函数会在调用它时知道实例。你能举一个你想达到的例子吗? – BrenBarn 2013-03-04 06:35:04

+0

因此,当我在'SomeViewController'上调用'create'时,装饰的方法可以访问'self'(它被传入'create',因此使用该对象是可能的),并且还可以使用参数来执行检查针对'self'的其他属性 – 2013-03-04 06:45:08

回答

9

是的。事实上,从某种意义上说,你似乎并没有真正的方法来写出一个装饰者,并不是有权访问self。装饰函数包装原始函数,所以它必须至少接受该函数接受的参数(或者可以从中派生出一些参数),否则它不能将正确的参数传递给底层函数。

没有什么特别的,你需要做的,做到这一点,只写一个普通的装饰:

def deco(func): 
    def wrapper(self, *args, **kwargs): 
     print "I am the decorator, I know that self is", self, "and I can do whatever I want with it!" 
     print "I also got other args:", args, kwargs 
     func(self) 
    return wrapper 

class Foo(object): 
    @deco 
    def meth(self): 
     print "I am the method, my self is", self 

然后,你可以使用它:

>>> f = Foo() 
>>> f.meth() 
I am the decorator, I know that self is <__main__.Foo object at 0x0000000002BCBE80> and I can do whatever I want with it! 
I also got other args:() {} 
I am the method, my self is <__main__.Foo object at 0x0000000002BCBE80> 
>>> f.meth('blah', stuff='crud') 
I am the decorator, I know that self is <__main__.Foo object at 0x0000000002BCBE80> and I can do whatever I want with it! 
I also got other args: (u'blah',) {'stuff': u'crud'} 
I am the method, my self is <__main__.Foo object at 0x0000000002BCBE80> 
+0

感谢。有没有办法让装饰参数检查?如果你能回答我会让你的答案成为可接受的答案。 – 2013-03-04 07:32:21

+0

你是什么意思“带参数检查”? – BrenBarn 2013-03-04 07:56:54

+0

装饰者必须接受一些参数,然后在装饰器函数中检查'self'。尽管如此,装饰器函数必须包装在另一个函数中。 – 2013-03-04 08:00:15