我有一个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
MyHandler
> get
(功能)> self
(参数)myDecorator
> __call__
(功能)> self
(参数)上面提到的自我论证是不同的。我的目的是从__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”,则是否已登录。
这是我对这个具体案例感兴趣的主要目标
如果我做错了,请告诉我你的建议/意见!
谢谢!
答案 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)
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建议的那样。