Dictionary value as function to be called when key is accessed, without using “()”

醉酒当歌 提交于 2020-12-01 03:33:27

问题


I have a dictionary that has values sometimes as strings, and sometimes as a functions. For the values that are functions is there a way to execute the function without explicitly typing () when the key is accessed?

Example:

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

I want:

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

回答1:


Another possible solution, is to create a custom dictionary object that implements this behavior:

>>> 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 perhaps more idiomatic solution would be to use try/except:

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

Note however the method above is really for completness. I would not reccomend using it. As pointed out in the comments, it would mask TypeError's raised by the function. You could test the exact content of TypeError, but at that point, you'd be better of using the LBYL style.




回答2:


I don't think that's (easily) possible with the standard library but you could use lazy_object_proxy.Proxy from the module lazy_object_proxy (it's third party so you need to install it):

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



回答3:


Use callable() to check if variable is, well, callable:

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



回答4:


You can try this:

  1. declare the dictionary with its keys and the name of each

  2. function without the()

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

  3. pass the function/value by using the method get, which returns None

  4. if the key doesn't exists
    action = functions.get(key)

  5. call the function ,which is stored in the var action, + () action()
  6. your function will be executed.



回答5:


Another solution: you can also pass some class method decorated using @property:

class Test:
    @property
    def method(self):
        return 'X'

d = {'a': 1, 'b': Test().method}
print(d)
print(d['a'])
print(d['b'])


来源:https://stackoverflow.com/questions/46106779/dictionary-value-as-function-to-be-called-when-key-is-accessed-without-using

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!