Comment voulez-vous faire un python 'eval' que dans un contexte de l'objet?

Est-il possible de faire quelque chose comme

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

en Python..c'est à dire func1() et func2() est évaluée dans le champ d'application de l'objet 'c' (si ils ont des fonctions de membre au sein de cette définition de la classe)? Je ne peux pas faire une analyse simple, depuis que mon application de l'eval chaînes peut devenir arbitrairement complexe. Je pense faire de la magie avec l'ast module pourrait faire l'affaire, mais en raison de la très peu de littérature sur les ast, je ne sais pas où chercher:

import ast

class MyTransformer(ast.NodeTransformer):
    def visit_Name(self, node):
        # do a generic_visit so that child nodes are processed
        ast.NodeVisitor.generic_visit(self, node)
        return ast.copy_location(
            # do something magical with names that are functions, so that they become 
            # method calls to a Formula object
            newnode,
            node
        )

class Formula(object):

    def LEFT(self, s, n):
        return s[:n]

    def RIGHT(self, s, n):
        return s[0-n:]

    def CONCAT(self, *args, **kwargs):
        return ''.join([arg for arg in args])

def main():

    evalString = "CONCAT(LEFT('Hello', 2), RIGHT('World', 3))"

    # we want to emulate something like Formula().eval(evalString)
    node = ast.parse(evalString, mode='eval')
    MyTransformer().visit(node)

    ast.fix_missing_locations(node)
    print eval(compile(node, '<string>', mode='eval'))    
Vous pourriez avoir plus de chance juste de créer votre propre langage simple et d'analyser cela avec quelque chose comme pyPEG
Pouvez-vous vous limiter uniquement à des méthodes sur l'objet, ou voulez-vous être en mesure d'appeler d'autres choses comme des variables globales ou de nommer explicitement les autres classes?
eval() peut prendre "globals" et "habitants" des dictionnaires en tant que paramètres. Peut-être que vous pouvez remplir ces avec vos fonctions et de les transmettre?
Honnêtement, je pense que vous doit être explicitement l'analyse ici. Il n'est pas trivial, mais c'est parce que ce que vous essayez de réaliser n'est pas trivial. Si cela ne fonctionne pas, @LAK suggestion de remplissage d'un explicite le dictionnaire à utiliser en tant que contexte est probablement encore plus simple que de faire semblant avec un objet. Mais si vous vous voulez utiliser des objets comme les contextes, voir ma réponse.
Aussi, si "l'eval chaînes peut devenir arbitrairement complexe"—sont-ils arbitrairement complexe Python? Quelqu'un peut-eval, disons, 'func1(42) + func2(24) + os.system("rm -rf /")'?

OriginalL'auteur Vineet Bansal | 2012-12-17