Pregunta

esto es a partir del código fuente de csv2rec en matplotlib

¿cómo puede esta función de trabajo, si sus únicos parámetros son 'func, por defecto'?

def with_default_value(func, default):
    def newfunc(name, val):
        if ismissing(name, val):
            return default
        else:
            return func(val)
    return newfunc

IsMissing toma un nombre y un valor y determina si la fila debe ser enmascarada en una matriz numpy.

func o bien será str, int, float, o dateparser ... que convierte los datos. Tal vez no es importante. Me pregunto cómo se puede conseguir un 'nombre' y 'valor'

Soy un principiante. Gracias por cualquier 2cents! Espero llegar lo suficientemente bueno para ayudar a los demás!

¿Fue útil?

Solución

Esta función with_default_value es lo que se refiere a menudo (imprecisa) como "un cierre" (técnicamente, el cierre es más bien el interior de función que es retornada, aquí newfunc - véase, por ejemplo aquí ). Más genéricamente, with_default_value es un función de orden superior ( "HOF."): Se toma una función (func) como un argumento, sino que también devuelve una función (newfunc) como el resultado

He visto respuestas confusas esto con el decorador concepto y construyo en Python, que es definitivamente no el caso - especialmente desde que mencionas func tan a menudo ser una incorporada como int. Decoradores son también funciones de orden superior, pero los más específicos: los que devuelven un decorado, es decir, "enriquecido", versión de su argumento de la función (que debe ser el solamente argumento - "decoradores con argumentos" se obtienen a través de un nivel más de anidación de la función / cierre, no , dando al decorador HOF más de un argumento), que se reasigna a exactamente el mismo nombre que el argumento de la función (y por lo general tiene la misma firma -. usando un decorador de lo contrario sería muy peculiar, un-idiomática, ilegibles, etc)

Así se olvide decoradores, que no tienen absolutamente nada que ver con el caso, y se centran en el cierre newfunc. Una función léxico anidado puede referirse a (aunque no vuelva a enlazar) todos los nombres de variables locales (incluyendo nombres de argumentos, ya que los argumentos son variables locales) de la función (s) que encierra - por eso se le conoce como un cierre: se "cerró sobre" éstos "variables libres". Aquí, newfunc puede referirse a func y default -. Y lo hace

funciones de orden superior son una cosa muy natural en Python, sobre todo porque las funciones son objetos de primera clase (por lo que no hay nada especial que tiene que hacer para pasarlos como argumentos, las devolverá lo valores de la función, o incluso almacenarlos en las listas u otros recipientes, etc.), y no hay distinción espacio de nombres entre las funciones y otros tipos de objetos, ninguna llamada automática de funciones simplemente porque se mencionan, etc, etc. (es más difícil - un poco más difícil, o mucho más difícil, dependiendo - en otros idiomas que no hacen un sorteo de distinciones de este tipo). En Python, mencionando una función es sólo eso - una mención; la llamada sólo ocurre si y cuando el objeto de función (denominado por su nombre, o de otro modo) es seguido por paréntesis.

Eso es todo lo que hay a este ejemplo - por favor no dude en corregir su pregunta, comentar aquí, etc, si hay algún otro aspecto específico que usted permanece en duda sobre

Editar : por lo que la OP ha comentado cortésmente pidiendo más ejemplos de "fábricas de cierre". Aquí hay uno - imaginar alguna clase abstracta de herramientas GUI, y que está tratando de hacer:

for i in range(len(buttons)):
  buttons[i].onclick(lambda: mainwin.settitle("button %d click!" % i))

pero esto no funciona bien - i dentro del lambda es enlazada en tiempo, de manera que cuando se hace clic en un botón de valor i siempre va a ser el índice del último botón , no importa que uno hizo clic. Hay varias soluciones factibles, pero una fábrica de cierre es una posibilidad elegante:

def makeOnclick(message):
  return lambda: mainwin.settitle(message)

for i in range(len(buttons)):
  buttons[i].onclick(makeOnClick("button %d click!" % i))

En este caso, estamos utilizando la fábrica de cierre para ajustar el tiempo de unión de las variables -). En una forma específica u otra, se trata de un caso de uso muy común para las fábricas de cierre

Otros consejos

Este es un decorador de Python - básicamente un envoltorio función. (Lea todo sobre decoradores en PEP 318 - http://www.python.org / dev / PEP / PEP-0318 / )

Si se mira a través del código, es probable que encontrar algo como esto:

def some_func(name, val):
    # ...
some_func = with_default_value(some_func, 'the_default_value')

La intención de este decorador parece proporcionar un valor por defecto si el nombre o val argumentos faltan (es de suponer, si se establecen en Ninguno).

En cuanto a por qué funciona:

with_default_value devuelve un objeto función, que es básicamente va a ser un copia de ese newfunc anidada, con el 'func' Call y el valor por defecto substited con lo que se pasó a with_default_value.

Si alguien hace 'foo = with_default_value (bar, 3)', el valor de retorno es básicamente va a ser una función nueva:

def foo(name, val):
    ifismissing(name, val):
        return 3
    else:
        return bar(val)

por lo que puede tomar ese valor de retorno, y lo llaman.

Esta es una función que devuelve otra función. name y value son los parámetros de la función de regresar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top