4

Djangoでかなり重いビュー関数をリファクタリングしようとしています。浮かんでいる変数が多すぎて、それは巨大な関数です。

理想的には、ビューを論理関数にモジュール化したいです。ただし、変数に簡単にアクセスするには、関数コンテキストを渡す必要があります。

例えば:

def complex_view(request, slug):
    some complex logic which creates variable abc ...
    ...
    some more complex logic which uses variable abc ...
    ...
    etc.

次のようになるはずです:

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

def process_X():
    ...

def process Y():
    ...

これを行うにはいくつかの方法が考えられますが、そのうちのいくつかはこのページで指摘されています:http: //mail.python.org/pipermail/tutor/2009-February/067506.html

a。マスタービューで定義されたサブ関数。どの変数が共有され、どの変数が共有されていないかを判断するのは難しいため、これは厄介なようです。

b。locals()辞書として渡す。変数にアクセスする方法が2つあるため、これも厄介です。xyzcontextDict['xyz']。そして、 1つを呼び出しNで使用し、次をN+1スタックで使用する必要があります。

c。ブルートフォースは、すべての変数を各関数呼び出しに渡し、関連する変数を返します。多くの変数が関係している場合、これは非常に面倒になります。

d。C ++ / C#では、クラスを作成し、MyComplexViewContextすべての共有変数を定義し、作業を実行するためのメンバー関数を作成するだけです。self.xyzその後、そのクラス内のすべてに使用できます。このメソッドはPythonでも使用できると思います。ただし、これが最善の方法かどうかはわかりません。

Python / Djangoでこれを行うための好ましい方法についてどう思いますか?

4

2 に答える 2

10

(d) が好き - クラスを作成し、メンバー関数を使用して作業を行います。

Django では、ビューは、HTTPRequest オブジェクトと、URL ルーティングが渡すその他のパラメーターを受け入れる単なる「呼び出し可能」です。

__call__Python クラスは、次のようにメソッドを定義すると、関数と同じように呼び出すことができます。

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

    def helper_method(self):
        # etc.

次に、ファイル内でクラスに名前を付けることができ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

urls.py では、(クラスではなく) オブジェクトを参照します。オブジェクトは、関数のように呼び出すこともできます。

他のトリックは、継承を使用して同様のビューを定義するか、基本クラスのいくつかの同様のビューにいくつかの一般的な機能を提供し、そこから特化したビュー クラスを継承することです。

詳細については、Simon Willison によるこのスライドショーを参照してください。具体的な例については、このスニペットを参照してください。

于 2010-01-11T21:18:18.380 に答える
0

次のように、d) に似たものを使用することをお勧めします。

class ComplexView_SharedVariables:
  # Shared variables (to be used as instance variables, not class variables!)
  a = "somevalue"
  b = ...
  c = ...

class ComplexView_Methods1:
  ... some functionality ...

class ComplexView_Methods2:
  ... some more functionality ...

class ComplexView_All(ComplexView_SharedVariables, ComplexView_Methods1, ComplexView_Methods2):
  # This class puts together all functionality and shared variables
  pass

この手順を使用すると、クラスを別のファイルに分割することもできます (Django で可能であれば、私はその経験がありません)。

于 2010-01-11T21:20:12.710 に答える