web-dev-qa-db-fra.com

Valeur du dictionnaire en tant que fonction à appeler lors de l'accès à une touche, sans utiliser "()"

J'ai un dictionnaire qui a des valeurs parfois sous forme de chaînes et parfois sous forme de fonctions. Pour les valeurs qui sont des fonctions, existe-t-il un moyen d'exécuter la fonction sans saisir explicitement () lors de l'accès à la clé?

Exemple:

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

Je voudrais:

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

Une autre solution possible consiste à créer un objet dictionnaire personnalisé qui implémente ce comportement:

>>> 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

Un peut-être une solution plus idiomatique serait d'utiliser try/except:

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

Notez cependant que la méthode ci-dessus est vraiment complète. Je ne recommanderais pas de l'utiliser. Comme indiqué dans les commentaires , cela masquerait les noms de TypeError soulevés par la fonction. Vous pouvez tester le contenu exact de TypeError, mais à ce stade, vous feriez mieux d'utiliser le style LBYL.

11
Christian Dean

Je ne pense pas que ce soit (facilement) possible avec la bibliothèque standard, mais vous pouvez utiliser lazy_object_proxy.Proxy à partir du module lazy_object_proxy (c'est une tierce partie, vous devez donc l'installer):

>>> 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

Vous pouvez essayer ceci: 

  1. déclarer le dictionnaire avec ses clés et le nom de chaque

  2. fonctionner sans le () 

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

  3. passe la fonction/valeur en utilisant la méthode get, qui renvoie None 

  4. si la clé n'existe pas
    action = functions.get(key) 

  5. appelez la fonction, qui est stockée dans l'action var, + () action() 
  6. votre fonction sera exécutée.
0
OG_

Utilisez callable() pour vérifier si la variable est bien appelable:

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