valor - usar diccionario python




Valor del diccionario como función que se debe invocar cuando se accede a la clave, sin usar "()" (3)

Tengo un diccionario que tiene valores a veces como cadenas, y a veces como funciones. Para los valores que son funciones ¿hay alguna manera de ejecutar la función sin escribir explícitamente () cuando se accede a la tecla?

Ejemplo:

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

Yo quiero:

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

No creo que eso (sea) posible con la biblioteca estándar, pero podrías usar lazy_object_proxy.Proxy desde el módulo lazy_object_proxy (es un tercero, así que debes instalarlo):

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

Use callable() para verificar si la variable es, bueno, invocable:

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

Otra posible solución es crear un objeto de diccionario personalizado que implemente este comportamiento:

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

Una solución quizás más idiomática sería usar try/except :

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

Sin embargo, tenga en cuenta que el método anterior es realmente para la completitud. No recomendaría usarlo. Como se señaló en los comentarios , enmascararía TypeError 's provocado por la función. Podría probar el contenido exacto de TypeError , pero en ese punto, sería mejor que use el estilo LBYL.





callback