2017-04-21 1 views
-1

oui, je suis un auteur de cette Change conditions using loop and array in pythonTypeError: objet « str » est pas appelable dans le script python

, je suis en train de modifier les conditions de celle-ci:

if sys.argv[1] == 'add': 
    sys.exit(add(db, usr)) 
if sys.argv[1] == 'rem': 
    sys.exit(rem(db, usr)) 
if sys.argv[1] == 'rmusr': 
    sys.exit(rmusr(db, usr)) 

Je suis en train de modifier ces conditions à la liste avec boucle

à partir des réponses des autres développeurs, je l'ai utilisé ceci:

actions = ['add','rem','rmusr'] 
if sys.argv[1] in actions: 
    sys.exit(sys.argv[1](db, usr)) 

Mais, quand je suis en train de vérifier la fonction, j'ai ce

File "sql.py", line 25, in <module> 
    sys.exit(sys.argv[1](db, usr)) 
TypeError: 'str' object is not callable 

Je ne comprends pas, où j'ai une erreur?

+1

Ils ont utilisé un dictionnaire dans la question liée, vous utilisez une liste –

+0

parce que je pense que cette liste devrait fonctionner aussi, mais je ne comprends pas, pourquoi cela ne fonctionne pas – Piduna

+0

Vous avez une liste de chaînes pas un liste des fonctions –

Répondre

0

Pour appeler la fonction nommée par sys.argv[1], elle doit d'abord être récupérée. Par exemple:

def add(x,y): 
    return x + y 

def mul(x,y): 
    return x * y 

def perform(action, x, y): 
    # action is a string containing a function name ("add" or "mul"). 
    # globals() contains the accessible members, along with the functions. 
    return globals()[action](x, y) 

Dans le cadre du code d'origine:

actions = ['add','rem','rmusr'] 
if sys.argv[1] in actions: 
    func = globals()[sys.argv[1]] 
    sys.exit(func(db, usr)) 
1

Votre erreur est précisément parce que vous essayez d'appeler une méthode avec la chaîne de signature (db, usr). La ligne sys.argv [1] fait référence à la chaîne située dans la liste argv dans votre programme sys. Les chaînes ne sont pas appelables; votre code est l'équivalent de:

"add"(db, usr) # add is not a variable name. 

La réponse à l'autre question a utilisé un dictionnaire dont les clés recherche étaient associées aux méthodes spécifiques du même nom, ils n'a pas appelé la chaîne tant que recherche la méthode du dictionnaire utilisant la chaîne.

0

Vous pouvez utiliser quelque chose comme ceci:

# specify the function to call for each command: 
# (note: the lookup key is a string, but the value is a function reference) 
actions = {'add': add, 'rem': rem, 'rmusr': rmusr} 
cmd = sys.argv[1] 
# check if it's in the dictionary's keys 
if cmd in actions: 
    # lookup the function to call 
    func = actions[cmd] 
    # call the function 
    sys.exit(func(db, usr)) 

Ou cela est moins bavard, mais aussi moins précis. Il utilise le fait que toutes les fonctions définies sont listées par nom dans le dictionnaire globals().

# list of all allowed commands: 
actions = ['add', 'rem', 'rmusr'] 
cmd = sys.argv[1] 
# check if it's allowed 
if cmd in actions: 
    # lookup the function by name in the globals() dictionary 
    func = globals()[cmd] 
    # call the function 
    sys.exit(func(db, usr)) 
0

sys.argv[1] est de type str (une chaîne), et une chaîne de caractères est pas une fonction. Ainsi, lorsque vous essayez d'exécuter sys.argv[1](db, usr), vous essayez littéralement d'exécuter une chaîne comme s'il s'agissait d'une fonction, ce qui n'est pas autorisé. Ce que pouvez peut, cependant, est rechercher la fonction en utilisant la valeur sys.argv[1] Vous pouvez le faire de plusieurs façons. Une solution consisterait à rechercher la fonction en utilisant globals(), ce qui renvoie un dictionnaire des noms des fonctions mappées à la fonction elle-même.

Par exemple:

Disons que vous exécutez votre programme avec cette commande: python myScript.py argument1. Cela signifierait que sys.argv[1] aurait la valeur "argument1".Ensuite, vous prendriez cette valeur et rechercher la fonction dans le dictionnaire retourné par globals() (ou vous pouvez utiliser locals() si vous êtes dans la même portée que la fonction que vous appelez):

sys.exit(globals()[sys.argv[1]](db, usr)) 

L'autre façon serait de créer ce dictionnaire vous:

actions = {'add': add, 'rem': rem, 'rmusr': rmusr} 
if sys.argv[1] in actions: 
    sys.exit(actions[sys.argv[1]](db, usr)) 
+0

'actions' a besoin d'accolades' {} 'pour créer un dictionnaire; c'est actuellement une liste (en fait, vous obtiendrez une erreur de syntaxe). –

+0

Oui, j'ai oublié de les changer. – wheeler

0

Je préfère utiliser: https://docs.python.org/3.3/library/argparse.html Utilisation du argparse vous flexability morze en utilisant les lignes de commande args. Vous pouvez facilement utiliser l'instruction if si un argument est utilisé dans les lignes de commande.