Skip to main content
 首页 » 编程设计

python之这个奇怪的 python 装饰器是如何工作的

2025年05月04日8Free-Thinker

我正在查看 pyFacebook 库的源代码并找到以下代码:

def require_login(next=None, internal=None, required_permissions=None): 
    def decorator(view): 
        def newview(request, *args, **kwargs): 
            next = newview.next 
            internal = newview.internal 
 
            try: 
                fb = request.facebook 
            except: 
                raise ImproperlyConfigured('Make sure you have the Facebook middleware installed.') 
 
            if internal is None: 
                internal = request.facebook.internal 
 
...            
 
            return view(request, *args, **kwargs) 
        newview.next = next 
        newview.internal = internal 
        return newview 
    return decorator 

我试图跳过不相关的代码,因此中间有省略号。完整 list 可在 https://github.com/sciyoshi/pyfacebook/blob/master/facebook/djangofb/__init__.py 找到

我的困惑源于第四行对嵌套函数的“next”属性的引用。我不知道 newview.next 的值应该是多少,每当我自己尝试类似的实验时,我都会收到“函数没有内部属性”错误。但是,代码可以正常工作,因为我在 django 项目中使用它没有问题。如果有人能向我解释这里发生了什么,我会很高兴。

请您参考如下方法:

在 Python 中,函数内部定义的变量与外部定义的函数属性不同。

以下示例可能会有所帮助:

cass A: 
  a = 1 
  def `__init__`(self): 
    self.a = 2 
 
print A().a 
print A.a 

更新: 对象 newview 在函数内部的范围内是由于函数之后的定义:

newview.next = next 

请记住,在 Python 中,函数也是对象,也可以具有属性!

这是一个更有帮助的例子:

def b(): 
  x=b.x 
  print x 
 
b() 
> Traceback (most recent call last): 
>   File "<stdin>", line 1, in <module> 
>   File "<stdin>", line 2, in b 
>   AttributeError: 'function' object has no attribute 'x' 
b.x = 1 
b() 
> 1 

这里没有魔法:b() 不知道它的名字。它只是在其范围内看到一个指向自身的变量 b 。它可以是 d 定义的一些变量

d = b 
d.x = 1