我正在使用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
列表中工作。此外,我有时不知道必须调用哪些键。
区分和超越地称呼所有可赎回的最佳方式是什么?
在Jon Kiparsky之后,我在每个方法定义上面添加了一个@property
装饰器。它通过颠倒问题来解决问题。没有可调用但使用此装饰器调用方法MyClass
的源定义。我的词典列表是由它生成的!
答案 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的一种形式,试图调用它并捕获异常(如果它不是可调用类型)。在你的情况下,然后只需分配它。