2009-11-16 3 views
17

Comment puis-je activer une chaîne telle que "+" dans l'opérateur plus? Merci!Transformez la chaîne en opérateur

+1

à la place, vous pouvez convertir d'autres choses à chaîne et d'évaluer http : //stackoverflow.com/questions/729248/python-eval-and-globals – Xinus

Répondre

56

Utilisez une table de recherche:

import operator 
ops = { "+": operator.add, "-": operator.sub } # etc. 

print ops["+"](1,1) # prints 2 
-12

Vous pouvez utiliser eval comme ceci:

eval("+") 
+5

cela provoque l'erreur de syntaxe – Xinus

+2

il est également très dangereux d'utiliser eval – Alvin

+1

"réponse" inutile qui produit juste une erreur de syntaxe, ce n'est même pas remarquable pour montrer le "Mauvaise façon de le faire". –

2

Vous pouvez essayer d'utiliser eval(), mais il est dangereux si les chaînes ne viennent pas de vous. Sinon vous pouvez envisager de créer un dictionnaire:

ops = {"+": (lambda x,y: x+y), "-": (lambda x,y: x-y)}

etc ... puis appeler

ops['+'] (1,2)
ou, pour les entrées utilisateur:

if ops.haskey(userop): 
    val = ops[userop](userx,usery) 
else: 
    pass #something about wrong operator
12
import operator 

def get_operator_fn(op): 
    return { 
     '+' : operator.add, 
     '-' : operator.sub, 
     '*' : operator.mul, 
     '/' : operator.div, 
     '%' : operator.mod, 
     '^' : operator.xor, 
     }[op] 

def eval_binary_expr(op1, oper, op2): 
    op1,op2 = int(op1), int(op2) 
    return get_operator_fn(oper)(op1, op2) 

print eval_binary_expr(*("1 + 3".split())) 
print eval_binary_expr(*("1 * 3".split())) 
print eval_binary_expr(*("1 % 3".split())) 
print eval_binary_expr(*("1^3".split())) 
+0

En python3, ceci donne: '+': operator.add, AttributeError: l'objet 'str' n'a pas d'attribut 'ajouter' –

+0

Le problème est que le 'opérateur 'mal nommé les conflits de paramètres avec le module opérateur importé. Je suppose que vous avez mis en ligne 'get_operator_fn' avec' eval_binary_expr'. Changez le paramètre 'operator' en quelque chose d'autre, comme' oper', et toutes les références à celui-ci. Voir ma modification. – PaulMcG

+0

Pour Python3, vous devrez également changer 'operator.div' en' operator.truediv' et corriger toutes les instructions d'impression. – PaulMcG

1

À mon avis, la réponse proposée par Amnon est le bon.

Cependant, vous pouvez également être intéressé par cet article sur un analyseur mathématique: http://effbot.org/zone/simple-top-down-parsing.htm

+0

Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses à lien uniquement peuvent devenir invalides si la page liée change. - [À revoir] (/ review/low-quality-posts/18628184) – xgord

+0

Cela appartient à la section des commentaires car ce n'est pas une réponse directe. – Pablo

0

Il existe une méthode magique correspondant à chaque opérateur

OPERATORS = {'+': 'add', '-': 'sub', '*': 'mul', '/': 'div'} 

def apply_operator(a, op, b): 

    method = '__%s__' % OPERATORS[op] 
    return getattr(b, method)(a) 

apply_operator(1, '+', 2) 
+1

cela fonctionne bien, merci pour le partage. pour la validation, nous pouvons étendre apply_operator. si op == '/' et b == 0: \t retour np.inf si op == '/' et a == 0: \t return 0 – iratzhash

+0

Cela ne laisse pas [NotImplemented] (https: //docs.python.org/3/library/constants.html#NotImplemented) fonctionne correctement. – wim