我最近将 Django 从 2.0.7 升级到 2.1.1,出现了一个新错误,其中出现此错误'functools.partial' object has no attribute '__name__'
.
我想了解我的修复是否正确以及是什么导致了这个新错误的发生,我在 django 发行说明中找不到与此问题相关的任何内容,也许我错过了它。
装饰器.py
def auth0_login_required(function):
def wrap(request, *args, **kwargs):
if request.isAuthenticated or request.user.is_staff:
pass
else:
raise Http404()
return function(request, *args, **kwargs)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__ # ERROR HERE
return wrap
它是如何使用的,views.py:
@method_decorator(auth0_login_required, name='dispatch')
class Dashboard(View):
...
对于我刚刚删除的修复wrap.__name__ = function.__name__
,但我不确定它是否会破坏其他东西。
与其手动复制内容,不如使用@functools.wraps()装饰者为您处理这个问题:
from functools import wraps
def auth0_login_required(function):
@wraps(function)
def wrap(request, *args, **kwargs):
if request.isAuthenticated or request.user.is_staff:
pass
else:
raise Http404()
return function(request, *args, **kwargs)
return wrap
The @wraps()
装饰器(通过functools.update_wrapper()它调用的函数知道如何处理functools.partial
正确地对象(或者更确切地说,它可以处理这样的事实:functools.partial
物体没有__name__
属性)。
包裹着就好了functools.partial()
上发现的物体View
类没有__name__
属性,不好的是,即使您正在装饰确实具有该属性的函数,也根本不复制该属性。如果你不想使用@wraps()
您必须手动复制属性并自己处理异常:
try:
wrap.__name__ = function.__name__
except AttributeError:
pass
try:
wrap.__doc__ = function.__doc__
except AttributeError:
pass
但请考虑到这不会复制__qualname__
, __module__
and __annotations__
属性,不处理设置的任何自定义属性function
(其他装饰器可能依赖)。@functools.wraps()
确实照顾到了所有这些,而且它还设置了__wrapped__
装饰器包装函数上的属性会让你再次打开装饰器.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)