Python:如何在给定时间调用包含字典的回调?

时间:2014-12-10 20:07:58

标签: python dictionary

我正在使用python中包含大量键的字典对象。它们的一些相关值类型是可调用类型。

类似的东西:

dico = {
    'key1' : 1,
    'key2' : 'cars',
    'key3' : <bound method MyClass.MyMethod_A of <MyClass: MyClass object >>,
    'deeperkeys':{
                  subkey1 : 'space',
                  subkey2 : <bound method MyClass.MyMethod_B of <MyClass: MyClass object >>,
                 },
       }

我知道我能做到:

dico['key3'] = dico['key3']()
dico['deeperkeys']['subkey2'] = dico['deeperkeys']['subkey2']()

此外,请注意我不是如上所述在unic dico上工作,而是在大量的dico列表中工作。此外,我有时不知道必须调用哪些键。 区分和超越地称呼所有可赎回的最佳方式是什么?

UPD

在Jon Kiparsky之后,我在每个方法定义上面添加了一个@property装饰器。它通过颠倒问题来解决问题。没有可调用但使用此装饰器调用方法MyClass的源定义。我的词典列表是由它生成的!

4 个答案:

答案 0 :(得分:0)

虽然我不以任何方式推荐这一点 - 请参阅我对原始问题的评论 - 嵌套结构通常需要递归下降。您编写了一个函数来检查dict的values()列表中的每个值,并执行以下三种操作之一:

  • 如果值可以调用,请将其命名为
  • 如果值是字典,请进行递归调用
  • 否则,跳过它。

与探索文件树没什么不同,真的。

然而,我并不为重复这一点而道歉,重要的是要在这里审查您的实际问题,并确定这是否真的是您想要做的事情。我无法看到这是一个很好的解决方案。

编辑:基于来自OP的更多信息,看起来@property装饰器可能是必需的。用法示例:

>>> class Foo:
...     @property
...     def current_time(self):
...             from datetime import datetime
...             return datetime.now()
... 
>>> f = Foo()
>>> f.current_time
datetime.datetime(2014, 12, 10, 15, 29, 35, 146096)
>>> f.current_time
datetime.datetime(2014, 12, 10, 15, 29, 42, 383874)

请注意,语法将current_time名称评估为简单值,但返回的值是调用函数的结果,导致评估时的值,我认为是什么你之后。

(但正如@abarnert所说,你将这些放入字典中,所以这对你不起作用)

答案 1 :(得分:0)

为什么在这个世界上你想要做到这一点超出了我的范围,但一个简单的recursive函数就可以了。类似的东西:

def call_all(dict_or_list):
    if type(dict_or_list) == list:
        for d in dict_or_list:
            call_all(d)
    elif type(dict_or_list) == dict:
        for k, v in dict_or_list.iteritems():
            call_all(v)
    else:
        try:
            dict_or_list()
        except:
            print("Couldn't call:", dict_or_list)

这应该遍历嵌套字典或列表的每个项目并尝试调用它们。

答案 2 :(得分:0)

你的问题的字面答案是callable函数,如果你传递了一些可调用的东西,则返回true,如果你没有,则返回false。

例如:

def undefer(func_or_value):
    if callable(func_or_value):
        return func_or_value()
    else:
        return func_or_value

现在你可以写:

dico['key3'] = undefer(dico['key3'])

但是,这可能会成为一个非常糟糕的主意。您可能不关心这些限制(例如,现在您实际上可以将任何可调用的值存储为值,并且您可能希望,例如,有一天在那里存储类型),但您显然关心产生的混淆将错误的函数和值混合成同一类东西,因为这种混淆首先导致了这个问题。

我认为你想要做的是存储除了callables之外什么都没有,所以你总是调用这个值。其中一些callables只返回一个常数值,但这很好:只存储lambda: 42而不是42。

或者你可能想让事情变得更加明确。你在这里并不是真正的可靠性;这些方法的意义在于它们就像递延值或期货一样。您可以编写一个非常简单的延迟/未来类,可以从常量调用或函数调用构造。这也可以让你添加像&#34这样的功能;只在第一次调用这个函数,然后缓存值&#34;。但是,更重要的是,它明确表达了你所做的事情;没有办法将Future与其他任何东西混淆,错过延期或延期的错误信息将是显而易见的,并且无法修复等等。

答案 3 :(得分:0)

如果它嘎嘎叫,那就是可以调用:

>>> y=lambda: 'Y'
>>> x='X'
>>> try:
...    z=x()
... except TypeError:
...    z=x
... 
>>> z
'X'
>>> try:
...    z=y()
... except TypeError:
...    z=y
... 
>>> z
'Y'

这是duck typing的一种形式,试图调用它并捕获异常(如果它不是可调用类型)。在你的情况下,然后只需分配它。