web-dev-qa-db-ja.com

「()」を使用せずにキーにアクセスしたときに呼び出される関数としての辞書値

時々文字列として、時には関数として値を持つ辞書があります。関数である値について、キーにアクセスしたときに明示的に()と入力せずに関数を実行する方法はありますか?

例:

d = {1: "A", 2: "B", 3: fn_1}
d[3]() # To run function

が欲しいです:

d = {1: "A", 2: "B", 3: magic(fn_1)}
d[3] # To run function
11
tyleax

別の可能な解決策は、この動作を実装するカスタム辞書オブジェクトを作成することです:

>>> class CallableDict(dict):
...     def __getitem__(self, key):
...         val = super().__getitem__(key)
...         if callable(val):
...             return val()
...         return val
...
>>>
>>> d = CallableDict({1: "A", 2: "B", 3: lambda: print('run')})
>>> d[1]
'A'
>>> d[3]
run

A おそらくもっと慣用的な解決策try/except

def __getitem__(self, key):
    val = super().__getitem__(key)
    try:
        return val()
    except TypeError:
        return val

ただし、上記の方法は実際に完全を期すためのものです。使用はお勧めしません。 コメントで指摘されているように は、関数によって発生したTypeErrorをマスクします。 TypeErrorの正確な内容をテストすることもできますが、その時点ではLBYLスタイルを使用する方がよいでしょう。

12
Christian Dean

標準ライブラリでは(簡単に)可能ではないと思いますが、lazy_object_proxy.Proxyモジュールから lazy_object_proxy (サードパーティなので、インストールする必要があります):

>>> import lazy_object_proxy
>>> def fn_1():
...     print('calculation')
...     return 1000
...
>>> d = {1: "A", 2: "B", 3: lazy_object_proxy.Proxy(fn_1)}
>>> print(d[3])
calculation
1000
6
MSeifert

あなたはこれを試すことができます:

  1. キーとそれぞれの名前で辞書を宣言します

  2. ()なしの関数

    functions = {'1':function1、 '2':fuction2、 '3':fuction3、...}

  3. noneを返すメソッドgetを使用して関数/値を渡します

  4. キーが存在しない場合
    action = functions.get(key)

  5. varアクションに保存されている関数を呼び出します+()action()
  6. 関数が実行されます。
0
OG_

callable()を使用して、変数が呼び出し可能かどうかを確認します。

d = {1: "A", 2: "B", 3: fn_1}
if callable(d[3]):
    d[3]()
else:
    d[3]
0
Alex Undefined