开发者

How does this strange python decorator work

I was looking through the source for the pyFacebook library and found the following code:

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

I have tried to skip irrelelvant code, hence the ellipsis in the middle. The full listing can be found at https://github.com/sciyoshi/pyfacebook/blob/master/facebook/djangofb/__init__.py

M开发者_如何学Cy confusion stems from the reference on the fourth line to the 'next' attribute of the nested function. I can't figure out what the value of newview.next should be, whenever I try similar experiments myself I get 'function has no attribute internal' errors. However, the code works as I am using it in a django project without problems. Would be very happy if someone could explain to me what is happening here.


In Python a variable defined inside a function is not the same as defined outside as a property of a function.

The following example will probably help:

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

print A().a
print A.a

UPD: The object newview is in the scope inside the function is due to the definition just after the function:

newview.next = next

Remember, in Python functions are also objects and can also have attributes!

Here is a more helpfull example:

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

There is no magic here: b() does not know it's name. It just sees a variable b in it's scope that points to itself. It could be some variable d defined by

d = b
d.x = 1
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜