我知道,标题很难理解。
所以,我有这个课程:
class ConfigDict(dict):
def __init__(self, dic):
super(ConfigDict, self).__init__(dic)
def required(self, keys_array, function):
print 'required'
def valid(self, function = None):
print 'valid'
我想要的是 - 我用dict作为参数创建这个类的实例:
ConfigDict({'a' : 'b'})
它正常运作,这很好。但是我希望在ConfigDict类的dict中传递函数作为参数而不从ConfigDict导入方法 例如,我想这样做:
ConfigDict({'a' : ('b', required(['test'], valid))})
我知道ConfigDict中的required
现在什么都不做。预期结果是:
>> ConfigDict({'a' : ('b', required(['test'], valid()))})
required called with ['test'], valid for {a : b}
valid called from required with None for {a : b}
因此,在使用{'a' : ('b', required['test'], valid())}
dict创建ConfigDict实例后,我希望__init__
方法中的这个实例在所有dict元素中生成循环,如果在值中创建了元组,则在自身中执行创建的嵌套函数
如果没有从ConfigDict导入所有方法,有没有办法做到这一点?
修改
正如我所料,我必须更好地解释我需要的东西。
好的,我们采取这个片段:
ConfigDict({'a' : ('b', required(['test'], valid))})
这使我们成为ConfigDict的新实例。 touple中的这些函数用于验证值,在这种情况下它是'b'
。我做了一些等待响应的更改,所以现在调用这个类看起来:
cd = ConfigDict()
cd.feed({'a' : 'b'})
我可以调用这样的函数:
cd.feed({'a' : ('b', cg.required(['test']))})
什么是工作非常好,但有一件事 - 它没有传递给required
函数的值。 ConfigDicts.required
应该获得数组和值,在本例中为'b'
。我不希望自己找到这样做的方法,除了使用lambda的所有内容,我想避免使用它。
所以,我的问题有点改变 - 有没有办法从内部 'b'
函数中获取required
值?我可以将'b'
作为参数直接传递给required
,但我希望在元组中调用很多函数,为每个函数传递值会使代码变得有些混乱。
此外,有人请,编辑我的帖子的标题,我缺乏描述这个问题的词语:)
答案 0 :(得分:2)
使用lambda函数:
ConfigDict({'a' : ('b', lambda self: self.required(['test'], valid))})
这需要您明确地将self
作为参数传递(从__init__方法看,它看起来像dict['a'][1](self)
)。
你可以发现某些东西是否是这样的元组:
>>> isinstance((1, 2, 3), tuple)
True
>>> isinstance(1, tuple)
False
如果你需要,你可以发现某些东西是否是这样的函数:
>>> import inspect
>>> def f():
print "I'm a function"
>>> inspect.isfunction(f)
True
>>> inspect.isfunction(5)
False
>>> inspect.isfunction(lambda d: d)
True
答案 1 :(得分:1)
你的英语有点难以理解,而你的问题包含一些错误(或只是不一致),所以我不确定你到底想要什么,但这可能对你有用:
(编辑)试试这个:
class CallWrapper(object):
def __init__(self, fn):
self.fn = fn
def __call__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
return self
def invoke_with_value(self, value):
return self.fn(value, *self.args, **self.kwargs)
class ConfigDict(dict):
def __init__(self, ldic):
myvars = globals()
for name in dir(self):
attr = getattr(self, name)
if callable(attr) and not name.startswith('_'):
myvars[name] = CallWrapper(attr)
wrapped_dic = eval(ldic.func_code, myvars)
dic = {}
for key, value in wrapped_dic.iteritems():
# Check if value is a tuple with call wrappers
if isinstance(value, tuple) and len(value) > 1 and \
isinstance(value[1], CallWrapper):
wrappers = value[1:]
value = value[0]
for wrapper in wrappers:
# Run wrappers
result = wrapper.invoke_with_value(value)
if result:
value = result # Wrapper modified value
dic[key] = value # No wrappers
super(ConfigDict, self).__init__(dic)
def prefix(self, value, pref):
print 'prefix called for value: ', value
return pref + '_' + value
def required(self, value, keys_array):
print 'required called for value: ', value
print 'with keys: ', keys_array
def valid(self, value):
print 'valid called for value: ', value
cfg = ConfigDict(lambda: {'A': ('a', required(['test']), valid()),
'B': ('b', prefix('hello')),
'C': 'c'})
print cfg
输出:
required called for value: a
with keys: ['test']
valid called for value: a
prefix called for value: b
{'A': 'a', 'C': 'c', 'B': 'hello_b'}
答案 2 :(得分:0)
这是一个警察,但你真的在这里写一些东西,通过领域特定语言写一些可能更好(更好理解,更少微妙的错误)的东西。