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
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.
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
Vous pouvez essayer ceci:
déclarer le dictionnaire avec ses clés et le nom de chaque
fonctionner sans le ()
functions = {'1': function1, '2': fuction2, '3': fuction3, ...}
passe la fonction/valeur en utilisant la méthode get, qui renvoie None
si la clé n'existe pasaction = functions.get(key)
action()
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]