How do you do a python 'eval' only within an object context?

前端 未结 4 2017
慢半拍i
慢半拍i 2021-02-14 14:41

Is it possible to do something like

c = MyObj()
c.eval(\"func1(42)+func2(24)\")

in Python..i.e. have func1() and func2() be evaluated within th

4条回答
  •  囚心锁ツ
    2021-02-14 14:57

    So, I advice you to do something like this:

    >>> class S(object):
    ...     def add(self, a, b):
    ...         return a + b
    ... 
    >>> filter(lambda (k,v): not k.startswith("__"), S.__dict__.items())
    [('add', )]
    >>> target = S()
    >>> map(lambda (k, f): (k, f.__get__(target, S)), filter(lambda (k,v): not k.startswith("__"), S.__dict__.items()))
    [('add', >)]
    >>> dict(_)
    {'add': >}
    >>> eval("add(45, 10) + add(10, 1)", _, {})
    66
    

    Seems like that you need. Let me explain how this works.

    1. eval accepts locals and globals as parameters.
    2. So we need to define special global context which will be "representation" of your class.
    3. To do this, we need to provide as globals dictionary of all "valuable" bounded methods.
    4. Starting from simples part. We have S class definition. How to get all "valuable" methods? Simple filter names from S.__dict__ in order to check whether method name starts from __ or not (you see, that as result we get list with 1 item - add function).
    5. Create target = instance of S class which will be "eval context".
    6. Next step is most "tricky". We need to create "bound method" from each function. To do this, we use those fact, that class __dict__ stores functions, each function is non-data descriptor and bounded method can be fetched simply with func.__get__(obj, type(obj)). This operation is performed in map.
    7. Take result from previous step, create dict from it.
    8. Pass as globals to eval function.

    I hope, this will help.

提交回复
热议问题