从装饰器访问函数参数

Mc-*_*Mc- 8 python google-app-engine decorator

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

class MyHandler(webapp.RequestHandler):

    @myDecorator
        def get(self):
            #code
Run Code Online (Sandbox Code Playgroud)

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

class myDecorator(object):

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

    def __call__(self):
        #work with self
Run Code Online (Sandbox Code Playgroud)
  1. MyHandler> get(功能)> self(参数)
  2. myDecorator> __call__(功能)> self(参数)

上面提到的自我论证是不同的.我的目的是从内部__call__函数访问第一个self ,或者找到一种类似的方法.

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

Update2:我想实现一个装饰器来使用谷歌应用引擎中的自定义登录:

我有一个类(requestHandler):

class SomeHandler(webapp.RequestHandler):
    @only_registered_users
    def get(self):
        #do stuff here
Run Code Online (Sandbox Code Playgroud)

我想装饰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
Run Code Online (Sandbox Code Playgroud)

我知道如果用户已登录,如果在会话对象中具有属性"user_key".

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

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

谢谢!

Chr*_*loe 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')
Run Code Online (Sandbox Code Playgroud)

如果你试图访问附加装饰函数的类,那么它有点诡计,你将不得不使用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
Run Code Online (Sandbox Code Playgroud)

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

>>> MyClass().say('hello')
MyClass says: hello
Run Code Online (Sandbox Code Playgroud)