2011-11-15 16 views
22

インスタンスメンバのデフォルトの引数値をメソッドに渡すには?

インスタンスの属性の値を使用してインスタンスメソッドにデフォルトの引数を渡したい:

class C: 
    def __init__(self, format): 
     self.format = format 

    def process(self, formatting=self.format): 
     print(formatting) 

これを試してみると、次のエラーメッセージが表示される:

NameError: name 'self' is not defined 

メソッドは次のように動作します:

C("abc").process()  # prints "abc" 
C("abc").process("xyz") # prints "xyz" 

ここで問題は何ですか、これはなぜ機能しませんか?そして、どうすればこの仕事をすることができますか?

+0

は、pythonの組み込み関数であるため、変数名としてformatを使用しません。 – Yajushi

+0

'プロセスメソッド 'で' self'の誤りを編集する –

答えて

31

デフォルト値は、インスタンスが存在する前のメソッドが定義されたときに評価されるため、実際にはこれをデフォルト値として定義することはできません。 formattingNoneある場合

class C: 
    def __init__(self, format): 
     self.format = format 

    def process(self, formatting=None): 
     formatting = formatting if formatting is not None else self.format 
     print(formatting) 

self.formatにのみ使用されます。簡単な回避策は、このような何かを行うことです。

def mk_default(): 
    print("mk_default has been called!") 

def myfun(foo=mk_default()): 
    print("myfun has been called.") 

print("about to test functions") 
myfun("testing") 
myfun("testing again") 

そして、ここで出力:


は、デフォルト値がどのように動作するかのポイントを証明するために、この例を参照してください

mk_default has been called! 
about to test functions 
myfun has been called. 
myfun has been called. 

mk_defaultは一度だけ呼び出され、そのたかお知らせ関数が呼び出される前に起こった!

+0

'foo = mk_default()'と呼ばれる関数が呼び出される前に 'mk_default'が呼び出されたと思います。 'foo = mk_default'であってはいけませんか?次に、あなたの例が 'myfun(" testing ")'に続いて 'myfun()'に変わるかもしれません。 – gary

+0

これは引き続き推奨される回避策ですか? – confused00

+2

'formatting = formattingまたはself.format'は' formatting'が '0 'のような偽の値である場合' self.format'に 'formatting'を設定することに注意してください。より安全な方法は 'formatting = formatting is not else self.format'または同等のものではない場合は' formatting = formatting 'と打つことです。 – Godsmith

6

Pythonでは、selfの名前はではなく、の名前です。これはパラメータ名の慣例なので、__init__にはselfというパラメータがあります。 (実際には、__init__はどちらかの非常に特別なものではありません、特にそれが実際にオブジェクトを作成できませんん...それは長い話だ)

C("abc").process()Cインスタンスを作成し、Cクラスでprocess方法を調べ、最初のパラメータとしてCインスタンスを使用してそのメソッドを呼び出します。したがって、それを指定した場合はselfパラメータになります。

でも、selfはデフォルト値を設定した時点ではないため、このパラメータを持っていてもdef process(self, formatting = self.formatting)のようなものを書くことはできません。 Pythonでは、関数のコンパイル時にパラメータのデフォルト値が計算され、関数には「スタック」されます。 (同じ理由で、[]のようなデフォルトを使用する場合、そのリストは関数呼び出しの変更を覚えています)。

どうすればこの作品を作成できますか?

伝統的な方法は、デフォルトとしてNoneを使用してその値をチェックし、機能内で置き換えることです。Noneではなく、呼び出すコードが同じインスタンスを使用しないように非表示にしておくと、目的に合わせて特別な値を設定するほうが少し安全です(objectインスタンスは必要なものだけです)。どちらの方法でも、ではなく、==でこの値を確認する必要があります。

+0

[なし]を使用している場合、回避策が目的の出力を満たしていません。 –

+0

'None'が' formatting'のための有効な値ならば、私は説明したように他のものを選ぶ必要があります。 –

1

静的でないメソッドとして動作するようにするには、「self」をクラス関数の最初の引数として渡す必要があります。

オブジェクト自体を指します。最初の引数として位置が固定されているので、デフォルトの引数として "self"を渡すことはできません。

代わりに "書式= self.format" 使用 "の書式=なし" のあなたのケースで

、次いで、以下のようにコードの値に割り当てる:

[EDIT]

class c: 
     def __init__(self, cformat): 
      self.cformat = cformat 

     def process(self, formatting=None): 
      print "Formating---",formatting 
      if formatting == None: 
       formatting = self.cformat 
       print formatting 
       return formatting 
      else: 
       print formatting 
       return formatting 

c("abc").process()   # prints "abc" 
c("abc").process("xyz")  # prints "xyz" 

注:使いません変数名としての "format"は、Pythonの組み込み関数であるため、

+0

さて、「自己」問題を修正しました。しかし、あなたの答えは希望の出力を満たしていません。 –

+0

編集したブロックをチェックすると、それが役に立ちます。 – Yajushi

関連する問題