简体   繁体   English

将函数从另一个类传递给该类

[英]Passing function from another class to this class

I know, title is hard to understand. 我知道标题很难理解。

So, i have this class: 所以,我有这个课:

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'

And what i want - i create instance of this class with dict as parameter: 而我想要的-我用dict作为参数创建此类的实例:

ConfigDict({'a' : 'b'})

It's working, thats good. 工作正常,那就好。 But i want pass function as argument in dict from ConfigDict class without importing methods from ConfigDict. 但是我想从ConfigDict类中将函数作为dict中的参数传递而无需从ConfigDict中导入方法。
For example, i want do this: 例如,我想这样做:

 ConfigDict({'a' : ('b', required(['test'], valid))})

I know that required in ConfigDict do nothing now. 我知道ConfigDict中required的现在什么也不做。 Expected result is: 预期结果是:

>> ConfigDict({'a' : ('b', required(['test'], valid()))})
required called with ['test'], valid for {a : b}
valid called from required with None for {a : b}

So, after creating instance of ConfigDict with {'a' : ('b', required['test'], valid())} dict, i want that this instance in __init__ method make loop in all dict elements, and if founds tuple in value, execute founded nested function in itselfs. 因此,在使用{'a' : ('b', required['test'], valid())} dict创建ConfigDict实例之后,我希望__init__方法中的此实例在所有dict元素中进行循环,如果找到元组值,本身执行已建立的嵌套函数。

Is here any way to do this without importing all methods from ConfigDict? 是否可以在不从ConfigDict导入所有方法的情况下执行此操作?

EDIT: 编辑:

As i expected i must better explain what i need. 如我所料,我必须更好地解释我的需求。

Ok, we take this fragment: 好的,我们看一下这个片段:

ConfigDict({'a' : ('b', required(['test'], valid))})

This made us new instance of ConfigDict. 这使我们有了ConfigDict的新实例。 These functions in touple is used to validate value , in this case it is 'b' . touple中的这些函数用于验证 ,在这种情况下为'b' I made few changes waiting for response, so calling this class is now look that: 我做了一些更改以等待响应,因此现在调用此类如下所示:

cd = ConfigDict()
cd.feed({'a' : 'b'})

I can call functions like that: 我可以这样调用函数:

cd.feed({'a' : ('b', cg.required(['test']))})

What is work's very well, but there's one thing - it not pass to required function the value. 工作很好,但是有一件事情-它没有将值传递给required函数。 ConfigDicts.required should get an array and value, in this case 'b' . ConfigDicts.required应该获取一个数组值,在这种情况下为'b' I don't expect to find way to do this myself, except using everywhere lambda's what i like to avoid. 我不希望自己找到办法,除非在各处都使用lambda,这是我想避免的。

So, my question been bit changed - is there a any way to get 'b' value from inside required function? 因此,我的问题已被更改-是否有任何方法可以从required函数内部获取'b'值? I can pass 'b' as argument directly into required , but i expect to have many functions call in tuple, passing value for each make a little mess in code. 我可以将'b'作为参数直接传递给required ,但是我希望在tuple中调用许多函数,为每个函数传递值会使代码有些混乱。

Also, anyone please, edit title of my post, i lack of words to describe this problem :) 另外,任何人,请编辑我的帖子的标题,我缺乏描述这个问题的文字:)

Use a lambda function: 使用lambda函数:

ConfigDict({'a' : ('b', lambda self: self.required(['test'], valid))})

This would require you to explicitly pass self as a parameter (From the __init__ method, it would look like dict['a'][1](self) ). 这将要求您显式地将self作为参数传递(从__init__方法中,它看起来像dict['a'][1](self) )。

You can find out if something is a tuple like this: 您可以找出某物是否是像这样的元组:

>>> isinstance((1, 2, 3), tuple)
True
>>> isinstance(1, tuple)
False

And if you need to, you can find out if something is a function like so: 并且,如果需要,您可以找出某种东西是否像这样的函数:

>>> import inspect
>>> def f():
    print "I'm a function"
>>> inspect.isfunction(f)
True
>>> inspect.isfunction(5)
False
>>> inspect.isfunction(lambda d: d)
True

Your English is a bit hard to understand, and your question contains some errors (or just inconsistencies), so I'm not sure what exactly you want, but here's one thing the may work for you: 您的英语有点难懂,而且您的问题包含一些错误(或仅不一致),所以我不确定您到底想要什么,但是这可能对您有用:

(Edit) Try this: (编辑)尝试:

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

Output: 输出:

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'}

这是一个解决方案,但您实际上是想在这里写一些用领域特定语言可以更好地完成(更好地理解,减少一些细微的错误)的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM