procedimientos lista funciones python arguments

lista - funciones y procedimientos en python



¿Por qué Python permite llamadas a funciones con un número incorrecto de argumentos? (2)

Python no puede saber por adelantado a qué objeto terminará llamando, porque siendo dinámico, puede intercambiar el objeto de función . En cualquier momento. Y cada uno de estos objetos puede tener un número diferente de argumentos.

Aquí hay un ejemplo extremo:

import random def foo(): pass def bar(arg1): pass def baz(arg1, arg2): pass the_function = random.choice([foo, bar, baz]) print(the_function())

El código anterior tiene una probabilidad de 2 en 3 de generar una excepción. ¡Pero Python no puede saber a priori si ese será el caso o no!

Y ni siquiera he comenzado con las importaciones de módulos dinámicos, la generación dinámica de funciones, otros objetos invocables (se puede llamar a cualquier objeto con un método __call__ ) o argumentos **kwargs ( *args y **kwargs ).

Pero para dejar esto más claro, usted declara en su pregunta:

No va a cambiar mientras se ejecuta el programa.

Este no es el caso, no en Python, una vez que se carga el módulo, puede eliminar, agregar o reemplazar cualquier objeto en el espacio de nombres del módulo, incluidos los objetos de función.

Python es mi primer lenguaje dinámico. Recientemente codifiqué una llamada de función que proporciona incorrectamente un número incorrecto de argumentos. Esto falló con una excepción en el momento en que se llamó a la función. Esperaba que incluso en un lenguaje dinámico, este tipo de error se pueda detectar cuando se analiza el archivo fuente.

Entiendo que el tipo de argumentos reales no se conoce hasta que se llama a la función, porque la misma variable puede contener valores de cualquier tipo en diferentes momentos. Pero el número de argumentos se conoce tan pronto como se analiza el archivo fuente. No va a cambiar mientras se ejecuta el programa.

Para que esta no sea una pregunta filosófica

Para mantener esto dentro del alcance de Stack Overflow, déjame formular la pregunta de esta manera. ¿Hay alguna característica, que ofrece Python, que requiera que demore la comprobación de la cantidad de argumentos en una llamada de función hasta que el código se ejecute realmente?


Se conoce el número de argumentos que se pasan, pero no la función que realmente se llama. Ver este ejemplo:

def foo(): print("I take no arguments.") def bar(): print("I call foo") foo()

Esto puede parecer obvio, pero pongamos esto en un archivo llamado "fubar.py". Ahora, en una sesión interactiva de Python, haga esto:

>>> import fubar >>> fubar.foo() I take no arguments. >>> fubar.bar() I call foo I take no arguments.

Eso fue obvio. Ahora viene la parte divertida. Definiremos una función que requiere una cantidad distinta de argumentos:

>>> def notfoo(a): ... print("I take arguments!") ...

Ahora hacemos algo que se llama parche de mono . De hecho, podemos reemplazar la función foo en el módulo fubar :

>>> fubar.foo = notfoo

Ahora, cuando llamamos a la bar , se generará un TypeError ; el nombre foo ahora se refiere a la función que definimos anteriormente en lugar de la función original anteriormente conocida como foo .

>>> fubar.bar() I call foo Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/horazont/tmp/fubar.py", line 6, in bar foo() TypeError: notfoo() missing 1 required positional argument: ''a''

Entonces, incluso en una situación como esta, donde podría parecer muy obvio que la función llamada foo no toma argumentos, Python solo puede saber que en realidad es la función foo que se llama cuando ejecuta esa línea de origen.

Esta es una propiedad de Python que lo hace poderoso, pero también causa algo de su lentitud. De hecho, hace tiempo que se discutió la creación de módulos de solo lectura para mejorar el rendimiento en la lista de correo de python-ideas, pero no obtuvo ningún apoyo real.