Django变量处理-为什么起作用?

时间:2018-07-31 04:36:21

标签: python django python-3.x

我对django并不陌生,在我创建的views.py文件中遇到了使我困惑的事情。我只是玩了一下,想出了一些可行的方法,但我不知道为什么会这样。

Draft_Order类(我在另一个文件中)要求NBA stats页面,在后端执行一些计算,并分发选秀彩票赔率(对于新选秀)。这些方法可以初始化,模拟草稿并获得排行榜,这一切都在后端进行(非常有效)。

现在,我的问题是我不明白为什么我可以在所有函数之外创建DraftOrder类的实例“ f”,但是在我获得的大多数函数中仍然能够引用它是从我的urls.py文件中调用的,因此似乎它们根本不应该工作。另外,由于某种原因,如果我在函数中没有给f赋值,则更新函数只能引用“ f”,例如如果我添加行

f = temp 

突然间,它给了我一个“ unboundlocalerror”,并说f在赋值之前被引用。

在此方面,我将不胜感激。谢谢。

from django.shortcuts import render
from django.http.response import HttpResponse
from simulator.draft_simulator import Draft_Order
from simulator.models import Order

# Create your views here.
f = Draft_Order()
f.initialize()

def index(request):
    return HttpResponse('<p>Hello World</p>')

def init(request):
    return HttpResponse(f.initalodds.to_html())

def table(request):
    f.sim_draft()
    return HttpResponse(f.finaltable.to_html())

def update(request):
    temp = Draft_Order()
    temp.get_standings()
    if temp == f:
        return HttpResponse('Same!')
    else:
        return HttpResponse('updated!')

2 个答案:

答案 0 :(得分:1)

发生UnboundLocalError的原因是,在函数内部对f的赋值掩盖了整个函数的全局f。您需要明确声明f引用了全局变量:

def update(r):
    global f
    if f == ...
    f = Draft_Order()  # new draft order

但是,实际上,您不应该依赖于存储在RAM中的全局值,因为在生产环境中,您将拥有多个可能具有不同f的进程,并且您将无法控制其生命周期所述过程。最好在这里依赖永久性内存(数据库,键值存储,文件等)。

答案 1 :(得分:0)

您需要查看python namespaces and scope

但是这是我想避免发疯的方式(python中的所有对象都是对象)。

用简单的术语python来说,这些 .py 文件是模块,当python运行时,这些模块会转换为对象,因此您有一个 url 对象,一个视图对象等

因此,您在模块级别定义的任何变量都将变成属性,而定义的任何函数都将变成方法。

我相信您可以在 url.py

上执行类似的操作
from simulator import views

from simulator.views import update

这基本上意味着获取表示 views.py 文件的 views 对象。 在视图对象中,您可以访问 update 之类的方法。

您的 update 方法能够访问 f ,因为这是python namespaces and scope

的摘录
  

模块中定义的函数的全局范围是该模块的名称空间,无论调用该函数的位置或别名如何。

  1. 基本上,您的 f 视图对象的属性,这意味着 views 对象中的任何方法都可以访问它。

  2. 之所以在 urls.py 上运行时为什么起作用,是因为方法可以访问定义在其中的对象的属性,所以由于 update 方法是在内部定义的视图可以访问视图属性。

请在python namespaces and scope上阅读更多信息,这是一个非常简化的解释。