Est-il possible de déclarer une fonction en Python?

Est-il possible de déclarer une fonction en Python? Je veux sortinger une liste en utilisant ma propre fonction cmp avant de la déclarer.

 print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)]) 

J’ai organisé mon code pour mettre la définition de la méthode cmp_configs après l’invocation. Il échoue avec cette erreur:

 NameError: name 'cmp_configs' is not defined 

Est-il possible de “déclarer” la méthode cmp_configs avant son utilisation? Cela rendrait mon code plus propre?

Je suppose que certaines personnes seront tentées de me dire que je devrais simplement réorganiser mon code pour ne pas avoir ce problème. Cependant, il y a des cas où cela est probablement inévitable, par exemple lors de la mise en œuvre de certaines formes de récursivité. Si vous n’aimez pas cet exemple, supposez que j’ai un cas dans lequel il est vraiment nécessaire de déclarer une fonction.

Considérez ce cas où la déclaration préalable d’une fonction serait nécessaire en Python:

 def spam(): if end_condition(): return end_result() else: return eggs() def eggs(): if end_condition(): return end_result() else: return spam() 

end_condition et end_result ont été précédemment définis.

La seule solution pour réorganiser le code et toujours mettre les définitions avant les invocations?

Si vous ne voulez pas définir une fonction avant qu’elle ne soit utilisée, et que sa définition soit impossible par la suite, pourquoi ne pas la définir dans un autre module?

Techniquement, vous définissez toujours le premier, mais c’est propre.

Vous pouvez créer une récursivité comme suit:

 def foo(): bar() def bar(): foo() 

Les fonctions de Python sont anonymes, tout comme les valeurs sont anonymes, mais elles peuvent être liées à un nom.

Dans le code ci-dessus, foo() n’appelle pas une fonction avec le nom foo, elle appelle une fonction qui est liée au nom foo au moment où l’appel est effectué. Il est possible de redéfinir foo quelque part ailleurs, et bar appelle alors la nouvelle fonction.

Votre problème ne peut pas être résolu car c’est comme demander une variable qui n’a pas été déclarée.

Ce que vous pouvez faire est d’envelopper l’invocation dans une fonction qui lui est propre.

Pour que

 foo() def foo(): print "Hi!" 

va casser, mais

 def bar(): foo() def foo(): print "Hi!" bar() 

fonctionnera correctement.

La règle générale en Python n’est pas que cette fonction devrait être définie plus haut dans le code (comme en Pascal ), mais qu’elle devrait être définie avant son utilisation.

J’espère que cela pourra aider.

Si vous démarrez votre script par les moyens suivants:

 if __name__=="__main__": main() 

alors vous n’avez probablement pas à vous soucier de choses comme “déclaration anticipée”. Vous voyez, l’interpréteur va charger toutes vos fonctions et ensuite démarrer votre fonction main (). Bien sûr, assurez-vous que toutes les importations sont correctes aussi 😉

En y repensant, je n’ai jamais entendu parler de “déclaration anticipée” en python … mais là encore, je peux me tromper 😉

Si l’appel à cmp_configs se trouve dans sa propre définition de fonction, ça devrait aller. Je vais donner un exemple.

 def a(): b() # b() hasn't been defined yet, but that's fine because at this point, we're not # actually calling it. We're just defining what should happen when a() is called. a() # This call fails, because b() hasn't been defined yet, # and thus trying to run a() fails. def b(): print "hi" a() # This call succeeds because everything has been defined. 

En général, mettre votre code à l’intérieur de fonctions (telles que main ()) résoudra votre problème; il suffit d’appeler main () à la fin du fichier.

Non, je ne crois pas qu’il existe un moyen de déclarer une fonction dans Python.

Imaginez que vous êtes l’interpréteur Python. Quand vous arrivez à la ligne

 print "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)]) 

soit vous savez ce que cmp_configs est ou non. Pour continuer, vous devez connaître cmp_configs. Peu importe s’il y a récursivité.

Je m’excuse d’avoir relancé ce fil, mais il y avait une stratégie non discutée ici qui pourrait être applicable.

En utilisant la reflection, il est possible de faire quelque chose qui s’apparente à une déclaration. Par exemple, disons que vous avez une section de code qui ressemble à ceci:

 # We want to call a function called 'foo', but it hasn't been defined yet. function_name = 'foo' # Calling at this point would produce an error # Here is the definition def foo(): bar() # Note that at this point the function is defined # Time for some reflection... globals()[function_name]() 

Ainsi, nous avons déterminé quelle fonction nous voulons appeler avant qu’elle ne soit réellement définie, ce qui constitue une déclaration directe. Dans python, la commande globals()[function_name]() est identique à foo() si function_name = 'foo' pour les raisons évoquées ci-dessus, car Python doit rechercher chaque fonction avant de l’appeler. Si l’on devait utiliser le module timeit pour voir comment ces deux instructions se comparent, elles ont exactement le même coût de calcul.

Bien sûr, l’exemple ici est très inutile, mais si l’on doit avoir une structure complexe qui nécessite l’exécution d’une fonction, mais qui doit être déclarée avant (ou structurellement, cela n’a pas beaucoup de sens après), on peut simplement stocker une chaîne et essayez d’appeler la fonction plus tard.

Il n’y a pas une telle chose dans python comme déclaration à terme. Vous devez juste vous assurer que votre fonction est déclarée avant qu’elle soit nécessaire. Notez que le corps d’une fonction n’est pas interprété tant que la fonction n’est pas exécutée.

Prenons l’exemple suivant:

 def a(): b() # won't be resolved until a is invoked. def b(): print "hello" a() # here b is already defined so this line won't fail. 

Vous pouvez penser qu’un corps de fonction est juste un autre script qui sera interprété une fois que vous appelez la fonction.

Parfois, un algorithme est plus facile à comprendre de haut en bas, en commençant par la structure globale et en explorant les détails.

Vous pouvez le faire sans déclarations anticipées:

 def main(): make_omelet() eat() def make_omelet(): break_eggs() whisk() fry() def break_eggs(): for egg in carton: break(egg) # ... main() 

Vous ne pouvez pas déclarer une fonction en Python. Si vous avez une logique en cours d’exécution avant que vous ayez défini des fonctions, vous avez probablement un problème de toute façon. Mettez votre action dans un if __name__ == '__main__' à la fin de votre script (en exécutant une fonction que vous if __name__ == '__main__' “main” si elle n’est pas sortingviale) et votre code sera plus modulaire et vous pourrez l’utiliser en tant que module si vous en avez besoin.

Remplacez également cette compréhension de liste par un générateur express (c.-à-d., print "\n".join(str(bla) for bla in sorted(mylist, cmp=cmp_configs)) )

De même, n’utilisez pas cmp , qui est obsolète. Utilisez la key et fournissez une fonction moins que satisfaisante.

“Il suffit de réorganiser mon code pour ne pas avoir ce problème.” Correct. Facile à faire. Travaille toujours

Vous pouvez toujours fournir la fonction avant sa référence.

“Cependant, il y a des cas où cela est probablement inévitable, par exemple lors de la mise en œuvre de certaines formes de récursivité”

Je ne vois pas comment cela est possible à distance. Veuillez fournir un exemple d’endroit où vous ne pouvez pas définir la fonction avant son utilisation.

Maintenant, attendez une minute. Lorsque votre module atteint l’instruction print dans votre exemple, avant que cmp_configs ne soit défini, en quoi consiste-t-il exactement?

Si votre publication d’une question à l’aide de print essaie vraiment de représenter quelque chose comme ceci:

 fn = lambda mylist:"\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)]) 

il n’est pas nécessaire de définir cmp_configs avant d’exécuter cette instruction, définissez-la plus tard dans le code et tout ira bien.

Maintenant, si vous essayez de référencer cmp_configs comme valeur par défaut d’un argument de la lambda, il s’agit d’une autre histoire:

 fn = lambda mylist,cmp_configs=cmp_configs : \ "\n".join([str(bla) for bla in sorted(mylist, cmp = cmp_configs)]) 

Maintenant, vous avez besoin d’une variable cmp_configs définie avant d’atteindre cette ligne.

[EDIT – cette partie suivante s’avère ne pas être correcte, car la valeur d’argument par défaut sera atsortingbuée lorsque la fonction est compilée, et cette valeur sera utilisée même si vous modifiez la valeur de cmp_configs ultérieurement.]

Heureusement, Python étant si accommodant en cmp_configs type, ne se soucie pas de ce que vous définissez comme cmp_configs .

 cmp_configs = None 

Et le compilateur sera content. Veillez simplement à déclarer le vrai cmp_configs avant d’invoquer fn .

Une façon consiste à créer une fonction de gestionnaire. Définissez rapidement le gestionnaire et placez le gestionnaire sous toutes les méthodes que vous devez appeler.

Ensuite, lorsque vous appelez la méthode du gestionnaire pour appeler vos fonctions, elles seront toujours disponibles.

Le gestionnaire peut prendre un argument nameOfMethodToCall . Ensuite, utilise un tas d’instructions if pour appeler la bonne méthode.

Cela résoudrait votre problème.

 def foo(): print("foo") #take input nextAction=input('What would you like to do next?:') return nextAction def bar(): print("bar") nextAction=input('What would you like to do next?:') return nextAction def handler(action): if(action=="foo"): nextAction = foo() elif(action=="bar"): nextAction = bar() else: print("You entered invalid input, defaulting to bar") nextAction = "bar" return nextAction nextAction=input('What would you like to do next?:') while 1: nextAction = handler(nextAction) 

Oui, nous pouvons vérifier cela.

Consortingbution

 print_lyrics() def print_lyrics(): print("I'm a lumberjack, and I'm okay.") print("I sleep all night and I work all day.") def repeat_lyrics(): print_lyrics() print_lyrics() repeat_lyrics() 

Sortie

 I'm a lumberjack, and I'm okay. I sleep all night and I work all day. I'm a lumberjack, and I'm okay. I sleep all night and I work all day. I'm a lumberjack, and I'm okay. I sleep all night and I work all day. 

Comme BJ Homer l’a mentionné plus haut, une règle générale en Python n’est pas que cette fonction devrait être définie plus haut dans le code (comme en Pascal), mais qu’elle devrait être définie avant son utilisation.

J’espère que cela pourra aider.