60

重複の可能性:
インスタンスメソッドの結果としてのパラメーターのデフォルト値

Pythonで関数パラメータにデフォルト値を設定することは可能ですが:

def my_function(param_one='default')
    ...

現在のインスタンス(自己)にアクセスできないようです:

class MyClass(..):

    def my_function(self, param_one=self.one_of_the_vars):
        ...

私の質問:

  • これは、現在のインスタンスにアクセスして関数のデフォルトパラメータを設定できないということですか?
  • それが可能でない場合:理由は何ですか?これがPythonの将来のバージョンで可能になると想像できますか?
4

4 に答える 4

61

それは次のように書かれています:

def my_function(self, param_one=None): # Or custom sentinel if None is vaild
    if param_one is None:
        param_one = self.one_of_the_vars

そして、関数が開始するまで実際には存在しないという性質のため、Pythonでは決して起こらないと言っても差し支えないと思いますself...(他のすべてのように、それ自体の定義では参照できません)

例:できませんd = {'x': 3, 'y': d['x'] * 5}

于 2012-11-02T13:18:48.700 に答える
24

あなたが思っているよりもはるかに多くのものがあります。デフォルトは静的(= 1 つのオブジェクトを指す定数参照) であり、定義のどこかに格納されていると考えてください。メソッド定義時に評価されます。インスタンスではなく、クラスの一部として。それらは一定であるため、 に依存することはできませんself

ここに例があります。直感に反しますが、実際には完全に理にかなっています。

def add(item, s=[]):
    s.append(item)
    print len(s)

add(1)     # 1
add(1)     # 2
add(1, []) # 1
add(1, []) # 1
add(1)     # 3

これは印刷されます1 2 1 1 3

と同じように動作するため、

default_s=[]
def add(item, s=default_s):
    s.append(item)

明らかに、 を変更するdefault_sと、これらの変更が保持されます。

など、さまざまな回避策があります。

def add(item, s=None):
    if not s: s = []
    s.append(item)

またはこれを行うことができます:

def add(self, item, s=None):
    if not s: s = self.makeDefaultS()
    s.append(item)

その後、メソッドmakeDefaultSは にアクセスできますself

別のバリエーション:

import types
def add(item, s=lambda self:[]):
    if isinstance(s, types.FunctionType): s = s("example")
    s.append(item)

ここで、 のデフォルト値sファクトリー関数です。

これらすべての手法を組み合わせることができます。

class Foo:
    import types
    def add(self, item, s=Foo.defaultFactory):
        if isinstance(s, types.FunctionType): s = s(self)
        s.append(item)

    def defaultFactory(self):
        """ Can be overridden in a subclass, too!"""
        return []
于 2012-11-02T13:22:55.583 に答える
3

パラメータのデフォルト値は、「コンパイル」時に1回評価されます。したがって、明らかにアクセスできませんself。古典的な例はlistデフォルトのパラメータです。要素を追加すると、パラメータのデフォルト値が変更されます。

回避策は、別のデフォルトパラメータ(通常はNone、)を使用してから、変数を確認して更新することです。

于 2012-11-02T13:20:47.710 に答える
2

ここで行っている誤った仮定が複数あります。まず、関数はインスタンスではなくクラスに属しています。つまり、実際に関与する関数は、クラスの 2 つのインスタンスで同じです。第 2 に、デフォルト パラメータはコンパイル時に評価され、一定です (定数オブジェクト参照のように、パラメータが可変オブジェクトの場合は変更できます)。したがってself、デフォルトのパラメーターでアクセスすることはできません。

于 2012-11-02T13:24:07.937 に答える