关于python:字典值作为访问密钥时要调用的函数,不使用“()”

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

我有一本字典,它的值有时是字符串,有时是函数。对于作为函数的值,在访问键时,有没有一种方法可以在不显式键入()的情况下执行函数?

例子:

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

我想要:

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


另一种可能的解决方案是创建一个实现此行为的自定义字典对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> 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

也许更惯用的解决方案是使用try/except

1
2
3
4
5
6
def __getitem__(self, key):
    val = super().__getitem__(key)
    try:
        return val()
    except TypeError:
        return val

但是请注意,上面的方法确实是为了完整。我不建议用它。正如评论中指出的那样,它将掩盖由函数提出的TypeError。您可以测试TypeError的确切内容,但在这一点上,您最好使用lbyl样式。


我认为标准库不可能(很容易)做到这一点,但是您可以使用来自模块lazy_object_proxylazy_object_proxy.Proxy(它是第三方,因此您需要安装它):

1
2
3
4
5
6
7
8
9
>>> 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


您可以尝试以下操作:

  • 声明字典及其键和每个键的名称

  • 不带()的函数

    函数='1':函数1,'2':函数2,'3':函数3,…'

  • 使用get方法传递函数/值,该方法不返回

  • 如果密钥不存在action = functions.get(key)

  • 调用存储在var操作中的函数,+()action()
  • 您的功能将被执行。

  • 使用callable()检查变量是否可调用:

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


    另一种解决方案:您还可以通过一些使用@property修饰的类方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Test:
        @property
        def method(self):
            return 'X'

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