¿Puede el intérprete de Python fallar en funciones redeclaradas?

Mientras trabajaba en un archivo python suficientemente grande, accidentalmente he redefinido una función en el ámbito global. Agradecería que el intérprete de python me advirtiera en esos casos.

Imagina que comienzas con este código (versión 1):

#!/usr/bin/env python ... lots of code ... def foo(version): if version == 1: return "Correct" return "Oops!" ... lots more code ... print foo(1) 

Que funciona correctamente:

 Correct 

Y luego quieres cambiar algunas cosas, y llamarlo versión 2. Reescribes la función foo, pero o no te das cuenta de que existía la anterior, o te olvidas de eliminarla. Terminas con esto:

 #!/usr/bin/env python def foo(version): if version == 2: return "Correct" return "Oops!" ... lots of code ... def foo(version): if version == 1: return "Correct" return "Oops!" ... lots more code ... print foo(2) 

Que no funciona tan bien:

 Oops! 

Sé que Python permite código como este:

 def monkey(): return "patching" monkey = "is" def monkey(): return {"really": "fun"} 

Pero parece que usar “def” de esa manera es una mala práctica.

¿Hay alguna manera de que pueda obtener este tipo de comportamiento:

 #!/usr/bin/env python --def-strict def foo(): pass def foo(): pass 

Resultados en:

 Traceback (most recent call last): File ..., line 3, in  NameError: name 'foo' is already defined 

Puede crear un decorador, que puede comparar el nombre de la función y tal vez almacenarlo en un diccionario. Y si la clave ya existe, puedes lanzar una excepción del decorador. Decora todas tus funciones con este decorador durante el desarrollo. ¡Luego puede deshacerse de la decoración después de que se hayan realizado todas las pruebas!

Algo como

#import sys if sys.argv[1] == "--def-strict": def duplicateFinder(f): if globals().has_key(f.__name__): raise AttributeError, "This module already has a function %s defined" % f.__name__ return f else: def duplicateFinder(f): return f @duplicateFinder def myFunction(): print "Hello World!" @duplicateFinder def myFunction(): print "Hello World Again!!!"
#import sys if sys.argv[1] == "--def-strict": def duplicateFinder(f): if globals().has_key(f.__name__): raise AttributeError, "This module already has a function %s defined" % f.__name__ return f else: def duplicateFinder(f): return f @duplicateFinder def myFunction(): print "Hello World!" @duplicateFinder def myFunction(): print "Hello World Again!!!" 

Esto debería generar un error cuando se ejecuta con “python –def-strict scriptname”.

EDITAR: Agregar su hipotético –def-strict! Además, no es necesario mantener un diccionario __functionNames separado. El diccionario globals () es suficientemente bueno. Así que editándolo para reflejar lo mismo!

No creo que haya una bandera para el intérprete de Python que pueda ayudarte, pero puedes usar una herramienta de análisis de código estático como pyflakes, que te advertirá sobre la redefinición (al menos en algunos casos).