python - 了解 Django 中的装饰器
问题描述
我目前正在尝试为基于函数的视图构建自己的装饰器。
我了解装饰器背后的基本概念,但我仍在努力完全理解“幕后”发生的事情。
我有这个示例装饰器。有人可以解释一下这里发生了什么或它是如何工作的吗?为什么我们需要这么多函数呢?
def active_user_required():
def decorator(function):
def wrapper(request, *args, **kw):
if request.user.is_active:
return function(request, *args, **kw)
else:
raise PermissionDenied()
return wrapper
return decorator
解决方案
理解 Python 中的装饰器的关键归结为:Python 中的函数是一等对象。这意味着它们可以作为参数传递并作为值返回(除其他外)。
在最简单的形式中,装饰器将函数作为参数并返回一个扩展其功能的新函数。例如,这是一个plusone
将原始函数的返回值加 1 的装饰器:
>>> def plusone(f):
... def wraps(*a):
... return f(*a) + 1
... return wraps
...
>>>
>>> @plusone
... def add(x, y):
... return x + y
...
>>>
>>> add(1, 2)
4
重申一下,重要的一点plusone
不是它“加 1”,而是它创建了一个新函数(在这种情况下调用)wraps
并返回. 在最后一行,当add(1, 2)
被调用时,它实际上wraps
是被调用的函数(回想一下,调用你的原始add
函数)。你可以证明它:
>>> add
<function wraps at 0x107b88578>
(如果没有装饰器,那就是说<function add at 0x...>
)
这可以扩展到更复杂的情况,例如带有自己参数的装饰器,但我不认为这些细节是你问题的根源。关键的一点是装饰器将一个函数作为参数,然后返回一个函数(并且返回的函数几乎总是以某种方式扩展传递的函数)。
希望有帮助。
推荐阅读
- serialization - 嵌套序列化程序的创建方法中的非空约束失败
- flutter - 当路由到另一个页面时,我得到“有多个英雄在子树中共享相同的标签”
- elasticsearch - 无法访问 Kibana 站点
- flutter - Flutter - 如何在 Dart 中使用 HTTP 发送 POST 请求?
- python - 如果是元组,我有一个列表。如何将其转换为表格格式?
- python - 使用熊猫在新列中获取满足多个条件的列的索引
- python - pip install trains 失败
- java - 组件树为空,无法添加任何组件
- java - kotlin(jvm,js)中的多维稀疏数组?
- python - 以相同的结构抓取多个页面