Un artículo para resolver el problema de la programación funcional con cierres de Python

Programación funcional

concepto de programación funcional podemos más o menos hemos oído, acabamos de escuchar cuando el sueño desconocido Li, creo que esto es un concepto muy oscuro de la ciencia y la tecnología. Pero, de hecho, su significado es muy simple, pero que se extiende a muchos ricos uso.

En el lenguaje de programación temprana, no un montón de tiempo, vamos a lenguaje en  lenguaje de alto nivel con el lenguaje de bajo nivel  . Tales como el lenguaje ensamblador, es el lenguaje de bajo nivel, casi cualquier paquete ni tenemos necesidad de un operador de asignación para el registro de llamadas manualmente. Y a partir de estas instrucciones en lenguaje de alto nivel del ámbito industrial, que extricates a favor de proceso orientado u objeto. En otras palabras escribimos código para algunos de ellos es un cálculo de ordenador o abstraído de objetos. Si usted ha estudiado orientado a objetos, y encontrará que en comparación con orientado al proceso, orientado a objetos más altos cierto nivel de abstracción, hizo un paquete más completo.

Después orientada a objetos la que, podemos hacer la encapsulación y la abstracción de la misma? Este giro de la programación funcional.

Función que todos sabemos, es un programa que definimos, sus entradas y salidas se determinan. Escribimos algunas funciones que pueden ser llamadas desde cualquier lugar. Dado que la función tan fácil de usar, se puede  poner en función también devuelve un parámetro variable y pasar a  él?

OK, esto es la mayoría de las funciones intuitivas y funcionales de programación. En otras palabras escribimos alguna función también se puede utilizar como una variable, ambos pueden ser utilizados para asignar, transferir también se puede utilizar, y pueden ser devueltos. Como resultado de ello, facilita en gran medida nuestro código, pero esto no es por el bien, por el contrario, trae un montón de problemas, el problema más intuitiva se debe a la función de los parámetros también se pueden pasar a otra función, que puede  conducir a la función cálculos se vuelven tan incierto  , muchos más allá de nuestras expectativas de lo que puede suceder.

Por lo tanto la programación funcional son las ventajas y desventajas, y realmente simplifica muchas cuestiones, pero ha creado muchos problemas nuevos, tenemos que tener cuidado en el proceso utilizado.

la función de retorno entrante,

Antes de presentar el filtro, mapa, reducir y personalizada de clasificación, cuando en realidad se ha utilizado el concepto de programación funcional.

Por ejemplo, cuando llamamos solucionado más o menos, si se pasa un array de objetos, esperamos que hemos desarrollado sobre la base del tipo de campo, esta vez a menudo necesitamos pasar una  función anónima  , que se utiliza para desarrollar el tipo de campo. De hecho, la función anónima entrante, de hecho, es la programación funcional refleja más intuitiva:

sorted(kids, key=lambda x: x['score'])

Además, también podemos devolver una función, por ejemplo, nos fijamos en un ejemplo:

def delay_sum(nums):
    def sum():
        s = 0
        for i in nums:
            s += i
        return s
    return sum

Si este tiempo que llamamos delay_sum pasar una cadena de números, ¿qué obtenemos?

La respuesta es una función, podemos dirigir la salida, visto desde la información en esta impresión:

>>> delay_sum([1, 3, 4, 2])
<function delay_sum.<locals>.sum at 0x1018659e0>

Queremos obtener el resultado de la operación debe ser cómo hacerlo? También es muy sencilla, se utiliza una variable para recibirlo, a continuación, puede ejecutar esta nueva variable:

>>> f = delay_sum([1, 3, 4, 2])
>>> f()
10

Esto tiene la ventaja de que podemos  retrasar el cálculo  , si no se utiliza la programación funcional, entonces necesitamos al llamar delay_sum esta función para calcular los resultados. Si esta operación es muy pequeña Afortunadamente, si esta operación es lo suficientemente grande, hará que por encima. , Probablemente hasta altas horas de la noche y se utilizará cuando calculamos los resultados, los resultados no pueden ser utilizados inmediatamente. Siendo ese el caso, volvemos a una función en lugar de la operación, cuando la necesidad real de utilizar más tarde los resultados, operaciones retrasando así. Esta es también una gran cantidad de ideas comunes plataforma de computación, tales como  la chispa  .

cierres

Echemos un vistazo en el ejemplo que acabamos de citar, en función de delay_sum sólo entre nuestra interna lograr una función suma, que llamamos parámetros de la función delay_sum pasaron en esta función que. Este tipo de  alcance exteriores  variables se hace referencia por una función llamada internos  cierres  .

De hecho, este concepto es la imagen, porque estos datos llamada a una función interna para la persona que llama está cerrada, por completo un cuadro negro, a menos que ver el código fuente, de lo contrario no sabemos el origen de la misma entre los datos. Además de no conocer el origen, es más importante es que es una variable de referencia fuera de la función, ya que es la variable de la nota es dinámico. Que nos  podemos cambiar el efecto del cierre de la operación cambiando el valor de algunas variables externas  .

Esto es un poco difícil de pronunciar, nos fijamos en un ejemplo sencillo. En Python tiene una función llamada Math.pow que en realidad es el poder de computación. Por ejemplo, queremos calcular el cuadrado de x, entonces debemos escribir:

math.pow(x, 2)

Pero si el escenario actual sólo tenemos que calcular el cuadrado, cada vez que tenemos un pase y luego pasar el extra 2 se verá muy molesto, esta vez utilizamos un cierre, se puede simplificar las operaciones:

def mypow(num):
    def pw(x):
        return math.pow(x, num)
    return pw
    
pow2 = mypow(2)
print(pow2(10))

Por el cierre, nos  ponemos una segunda variable a fijo  , sólo necesitaremos utilizar el original se puede lograr Math.pow pow2 (x, 2) la función. Si tenemos que cambiar de repente la demanda de potencia de cálculo 3 o 4 el poder, sólo tenemos que modificar los parámetros de entrada PTPA puede, sin necesidad de modificar el código.

De hecho, este es el mayor cierre de escenarios de uso, podemos  a través del cierre logra algunas características muy flexibles  , así como la modificación de algunas de las funciones que se activan por la configuración sin la necesidad de escribir el código de los muertos. Conocer para la industria, la línea de código no se podía cambiar, sobre todo el cliente, tales como tienda de Apple o Android, entre un almacén de paquetes, sólo el usuario que actualice manualmente tirará. Si se produce un problema, y casi no hay manera de modificar el usuario manualmente las actualizaciones sólo se puede esperar. Por lo tanto, el funcionamiento normal es utilizar alguna función de cierre flexible similar,  cambiar la lógica del código mediante la modificación del modo de configuración  .

Además, hay un cierre que se puede utilizar  la variable de entorno de tiempo de ejecución o temporal  .

Por ejemplo, nos fijamos en el siguiente código:

def step(x=0):
    x += 5
    return x

Esto no es una función de la utilización de dispositivos de cierre, no importa cuántas veces lo llamamos, la respuesta es 5, x + = ejecutar el resultado después de 5 y no se guardarán cuando la función regresa, será el escenario abandonaron este valor . ¿Qué pasa si  quiero llamar cada vez que los resultados se basan en la última llamada  , lo que significa que cada vez que modifican la acción se puede guardar, en lugar de descartarlo?

Esta vez tiene que utilizar el cierre:

def test(x=0):
    def step():
        nonlocal x
        x += 5
        return x
    return step
    
t = test()
t()
>>> 5
t()
>>> 10

Ese es nuestro valor de x está guardada,  cada modificación será acumulativa  , en lugar de desechado. Cabe señalar que usamos una nueva palabra clave se llama  no local  , que es único entre las palabras clave python3 utilizados para declarar la variable actual X no es una variable local, lo que Python intérprete irá a ellos para encontrar esta una variable global x, de modo que el método de ensayo asociado que se puede pasar en el parámetro x. funcionarios python2 no han actualizado, no se recomienda.

Como Python todo es un objeto que es, si nosotros  funcionamos como el cierre de la capa externa es una clase  si, cierres de datos y la diferencia de clases no es grande, incluso podemos devolver el paquete a la función de cierre de la función de correlación, por lo casi un objeto de. Mira un ejemplo:

def student():
    name = 'xiaoming'
    
    def stu():
        return name
        
    def set_name(value):
        nonlocal name
        name = value
        
    stu.set_name = set_name
    return stu
    
stu = student()
stu.set_name('xiaohong')
print(stu())

Última operación es Xiaohong, debido a que llamamos el cambio nombre_conjunto el valor de la parte exterior de cierre. Que así sea, pero en circunstancias normales no podríamos usarlo. Y escribir una clase de comparación por medio del cierre de  la velocidad de operación será más rápido . Razón de más sutil, porque ninguno de cierre puntero del auto, lo que ahorra una gran cantidad de variables de acceso y operación, por lo que el cálculo de algunos más rápido. Pero los cierres se involucran en fuera de pseudo objeto es  no utilizar la herencia, derivados  métodos, pero también fuera de tono y el uso normal, por lo que sabemos no es el método a tal puede ser una realidad y no ser utilizado.

el cierre de minas

Aunque el cierre fácil de usar, pero no se tiene cuidado, es muy fácil de paso en el hoyo, aquí están algunos fosa común.

Los cierres no pueden acceder directamente a las variables externas

Esto es algo que ya hemos mencionado, el cierre de las que  no podemos acceder directamente a las variables externas  deben ser etiquetados por palabra clave no local, de lo contrario es se quejan.

def test():
    n = 0
    def t():
        n += 5
        return n
    return t

Por ejemplo, este es el caso, será de error:

variable de bucle de cierre que no se puede utilizar

Los cierres tienen un gran problema es  que no se puede utilizar una variable de bucle  , pozo profundo oculto, simplemente porque desde un punto de vista lógico es que el código no se puede encontrar. Es decir, lógicamente, no hay código de problema, cuando es ejecutado tienden para nuestra sorpresa, que tenemos que tener un profundo conocimiento de los principios subyacentes se pueden encontrar, por ejemplo, nos fijamos en un ejemplo:

def test(x):
    fs = []
    for i in range(3):
        def f():
            return x + i
        fs.append(f)
    return fs


fs = test(3)
for f in fs:
    print(f())

En el ejemplo anterior ellos, utilizamos un bucle for para crear tres cierres, utilizamos tres fs tienda de cierres y de retorno. Luego llamamos a la prueba, para obtener los tres cierres, y luego fuimos llamados.

Esta lógica no parece ser un problema, de acuerdo con la razón, estos tres cierres es creado por un bucle, y en el que se utilizó la variable de bucle de cierre i. Que de acuerdo con nuestras ideas, el resultado de la salida final debe ser [3, 4, 5], pero, por desgracia, obtenemos la final  resultado es [5, 5, 5]  .

Parece extraño, y que no era sorprendente, porque  la variable de bucle i no está en la creación de cierre cuando se puso buena  . Pero cuando llevamos a cabo el cierre, vamos en busca de los valores correspondientes de i, obviamente, cuando corremos el cierre, el ciclo se ha ejecutado más, esta vez me detuve en la 2. Por lo tanto, los resultados de estos tres cierre es 2 + 3 es 5. El foso es un intérprete de Python para la lógica que llevó al cierre de la ejecución de la lógica de escritura que es correcto, pero no se sigue de nuestra lógica, por lo que debe tener cuidado, si se le olvida, que desea pasar Descubre será difícil de depurar.

resumen

Aunque en la superficie hay algunos problemas y el cierre de pozos, pero sigue siendo nuestras  características avanzadas de Python utilizados comúnmente  , y también es la base para muchos otros usos de alto. Así aprendemos a entender y cierres es muy necesario, no lo hacen indigno.

De hecho, no sólo el cierre, muchas de las características son más o menos altamente abstracto tienen este tipo de problemas. Porque cuando abstracto, que por supuesto simplifica el código, mayor flexibilidad, pero al mismo tiempo también crea  la curva de aprendizaje se hace más pronunciada  , con lo que más tenemos que entender y recordar el contenido. También es una solución de compromiso, funciones fáciles de utilizar en la naturaleza del código obligados a pagar, fácil de usar y, a menudo significa más rígida inflexible. Para este problema, tenemos que mantener el estado de ánimo, pero las noticias buenas a primera vista cuando

Publicados 151 artículos originales · ganado elogios 4 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_46089319/article/details/105364151
Recomendado
Clasificación