从装饰器访问函数参数

时间:2011-06-24 15:26:21

标签: python google-app-engine decorator

我有一个Request处理程序和一个装饰器,我想使用装饰器内的self对象

class MyHandler(webapp.RequestHandler):

    @myDecorator
        def get(self):
            #code

更新:请注意第一个和第二个自我之间的区别

class myDecorator(object):

    def __init__(self, f):
        self.f = f

    def __call__(self):
        #work with self
  1. MyHandler> get(功能)> self(参数)
  2. myDecorator> __call__(功能)> self(参数)
  3. 上面提到的自我论证是不同的。我的目的是从__call__函数内部访问第一个self,或者找到一种方法来做类似的事情。

    您可以从装饰器内的get函数访问MyHandlers自身参数吗?

    Update2:我想在google应用引擎中实现一个装饰器来处理自定义登录:

    我有一个类(requestHandler):

    class SomeHandler(webapp.RequestHandler):
        @only_registered_users
        def get(self):
            #do stuff here
    

    我想装饰get函数以检查用户是否登录:

    from util.sessions import Session
    import logging
    
    class only_registered_users(object):
    
        def __init__(self, f):
            self.f = f
    
        def __call__(self):
            def decorated_get(self):
            logging.debug("request object:", self.request)
            session = Session()
    
            if hasattr(session, 'user_key'):
                return self.f(self)
            else:
                self.request.redirect("/login")
    
    
        return decorated_get
    

    我知道如果用户在会话对象中拥有属性“user_key”,则是否已登录。

    这是我对这个具体案例感兴趣的主要目标

    如果我做错了,请告诉我你的建议/意见!

    谢谢!

5 个答案:

答案 0 :(得分:9)

我并不完全清楚你想要的是什么,但是如果你只想使用修饰函数的参数,那么这正是基本的装饰器所做的。所以要从装饰器访问说self.request,你可以这样做:

def log_request(fn):
    def decorated_get(self):
        logging.debug("request object:", self.request)
        return fn(self)
    return decorated_get

class MyHandler(webapp. RequestHandler):
    @log_request
    def get(self):
        self.response.out.write('hello world')

如果你试图访问附加装饰函数的类,那么它有点诡计,你将不得不使用inspect模块作弊。

import inspect

def class_printer(fn):
    cls = inspect.getouterframes(inspect.currentframe())[1][3]
    def decorated_fn(self, msg):
        fn(self,cls+" says: "+msg)
    return decorated_fn

class MyClass():
    @class_printer
    def say(self, msg):
        print msg

在上面的例子中,我们从当前帧(在执行装饰器期间)获取类的名称,然后将其存储在装饰函数中。在这里,我们只是将类名称添加到msg变量之前,然后再将其传递给原始的say函数,但是一旦你上课,你可以用你的想象力去做你想做的事情。名。

>>> MyClass().say('hello')
MyClass says: hello

答案 1 :(得分:1)

尝试这种方法:Can a Python decorator of an instance method access the class?

不是完全相同的问题,但你应该能够使用相同的方法来创建对self的引用或对字典的引用,其中包含某个类的对象,你可以在装饰器中找到它。

答案 2 :(得分:1)

import random

#decorator to the get function in order to check out if the user is logged in or not
def only_registered_users(func):
    def wrapper(handler):
        print 'Checking if user is logged in'
        if random.randint(0, 1):
            print 'User is logged in. Calling the original function.'
            func(handler)
        else:
            print 'User is NOT logged in. Redirecting...'
            # redirect code here
    return wrapper


class MyHandler(object):

    @only_registered_users
    def get(self):
        print 'Get function called'



m = MyHandler()
m.get()

答案 3 :(得分:1)

source

def p_decorate(func):
   def func_wrapper(name):
       return "<p>{0}</p>".format(func(name))
   return func_wrapper

@p_decorate
def get_text(name):
   return "lorem ipsum, {0} dolor sit amet".format(name)

print get_text("John")

# Outputs <p>lorem ipsum, John dolor sit amet</p>

答案 4 :(得分:0)

self的{​​{1}}参数将填充调用装饰方法的实例。没有办法从这里访问装饰器对象 - __call__是一个绑定方法,而你所要求的将要求它实际上是“双重绑定”。 Python不支持这一点,因此装饰器实例将被装饰函数的第一个参数替换。

解决此问题的最简单方法是使用嵌套函数,如@Chris建议的那样。