我的代码行为怪异,我不明白为什么。你知道吗
代码如下:
from django.urls import path
app_name = 'portal'
urlpatterns = []
def route(url, name=""):
def dec(f):
f_name = name or f.__name__
urlpatterns.append(
path(url, f, name=f_name)
)
return f
return dec
from . import views
# 2) The decorator call in the other file
from . import urls
@urls.route("/my_function")
def my_function():
print("Hello world")
我在name
上得到一个UnboundLocalError
File "urls.py", line 10, in dec
if name == "":
UnboundLocalError: local variable 'name' referenced before assignment
name
应该默认设置为""
,我不知道问题出在哪里。
奇怪的是,如果我运行相同的代码并将decorator更改为:
urlpatterns = []
def route(url, name=""):
def dec(f):
if name == "":
print("I work!")
urlpatterns.append(
path(url, f, name=name)
)
return f
return dec
它工作正常,输出:
I work !
而问题应该来自于if name == ""
PS:我在django上编程,这行在urls.py
文件中。你知道吗
答案就在你没贴的那部分。你真正的代码看起来像
赋值给
name
使其成为局部变量-Python没有变量声明,因此它是定义其作用域的名称绑定位置。在您的例子中,在dec
中指定给name会使名称“name”成为dec
的本地名称,因此不会在封闭作用域中查找它。由于在赋值之前对它进行测试(“reference”),所以会出现非常明显的错误(不,只是开玩笑)“localvariable'name'referenced before assignment”。你知道吗这里的解决方案是在
dec
函数的顶部将name
声明为“非本地”,这样Python就知道必须在封闭范围内(或者更确切地说,在捕获dec
函数环境的闭包单元格中)查找它:请注意,这只适用于Python3-如果使用Python2,则必须借助黑客来模拟此行为:
这里的黑客建议您对其进行变异而不是重新绑定,因此Python不会将其标记为局部变量。你知道吗
作为补充,我不建议尝试移植这个
@route(url)
习惯用法(有人吗?)去Django。首先是因为将视图定义与url映射分离是一个经过深思熟虑的设计决策,它允许将第三部分apps url重新映射到我们想要的任何东西,而无需黑客或叉子等,而且还因为大多数Django开发人员希望url在urls.py
模块中被明确定义,并且会因为您不遵守约定而憎恨您。现在你当然可以随心所欲地写你的项目了,但是遵循惯例对每个人来说都很容易。我的2美分。。。相关问题 更多 >
编程相关推荐