Django 2.1-'functools.partial'对象没有属性'__name__' [英] Django 2.1 - 'functools.partial' object has no attribute '__name__'

查看:364
本文介绍了Django 2.1-'functools.partial'对象没有属性'__name__'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近将Django从2.0.7升级到2.1.1,发生了一个新错误,我收到此错误'functools.partial'对象没有属性'__name __'

I recently upgraded Django from 2.0.7 to 2.1.1, a new error occurs in which I get this error 'functools.partial' object has no attribute '__name__'.

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

I'd like to understand if my fix is right and what caused this new error to happen, I couldn't find anything on the django release notes related to this issue, maybe I missed it.

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

如何使用,视图。 py

@method_decorator(auth0_login_required, name='dispatch')
class Dashboard(View):
    ...

对于我刚刚删除的修复程序, wrap .__ name__ =函数。__name __ ,但是我不确定它是否会破坏其他东西。

For the fix I just removed wrap.__name__ = function.__name__, but I'm not sure if it'll break something else.

有人可以解释吗?

推荐答案

使用 @ functools.wraps()装饰器处理您:

Rather than manually copy things across, use the @functools.wraps() decorator to handle this for you:

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()函数知道如何正确处理 functools.partial 对象(或者说,它可以处理 functools.partial 对象没有<$的事实c $ c> __ name __ 属性)。

The @wraps() decorator (via the functools.update_wrapper() function it calls knows how to handle functools.partial objects correctly (or rather, it can handle the fact that functools.partial objects have no __name__ attribute).

是f这表明在 View 类上找到的包装后的 functools.partial()对象没有 __ name __ 属性,那是不好的,因为即使您正在修饰确实具有该属性的函数,也就根本不复制该属性。如果您不想使用 @wraps(),则必须手动复制属性并自己处理异常:

It's fine that the wrapped functools.partial() object found on the View class doesn't have a __name__ attribute, what's not fine is that you then don't copy that attribute at all even when you are decorating functions that do have the attribute. If you don't want to use @wraps() you'd have to manually copy the attribute across and handle the exception yourself:

try:
    wrap.__name__ = function.__name__
except AttributeError:
    pass
try:
    wrap.__doc__ = function.__doc__
except AttributeError:
    pass

考虑到这不会复制 __ qualname __ __ module __ __ annotations __ 属性不处理在函数(其他装饰器可能会依赖)上设置的任何自定义属性。 @ functools.wraps()确实会处理所有这些问题,另外还会在装饰器包装器上设置 __ wrapped __ 属性可以让您再次打开装饰器的功能

but take into account that this doesn't copy the __qualname__, __module__ and __annotations__ attributes, doesn't handle any custom attributes set on function (which other decorators might rely on). @functools.wraps() does take care of all of those, plus it sets the __wrapped__ attribute on the decorator wrapper function that would let you unwrap the decorator again.

这篇关于Django 2.1-'functools.partial'对象没有属性'__name__'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆