2016-03-28 13 views
3

と発送方法は、私は3つの引数に取るメソッドを記述する必要があります。stringのpython:文字列入力

  1. をその関数の引数のlist注文機能
  2. の名前で。これがデフォルト値と*varargsと引数を含むが、任意の追加のキーワード引数を表す**kwargs
  3. dictが含まれていない、またはNoneどれ

がない場合、私は、関数とコールを取得するために、この入力を使用する必要がありますそれ。たとえば、次のように

def dispatch(name, args, kwargs=None): 
    do_magic_here(name, args, kwargs) 

def meth1(): 
    print "meth1" 

def meth2(a, b): 
    print "meth2: %s %s" % (a, b) 

def meth3(a, **kwargs): 
    print "meth3: " + a 
    for k,v in kwargs.iteritems(): 
     print "%s: %s" % (k,v) 

そして、私はこのようなものを呼び出すことができるようにする必要があります。

>>> dispatch("meth1", []) 
meth1 
>>> dispatch("meth2", [1, 3]) 
meth2: 1 3 
>>> dispatch("meth3", [1], {"hello":2, "there":3}) 
meth3: 1 
hello: 2 
there: 3 

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

def do_magic_here(name, args, kwargs=None): 
    if name=="meth1": 
     meth1() 
    if name=="meth2": 
     meth2(args[0], args[1]) 
    if name=="meth3": 
     meth3(args[0], **kwargs) 

しかし、私は40のように派遣しようとしているがメソッドが増え、その数が増える可能性があるので、もっとプログラム的なやり方があると思っています。私はgetattrと何かを見ているが、私はそれを理解できない。

答えて

4

私はちょうどあなたがより自然にかつ透過的に通過argskwargsを通過させる

func_name_dict = {'meth1':meth1, 
        'meth2':meth2, 
        ...} 

def dispatch(name, *args, **kwargs): 
    func_name_dict[name](*args, **kwargs) 

を使用します。

>>> dispatch("meth2", 1, 3) 
meth2: 1 3 

あなたはもちろんのdictの代わりにglobals()またはlocals()を使用することができますが、あなたはあなたがそれぞれの名前空間で関数やメソッドがない場合は、発信者

+0

'dispatch'は' * args'や '** kwargs'を取るのではなく、実際のリストと辞書を使用しています。違いがありますか?私が働いているフレームワークのために、この方法で定義する必要があります – ewok

+0

本当にリストとディクテーションを通らなければならない限り、私はこのようにします。未知の引数をPythonで渡すより自然な方法です(デコレータ、メソッドのオーバーライドなど) – DaveBensonPhillips

+0

@ewok '*'でリストを解凍しても、 '**'でディクテーションすることができます。もしあなたが 'dispatch(* args、** kwargs)'を使うことができるならば、 – schwobaseggl

1

実際にはgetattrが届きます。

class X: 
    def a(self): 
     print('a called') 
    def b(self, arg): 
     print('b called with ' + arg) 

x = X() 
getattr(x, 'a')() 
# a called 
getattr(x, 'b')('foo') 
# b called with foo 

getattrがメソッドを処理し、同じようにフィールドと同じように、あなたはlocals()globals()を参照することで、クラスに関連付けられていない 関数と変数を扱うことができます。

あなたがグローバルスコープ内の関数を参照したい場合:たとえば

globals()['meth'](args) 

def dispatch(name, *args, **kwargs): 
    globals()[name](*args, **kwargs) 

dispatch('meth3', 'hello', foo='bar') 
# meth3: hello 
# foo: bar 

あなたは常に引数またはキーワード引数の辞書のリストを渡すことができますPythonで覚えておいてください**を使用して:

dispatch('meth3', *['hello'], **{'foo':'bar'}) 

本当に引数をリスト/ dispatchへのdict:

def dispatch(name, args, kwargs): 
    globals()[name](*args, **kwargs) 

dispatch('meth3', ['hello'], {'foo': 'bar'}) 
+1

何に公開したくないかについて注意する必要がある場合がありますクラスで? – Bahrom

+1

それは*メソッド*ではなく*関数*ではありません。私は答えを更新します。 – szym

+0

ああ、はい、良い点。 – Bahrom

関連する問題