好吧这就是我所拥有的:
我正在玩苏格兰威士忌认证,并且无法弄清楚如何制作一个管理装饰器。这段代码很简单:
class Jinja2Handler(webapp2.RequestHandler):
"""
BaseHandler for all requests all other handlers will
extend this handler
"""
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def get_messages(self, key='_messages'):
try:
return self.request.session.data.pop(key)
except KeyError:
return None
def render_template(self, template_name, template_values={}):
messages = self.get_messages()
if messages:
template_values.update({'messages': messages})
self.response.write(self.jinja2.render_template(
template_name, **template_values))
def render_string(self, template_string, template_values={}):
self.response.write(self.jinja2.environment.from_string(
template_string).render(**template_values))
def json_response(self, json):
self.response.headers.add_header('content-type', 'application/json', charset='utf- 8')
self.response.out.write(json)
def UserArea(fuct):
def Usercheck():
return Usercheck
class PageHandler(Jinja2Handler):
def root(self):
session = self.request.session if self.request.session else None
user = self.request.user if self.request.user else None
profiles = None
emails = None
if user:
profile_keys = [ndb.Key('UserProfile', p) for p in user.auth_ids]
profiles = ndb.get_multi(profile_keys)
emails = models.UserEmail.get_by_user(user.key.id())
self.render_template('home.html', {
'user': user,
'session': session,
'profiles': profiles,
'emails': emails,
})
@UserArea
class UserHandler(Jinja2Handler):
def get(self):
self.render_template('index-2.html', {
})
省略缩进错误......我似乎无法弄清楚......我读过这个想法 How to make a chain of function decorators? 以为我对它有基本的了解......但没有
任何帮助都能以正确的方式指出我......
我接缝的错误很多 TypeError:'NoneType'对象不可调用
答案 0 :(得分:0)
def UserArea(fuct):
def Usercheck():
return Usercheck
您将此作为装饰器使用,但它不会返回任何内容,因此会返回None
。因此,当您尝试实例化已修饰的类时,您正在调用None()
,显然这不起作用。此外,包装函数只返回自身,这很少是你想要的。
很难说出你真正想要装饰者做什么,但通常装饰者的写法是这样的:
import functools
def UserArea(func):
@functools.wraps(func)
def usercheck(*args, **kwargs):
if adminuser: # however this gets defined
return func(*args, **kwargs)
else:
raise Exception("not authorized")
return usercheck
请注意,内部函数将用作装饰对象的包装器,调用装饰对象并返回其结果,允许它用作装饰对象的直接替代在客户端代码中。如果您的包装器功能没有这样做,那么装饰器就会崩溃。
作为进一步的说明,我看到你将它用作类装饰器,这意味着它将在实例化类时被调用。使用返回函数的类装饰器将使类的子类化变得困难,因为实际的类不再具有公共名称。那么,装饰类的一些或所有方法而不是类本身可能更有意义。