Django 2.1-'functools.partial'对象没有属性'__name__'

时间:2018-09-11 08:03:29

标签: python django

我最近将Django从2.0.7升级到2.1.1,出现一个新错误,我收到此错误'functools.partial' object has no attribute '__name__'

我想了解我的修复程序是否正确以及导致此新错误发生的原因,我在django发行说明中找不到与此问题相关的任何内容,也许我错过了。

decorators.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__,但不确定是否会破坏其他功能。

有人可以解释吗?

1 个答案:

答案 0 :(得分:6)

使用@functools.wraps() decorator帮您完成此任务,而不是手动复制内容:

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

@wraps()装饰器(通过functools.update_wrapper() function it calls知道如何正确处理functools.partial对象(或者说,它可以处理functools.partial对象没有{{1 }}属性。

__name__类上找到的包装的functools.partial()对象没有View属性是没有问题的,那是不好的,那就是您根本不复制该属性即使在装饰确实具有该属性的函数时也是如此。如果您不想使用__name__,则必须手动复制属性并自己处理异常:

@wraps()

,但要考虑到这不会复制try: wrap.__name__ = function.__name__ except AttributeError: pass try: wrap.__doc__ = function.__doc__ except AttributeError: pass __qualname____module__属性,也不处理__annotations__上设置的任何自定义属性(其他装饰者可能依赖)。 function确实会处理所有这些问题,此外,它还会在装饰器包装函数would let you unwrap the decorator again上设置@functools.wraps()属性。