将另一个类的函数传递给这个类
我知道,标题很难理解。将另一个类的函数传递给这个类
所以,我有这个类:
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'
,我想什么 - 我用字典创建该类的实例作为参数:
ConfigDict({'a' : 'b'})
它的工作,那是很好的。但我想从ConfigDict类的字典中传递函数作为参数,而无需从ConfigDict中导入方法。
例如,我想这样做:
ConfigDict({'a' : ('b', required(['test'], valid))})
我知道required
在ConfigDict现在什么也不做。预期的结果是:
>> 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())}
字典创建ConfigDict的实例后,我想,这种情况下在__init__
方法使循环中的所有字典的元素,如果创建于一值的元组,执行在itselfs成立嵌套函数。
在这里有没有办法做到这一点,而无需从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
,但我希望有多个函数调用元组,每个值都会在代码中造成一些混乱。
而且,任何人请,我的文章的编辑,我缺乏的话来形容这个问题:)
你的英语有点难以理解,并且你的问题包含一些错误(或者只是不一致),所以我不确定你到底想要什么,但是这里有一件事可能适用于你:
(编辑)试试这个:
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'}
使用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
这是一种逃避,但是你真的弯曲这里写一些东西,很可能是更好的成就(更好的理解,更少的微妙的错误)通过域特定语言。
只有一点点?不错的进展,一个月前我甚至无法理解我自己;)这几乎正是我要找的,谢谢。 – Galmi 2011-05-17 00:08:24
我测试了你的代码,我发现这很好,但是没有做到我所期望的,除了在ConfigDict中调用函数。在几分钟内我编辑我的帖子,尝试解释我需要的更简单。 – Galmi 2011-05-17 00:42:22
现在工作:)再次谢谢你。 – Galmi 2011-05-17 02:57:30