2011-09-20 4 views
8

this documentスレッドの安全性について読んだ後で、ドキュメントに何かがないか、それを読んだり、推論していると感じました。 テンプレートタグを使用したスレッドセーフティ

は、簡単な例を挙げてみましょう:私は hello_worldタグが使用されるたびに HelloWorldNodeクラスの新しいインスタンスを構築するために、このコードを理解

class HelloWorldNode(template.Node): 
    def render(self, context): 
     return "O HAI LOL" 

@register.tag(name="hello_world") 
def hello_world(parser, tokens): 
    """ 
    Greets the world with wide-eyed awe. 
    """ 
    return HelloWorldNode() 

hello_worldが実行されたとき

class HelloWorldNode(template.Node): 
    def __init__(self, message): 
     self.message = message 

    def render(self, context): 
     return "O HAI LOL " + message 

@register.tag(name="hello_world") 
def hello_world(parser, tokens): 
    """ 
    Greets the world with wide-eyed awe. 
    """ 

    message = tokens.split_contents()[1] 

    return HelloWorldNode(message) 

はこのように、HelloWorldNodeの新しいインスタンスが作成され、インスタンス辞書には、属性messageがあります。他の例としては、このように、コンストラクタに引数を渡すことを含みます。このインスタンスは、タグの指定されたインスタンスのみをレンダリングする場合にのみ使用する必要があります。他のレンダリングに使用すると、バインドされたデータが正しくない可能性があります。これが当てはまらない場合、タグのさまざまな使用の間で議論が混ざり合ってしまうでしょう。ドキュメントからの他の例を見てみると

は、ここhereからの簡単な例です:

def do_current_time(parser, token): 
    tag_name, format_string = token.split_contents() 
    return CurrentTimeNode(format_string[1:-1]) 

これは、関数に渡されたトークンからデータを取ると、CurrentTimeNodeが働くことができる唯一の方法は、新しいものですdo_current_timeが呼び出されるたびにインスタンス化されます。

ドキュメントのページに戻って、不協和音が設定されています。これは「悪い」です。

class CycleNode(Node): 
    def __init__(self, cyclevars): 
     self.cycle_iter = itertools.cycle(cyclevars) 
    def render(self, context): 
     return self.cycle_iter.next() 

ドキュメントは、彼らの両方が同じノードを使用する場合、同じタグを使用して2つのページは、その後、競合状態を経験するかもしれないと述べています。 2つのテンプレートのレンダリングが、それぞれ独立してインスタンス化すると、同じインスタンスを共有する方法を理解できません。

これを解決する方法は、ドキュメントは、このようなものですと言う:

class CycleNode(Node): 
    def __init__(self, cyclevars): 
     self.cyclevars = cyclevars 
    def render(self, context): 
     if self not in context.render_context: 
      context.render_context[self] = itertools.cycle(self.cyclevars) 
     cycle_iter = context.render_context[self] 
     return cycle_iter.next() 

これはselfとインデックスcontext.render_contextに表示されます。システム全体で

  1. self参照クラスの特定のインスタンスを唯一のクラス、および順に
  2. self参照:その含意は、selfは、次のいずれかの方法でインスタンスを識別するために使用されていることでなければなりませんインスタンスを参照するにはレンダリングコンテキストが必要です

1が真であれば、データをselfに関連付けるだけではどうですか?

2がtrueで、レンダリングコンテキストが「現在レンダリング中のテンプレートのコンテキストに関連付けられている」場合、同じページの2つのテンプレートタグのインスタンスを区別することはできますか?

タグは、呼び出されるたびに個別にインスタンス化されますか?もしそうなら、並行処理の問題はなぜですか?そうでない場合は、どうしてですか?

答えて

0

thisの近くに読んでください。

テンプレートは読み込まれるとコンパイルされます。タグ関数に渡される引数はすべて 'static'です。リテラル文字列か、レンダリングコンテキストでバインドされた変数を参照するための識別子として使用される文字列です。

したがって、Nodeオブジェクトは各タグごとにインスタンス化され、テンプレートが使用されるたびに使用可能な状態でハングします(もちろん、テンプレートは任意の数のスレッドで使用できます)。

私の質問でselfは、テンプレート内の特定のノードのアイデンティティです。レンダリングコンテキストと組み合わせると、インスタンス変数をハングアップする一意のIDが与えられます。

関連する問題