0

私はPythonにまったく慣れておらず、ユーザーがオプションの1つを選択すると動的に入力される文字列と変数の接続詞によって形成される名前を持つ、関数を呼び出す方法を探していました。

例:

ユーザーに特定のオプションを提供するメニューからプログラムを開始します(1、2、3、または4を選択)

ユーザーが1を選択した場合、変数xyzはタプルまたはリスト内の文字列で埋められます。

この文字列を変数に割り当てて、別のオプションを提供する別の関数を呼び出します。

オプション1を取得すると、コードは関数名(次に呼び出される名前)を形成する事前定義された文字列にxyz変数を追加します。

if int(option) == 1:
#prefixfunc will be that predefined string that will be the prefix for every function  #to be called
    exec('prefixfunc'+xyz'()')
    #or
    #eval('prefixfunc_'+xyz'()')
    #for example, we have xyz as abc, then it calls function prefixfunc_abc()

コードでは正常に機能します。また、ユーザーが別の入力を追加した場合の責任になるとは思いません。変数は、リストまたはタプルですでに定義されている文字列を使用して割り当てられるため。

私は自分自身を明確にしたと思います。

明確にするために:

def maint_car():
print('It Works!!! But did you come until here in a safe way?' )

def veh_func():
func=( "Maintenance", "Prices", "Back", "Quit" )
ord = 0

for i in func:
    ord += 1
    print(ord,'\b)', i)

picked = input('\nOption: ')

if int(picked) == 1:
    exec('maint_'+xyz+'()')




def startprog():

abcd =( "car", "bike", "airplane", "Quit" )
global xyz
ord = 0
for i in abcd:
    ord += 1
    print(ord,'\b)', i)

picked = input('\nVehicle:')

if int(picked) == 1:
    xyz = abcd[0]
    veh_func()

elif int(picked) == 2:
    xyz = abcd[1]
    veh_func()

elif int(picked) == 3:
    xyz = abcd[3]
    veh_func()

elif int(picked) == 4:
    print('\nBye.\n')

startprog()
4

3 に答える 3

8

このために、dict文字列名を関数にマップするを使用します。

def test():
 print "yay"

funcs = { "test": test }
funcs["test"]()

inこれにより、これを行うためのはるかに優れた方法が提供され、演算子を使用して関数を非常に簡単に実行するかどうかをテストできます。

答えるには:あなたの例は良い使い方ですか、evalそれともexec私はノーと言います。それが正しい答えだと思う場合execは、ソリューションを調べて、目標を達成するためのより保守しやすい、単純な、または明示的な方法があるかどうかを確認してください。この場合、特定のユーザー入力に基づいて呼び出す関数にユーザー入力をマッピングしていました。

于 2012-12-28T18:03:47.540 に答える
3

ええと、あなたはそのようにそれをすることができました、しかし多くのより良い方法があるのになぜそれをそのようにするのですか?そのような:

funcs = {1: func1, 2: func2, 3: func3, 4: func4}
option = int(raw_input("Enter selection: "))
option in funcs and funcs[option]()

ここでの利点は、関数の特定の命名規則に従う必要がないことです。オプション1が「名前の追加」の場合、のaddname()代わりに関数を呼び出すことができますfunc1()。これにより、コードをより簡単に追跡できるようになります。

于 2012-12-28T18:06:43.513 に答える
1

メソッドの名前を直接知っている場合は、@kindallが提案するようにしてください。そうでない場合は、eval()を使用してコンパイル/評価するのではなく、getattr()を使用して呼び出し用のメソッドをフェッチできます。

class ZZ(object):
  def fooBar(self):
    print(42)
  def barFoo(self):
    print(-42)

#now make a z
anInstance = ZZ()

#build up a dynamic string
string = 'foo' + 'Bar'

#fetch the attribute bound to string for the instance
method = getattr(anInstance, string)

#now execute the bound method/function (that's what the empty parens do)
method()

# out comes the following! Tada!
>>> 42

# we can inline a lot of this and just do things like
getattr(anInstance, 'bar' + 'Foo')()

# out comes the following! Again with the Tada...
>>> -42
于 2012-12-28T18:17:15.183 に答える