就我个人而言,我是装饰器的忠实粉丝,装饰器是一种非 Django 特有的 Python 功能。装饰器是高阶函数之上的完美语法糖,它们对于减少视图中的样板特别有用——您可以快速定义一个通用的包装器函数,您可以在其中放置重复的代码以便于重用和方便-停止重构。
向您展示可能比解释它们的工作原理更容易。这是一个简化的视图示例:
def listpage(request):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
def itemlist_tags(request, tags):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
...但是你说你想让这些页面要求用户登录。你可以像这样添加登录代码:
def listpage(request):
if not request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
def itemlist_tags(request, tags):
if not request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
...它开始变得明显更大和重复,即使是一个人为的例子。你可以用装饰器让你的函数再次变得苗条,就像这样:
从装饰器导入装饰器
@decorator
def loginrequired(f, request, *args, **kwargs):
if request.user.is_authenticated():
return f(request, *args, **kwargs)
else:
return HttpResponseRedirect("/")
@loginrequired
def listpage(request):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.filter(visible=True).order_by("-modifydate")
}))
@loginrequired
def itemlist_tags(request, tags):
return HttpResponse(render_to_string("itemlist.html", {
"items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
}))
@loginrequired
def another_such_function(request):
(...)
@loginrequired
def and_again(request):
(...)
装饰器函数在函数定义时执行。在我的示例中,“f”是一个对象,表示应用了装饰器的函数,您可以以无休止的方式对其进行操作。
这需要decorator library,它在 PyPI 上是免费的,你会发现许多好的 python 小点心。
您不需要 this 库来编写装饰器函数,但它很有帮助,尤其是在开始时。他们可以做更多的事情——任何可调用对象都可以是装饰器;您可以装饰类方法并拦截self 变量;装饰器可以链接起来,如下所示:
@second
@first
def originalfunction(*args):
(...)
如果这个想法能激起你的兴趣,我将把对如此简单的高阶函数操作可以做什么的探索留给你。对于您或任何其他好奇的新 python 爱好者,我还有更多示例。祝你好运。