2011-08-16 5 views
1

私は、メソッドで宣言されたPythonの変数がその外部では見えないことを知っています。しかし、彼らのライフサイクルは何ですか?そのメソッドが呼び出されるたびに、メソッドの中で宣言された変数が作成されると思います。pythonのメソッド変数とメソッドで作成されたオブジェクト

私は次のような状況のため質問しています。私は以下のような方法を持っています(これはチェリーピーと関連していますが、おそらく関連性はありませんが、何らかの影響を受けるチャンスのために追加します)。

まず私が使用しているカスタムフィルタークラス:

class Filter(): 
""" 
Class used to filter tables displayed in UI, based on few criteria. 
Initialize filter with a list of fields, and correspondinf values. 
""" 
def __init__(self, display_name= "", fields= [], values= [], operations= []): 
    self.display_name = display_name 
    self.fields = fields 
    self.values = values 
    self.selected = False 
    self.operations = operations 

を今私は基本的に私は、パラメータとして受け取ったフィルタ値を追加する程度

@cherrypy.expose 
@logged() 
def getfiltereddatatypes(self, name, filters, datatype): 
    ...some mumbo jumbo... 

    default_filter = self._get_default_filters(inputTree, name) 

    #default_filter here can be a object of type Filter if defined or None otherwise 

    print "RECIEVED " + str(filters) 
    if default_filter is not None: 
     print "CREATING NEW" 
     new_filter = copy.deepcopy(default_filter) 
    else: 
     print "CREATING NEW" 
     new_filter = Filter() 
    [new_filter.fields.append(value) for value in filters['fields']] 
    [new_filter.operations.append(value) for value in filters['operations']] 
    [new_filter.values.append(value) for value in filters['values']] 
    print "LENGTH =" + str(len(new_filter.fields)) 

    ...Some other mumbo jumbo.... 

を話している方法をfiltersをdefault_onesに変更します。しかし、私はメソッドが呼び出されるたびにこれを実行したい、またはそれをよりよく説明するために、私は自分の問題を示すためにプリントを作った。だから、最初のメソッド呼び出し時:

RECIEVED {'operations': ['!='], 'fields': ['model.DataType.subject'], 'values': ['w']} 
    CREATING NEW 
    LENGTH =1 

予想ように、新しいフィルターオブジェクトが作成され、受け取ったパラメータからの操作、フィールド、および値が加算され、長さ(フィールド)= 1しかし、私の第二のパス:

RECIEVED {'operations': ['!='], 'fields': ['model.DataType.subject'], 'values': ['']} 
    CREATING NEW 
    LENGTH =2 

ここではこの動作を説明できません。ご覧のように、ifの新しいbrachを再度呼び出すと、filters変数に1つの項目リストが保持されますが、結果の長さは2になります。何度も何度も実行すると、常に増分されます。 new_filter = Filter()呼び出しが前のメソッド呼び出しからnew_filterを返すようなものです。このような行動の原因は何ですか?私はnew_filter = copy.deepcopy(Filter())を解決するかもしれないが、なぜ私はそれをやらなければならないのでしょうか?

よろしく、 ボグダン

+1

、それは外側の文脈で行わなければなりません。 – agf

答えて

5
def __init__(self, display_name= "", fields= [], values= [], operations= []) 

リストは一度だけ作成されます。したがって、それらを変更すると、次の呼び出しには変更されたリストがあります。この動作を望まない場合は、単にデフォルト値としてNone使用し、このような何かを追加します。

if fields is None: 
    fields = [] 
self.fields = fields 

別の解決策は関係なく、渡されたものを、新しいリストを作成しないであろう。

self.fields = list(fields) 

がありますまた、リスト内包のあなたの乱用がいいところでhttp://effbot.org/zone/default-values.htm


でこの動作に関する詳細な記事ではありません。

[new_filter.fields.append(value) for value in filters['fields']] 

方法では発生しません `def`ライン上で何が起こる
new_filter.fields += filters['fields'] 
+6

か、おそらくnew_filter.fields.extend(filters ['fields'])が可能な型の範囲を拡張します。 '+ ='では、リストを他のリストに追加することしかできませんが、 'extend()'では任意のシーケンス型を使用することができます。 – glglgl

+0

入力いただきありがとうございます、私の問題を修正しました。 – Bogdan

関連する問題