Pythonize Me:如何在Python中管理调用者上下文变量?(Python的/ Django的)

vau*_*och 4 python django django-context

我正在尝试在Django中重构一个相当重要的视图函数.浮动的变量太多了,这是一个巨大的功能.

理想情况下,我想将视图模块化为逻辑函数.但是,我必须传递函数上下文以便轻松访问变量.

例如:

def complex_view(request, slug):
    some complex logic which creates variable abc ...
    ...
    some more complex logic which uses variable abc ...
    ...
    etc.
Run Code Online (Sandbox Code Playgroud)

应该变得像:

def complex_view(request, slug):
    process_X()
    ...somehow pass variables and context to next function...
    process_Y()
    ... 
    etc.

def process_X():
    ...

def process Y():
    ...
Run Code Online (Sandbox Code Playgroud)

我可以想到几种方法来实现这一点,其中一些方法在本页中有所指出:http: //mail.python.org/pipermail/tutor/2009-February/067506.html

一个.主视图中定义的子功能.这看起来很糟糕,因为很难分辨哪些变量是共享的,哪些不是.

传递locals()中作为字典.这也是kludgey,因为现在有两种不同的方式来访问变量:xyzcontextDict['xyz'].你必须在呼叫中使用一个N,并N+1在堆栈中调用下一个.

C.暴力将所有变量传递给每个函数调用并返回相关的变量.当涉及到很多变量时,这变得非常乏味.

d.在C++/C#中,我只需创建一个类MyComplexViewContext,定义所有共享变量,并创建成员函数来执行工作.然后你可以使用self.xyz该类中的所有内容.我想我也可以在Python中使用这个方法.不知道这是不是最好的方法.

你对Python/Django中首选的方法有什么看法?

Ian*_*and 10

我喜欢(d) - 为它创建一个类,并使用成员函数来完成工作.

在Django中,视图只是一个"可调用",它接受HTTPRequest对象,以及URL路由传递给它的其他参数.

Python类可以像函数一样调用,如果你__call__在它们上定义一个方法,就像这样:

class MyView(object):
    def __call__(self, request, slug)
        # do stuff here

    def helper_method(self):
        # etc.
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的urls.py文件中命名该类,它将像任何其他python函数一样被调用.

这样做还可以将类似的视图转换为对象实例:

class MyView(object):
    def __init__(self, parameters):
        # initialize instance

    def __call__(self, request, slug):
        # main view code goes here

first_view = MyView("some parameter")
second_view = MyView("some other parameter") # creates second object instance
Run Code Online (Sandbox Code Playgroud)

在urls.py中,引用对象(而不是类) - 对象也可以像函数一样被调用.

其他技巧是使用继承来定义类似的视图,或者为基类中的许多类似视图提供一些通用功能,然后专用视图类继承.

您可以通过Simon Willison查看此幻灯片以获取更多详细信息,或者获取此片段的具体示例