27

getattrを使用して、変数に応じてさまざまな関数を呼び出しています。

私はそのようなことをしています:

getattr(foo, bar) ()

それは機能し、foo.bar()のような関数を呼び出します

私の問題は、「bar」関数があり、それを異なるパラメーターで呼び出したいということです。例えば:

def f1() :
  pass

def f2(param1) :
  pass

def f3(param1,param2) :
  pass

したがって、「bar」はf1、f2、またはf3になります。

私はこれを試しました:paramsが「bar」関数に必要なすべてのパラメータを含むリストであると仮定します

getattr(foo, bar) (for p in params :)

params変数の長さを監視する必要がない「クリーンな」ソリューションを監視しています

4

3 に答える 3

36

次のようなことを試すことができます:

getattr(foo, bar)(*params)

これparamsは、がリストまたはタプルの場合に機能します。からの要素paramsは次の順序で解凍されます。

params=(1, 2)
foo(*params)

と同等です:

params=(1, 2)
foo(params[0], params[1])

キーワード引数がある場合は、それも実行できます。

getattr(foo, bar)(*params, **keyword_params)

keyword_params辞書はどこにありますか。

また、この回答は実際にはとは無関係ですgetattr。それはどんな関数/メソッドでも機能します。

于 2012-08-02T15:53:47.650 に答える
5

これはPython3では非常に簡単です。例を次に示します。

class C:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def m(self, x):
        print(f"{self.name} called with param '{x}'")
        return

ci = C("Joe", 10)
print(C)
print(ci)
print(C.m)
print(ci.m)
print(getattr(ci,'m'))
getattr(ci,'m')('arg')

<class '__main__.C'>
<__main__.C object at 0x000001AF4025FF28>
<function C.m at 0x000001AF40272598>
<bound method C.m of <__main__.C object at 0x000001AF4025FF28>>
<bound method C.m of <__main__.C object at 0x000001AF4025FF28>>
Joe called with param 'arg'

getattrは組み込みモジュールからのものであり、この場合、クラスインスタンスciと関数の名前を表す文字列の2つのパラメーターを受け取ることに注意してください。

パラメータのデフォルト値を定義することもできます。

def m(self, x=None):
    print(f"{self.name} caled with param '{x}'")
    return

その場合、私たちは次のように呼ぶかもしれません:

getattr(ci,'m')()
于 2019-05-24T14:16:16.970 に答える
1

おそらくもっと読みやすい方法で、例外の処理に適しています。

class foo:
    def method_xy(self, *args, **kwargs):
        print(f'args:{args}, kwargs:{kwargs}')


bar = 'method_xy'
xi = foo()
try:
    func_name = getattr(xi, bar)
except AttributeError:
    # handle missing method
    pass

args = ['bla1', 'bla2']
kwargs = {'a1': 1, 'a2': 2}

try:
    result = func_name(*args, **kwargs)
except TypeError:
    # handle Problems with arguments
    pass
于 2020-01-22T15:53:16.573 に答える