una propias otra metodos mandar llamar lista funciones funcion dentro clases python forward-declaration

propias - llamar funciones dentro de funciones python



¿Es posible reenviar-declarar una función en Python? (13)

"simplemente reorganice mi código para que yo no tenga este problema". Correcto. Fácil de hacer. Siempre funciona

Siempre puede proporcionar la función antes de su referencia.

"Sin embargo, hay casos en que esto es probablemente inevitable, por ejemplo cuando se implementan algunas formas de recursión"

No puedo ver cómo eso es remotamente posible. Proporcione un ejemplo de un lugar donde no pueda definir la función antes de usarla.

¿Es posible reenviar-declarar una función en Python? Quiero ordenar una lista usando mi propia función cmp antes de que se declare.

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

He organizado mi código para poner la definición del método cmp_configs después de la invocación. Falla con este error:

NameError: name ''cmp_configs'' is not defined

¿Hay alguna forma de "declarar" el método cmp_configs antes de usarlo? ¿Haría que mi código se vea más limpio?

Supongo que algunas personas sentirán la tentación de decirme que debería reorganizar mi código para que no tenga este problema. Sin embargo, hay casos en que esto es probablemente inevitable, por ejemplo cuando se implementan algunas formas de recursión. Si no te gusta este ejemplo, supongamos que tengo un caso en el que es realmente necesario reenviar declarar una función.

Considere este caso donde declarar a futuro una función sería necesaria en Python:

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

Donde end_condition y end_result han sido definidos previamente.

¿Es la única solución para reorganizar el código y siempre poner las definiciones antes de las invocaciones?


A veces, un algoritmo es más fácil de entender de arriba hacia abajo, comenzando con la estructura general y profundizando en los detalles.

Puede hacerlo sin declaraciones directas:

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


Ahora espera un minuto. Cuando su módulo llega a la declaración de impresión en su ejemplo, antes de que se haya definido cmp_configs , ¿qué es exactamente lo que espera que haga?

Si su publicación de una pregunta usando impresión realmente intenta representar algo como esto:

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

entonces no hay ningún requisito para definir cmp_configs antes de ejecutar esta declaración, simplemente cmp_configs más adelante en el código y todo estará bien.

Ahora bien, si intentas hacer referencia a cmp_configs como un valor predeterminado de un argumento para la lambda, entonces esta es una historia diferente:

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

Ahora necesita una variable cmp_configs definida antes de llegar a esta línea.

[EDITAR: esta próxima parte resulta no ser correcta, ya que el valor del argumento predeterminado se asignará cuando se compile la función, y ese valor se usará incluso si cambia el valor de cmp_configs más adelante.]

Afortunadamente, Python es tan acomodaticio como es, no le importa lo que usted defina como cmp_configs , por lo que podría cmp_configs con esta afirmación:

cmp_configs = None

Y el compilador estará feliz. Solo asegúrese de declarar los cmp_configs reales antes de invocar fn .


Lo que puedes hacer es envolver la invocación en una función propia.

Así que eso

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

se romperá, pero

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

funcionará correctamente

La regla general en Python no es que la función deba definirse más arriba en el código (como en Pascal ), sino que debe definirse antes de su uso.

Espero que ayude.


Me disculpo por revivir este hilo, pero hubo una estrategia no discutida aquí que puede ser aplicable.

Usando la reflexión es posible hacer algo parecido a la declaración directa. Por ejemplo, digamos que tiene una sección de código que se ve así:

# 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]()

Entonces, de esta manera, hemos determinado a qué función queremos llamar antes de que realmente esté definida, de hecho, una declaración directa. En python, el enunciado globals()[function_name]() es el mismo que foo() si function_name = ''foo'' por los motivos mencionados anteriormente, ya que python debe buscar cada función antes de invocarla. Si uno fuera a usar el módulo de tiempo para ver cómo se comparan estas dos declaraciones, tienen exactamente el mismo costo computacional.

Por supuesto, el ejemplo aquí es muy inútil, pero si uno tuviera una estructura compleja que necesitara ejecutar una función, pero debe declararse antes (o estructuralmente tiene poco sentido tenerla después), uno puede simplemente almacenar una cadena y intenta llamar a la función más tarde.


No existe tal cosa en python como declaración avanzada. Solo debe asegurarse de que su función esté declarada antes de que sea necesaria. Tenga en cuenta que el cuerpo de una función no se interpreta hasta que se ejecuta la función.

Considere el siguiente ejemplo:

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.

Puede pensar que un cuerpo de una función es simplemente otra secuencia de comandos que se interpretará una vez que llame a la función.


No puede reenviar-declarar una función en Python. Si tiene la ejecución de la lógica antes de que haya definido las funciones, probablemente tenga un problema de todos modos. Ponga su acción en un if __name__ == ''__main__'' al final de su script (ejecutando una función que nombre "main" si no es trivial) y su código será más modular y podrá usarlo como un módulo si alguna vez lo necesita.

Además, reemplace esa lista de comprensión con un generador expreso (es decir, print "/n".join(str(bla) for bla in sorted(mylist, cmp=cmp_configs)) )

Además, no use cmp , que está en desuso. Use la key y proporcione una función menor que.


No, no creo que haya ninguna forma de reenviar: declarar una función en Python.

Imagina que eres el intérprete de Python. Cuando llegas a la línea

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

o bien sabes qué es cmp_configs o no. Para continuar, debes conocer cmp_configs. No importa si hay recursión.


Sí, podemos verificar esto.

Entrada

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()

Salida

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.

Como BJ Homer mencionó en los comentarios anteriores, Una regla general en Python no es que la función deba definirse más arriba en el código (como en Pascal), sino que debe definirse antes de su uso.

Espero que ayude.


Si inicia su secuencia de comandos a través de lo siguiente:

if __name__=="__main__": main()

entonces probablemente no tenga que preocuparse por cosas como "declaración directa". Verá, el intérprete irá cargando todas sus funciones y luego comenzará su función main (). Por supuesto, asegúrese de tener todas las importaciones correctas también ;-)

Ahora que lo pienso, nunca escuché algo como "declaración directa" en Python ... pero, de nuevo, podría estar equivocado ;-)


Si la llamada a cmp_configs está dentro de su propia definición de función, debería estar bien. Daré un ejemplo.

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 general, poner su código dentro de las funciones (como main ()) resolverá su problema; simplemente llame a main () al final del archivo.


Si no quiere definir una función antes de que se use, y definirla después es imposible, ¿qué hay de definirla en algún otro módulo?

Técnicamente todavía lo defines primero, pero está limpio.

Puede crear una recursión como la siguiente:

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

Las funciones de Python son anónimas al igual que los valores son anónimos, pero pueden vincularse a un nombre.

En el código anterior, foo() no llama a una función con el nombre foo, sino que llama a una función que está vinculada al nombre foo en el punto donde se realiza la llamada. Es posible redefinir foo en otro lugar, y la bar llamaría a la nueva función.

Su problema no se puede resolver porque es como pedir una variable que no ha sido declarada.


Una forma es crear una función de controlador. Defina el controlador desde el principio y coloque el controlador debajo de todos los métodos a los que debe llamar.

Luego, cuando invoque el método del manejador para llamar a sus funciones, siempre estarán disponibles.

El controlador podría tomar un argumento nameOfMethodToCall . Luego usa un montón de instrucciones if para llamar al método correcto.

Esto resolvería tu problema.

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)