Notas de estudio de Python: funciones avanzadas

Tutorial de Python: sitio web oficial de Liao Xuefeng

Variables y funciones

Las variables pueden apuntar a funciones:

abs # 这个变量其实是 abs()
print(type(abs))

<clase 'función_de_builtin_or_metodo'>

Por lo tanto, el nombre de la función se puede pasar como un parámetro , como la definición de una función computed(x, y, f), de modo que x, ycomo el parámetro para llamar a funa función de los puntos variables.

  • El objeto de función tiene un __name__atributo, puede obtener el nombre de la función
def computed(x, y, f):
    return f(x) + f(y)

print(computed(-2, -8, abs)) # 计算-2、-8的绝对值之和

10

Por ejemplo computed(), una función que toma una función variable, llamadas funciones de orden superior.

Función de orden superior

map() Función de orden superior

Se crea una función para asociarse con todos los elementos de un objeto iterable y se devuelve como un Iterator( iterador ), a la espera de ser ejecutado.

  • Esta función no se ejecuta en este momento y la función se ejecuta solo cuando se itera el iterador.
result = map(abs, [-1, -2, 3]) # 得到 <class 'map'> 对象
print(list(result)) # 转为列表

[1, 2, 3]

  • resultEs un objeto inerte , que utiliza list()valores calculados y convierte toda la lista.

reduce() Función de orden superior

Aplica una función a todos los elementos de un objeto iterable, esta función necesita recibir dos parámetros y reduce()se ejecutará así: tomar el resultado obtenido al ejecutar los dos elementos, y sustituir el siguiente elemento como parámetro para continuar la ejecución. Obtenga el resultado y continúe sustituyendo el siguiente elemento para la ejecución hasta el final.

  • La función se ha ejecutado en este punto.

Por ejemplo, combine una secuencia para formar un número:

from functools import reduce # 需要导入模块
def fn(x, y):
    return x *  10  + y

r = reduce(fn, [1, 2, 3])
print(r)

123

map()Y reduce()ejemplos de uso: la cadena en digital

from functools import reduce

DIGITS = {
    
    '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def char2num(s):
    return DIGITS[s]

def str2int(s):
    return reduce(lambda x, y: x * 10 + y, map(char2num, s))

filter() Función de orden superior

Y map()similar, pero filter()es una función para crear un enlace que se usa para filtrar elementos, de acuerdo con el valor booleano que devuelve la función para elegir si retener elementos. Devuelve un objeto iterador.

  • Devuelve un objeto perezoso, no ejecutado
# 判断一个数字反过来还是不是它
def is_palindrome(n):
    temp = n
    m =  0
    while temp >  0: # 有大于十位数的位数存在
        m = m *  10  + temp %  10  # 取个位数;下一次循环时,将个位数升级,
        temp = temp //  10  # 得到个位数以上的数字
    return n == m

print(list(filter(is_palindrome, range(1, 100)))) # 打印1~99的回数

sorted() Función de orden superior

sorted(lista)Sirve para ordenar una lista, y también puede pasar parámetros de palabras clave key. Es una función que puede ordenar la lista de elementos después de aplicar la función .

  • Por ejemplo sorted(lista, key=abs), ordena la lista según el tamaño absoluto
  • Python usa los elementos abs(), y luego obtiene el valor absoluto, interno procede de acuerdo al orden original, pero cuando este tipo de elemento, ver es el uso del abs()elemento posterior.
  • Esta función debe devolver un valor para que Python lo ordene.

La clasificación original de la lista de cadenas se basa en el código ASCII:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']

Utilice keyparámetros, haciendo que se ignore el caso al realizar el pedido:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
# 排序看的是:'bob', 'about', 'zoo', 'credit'
['about', 'bob', 'Credit', 'Zoo']

En orden inverso, puede pasar el tercer parámetro reverse=True:

>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
  • Por lo tanto, podemos escribir una función para pasar, como ordenar una lista de tuplas:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
    return t[0] # 返回名字,让 Python 内部根据名字排序

L2 = sorted(L, key=by_name)
# 按照 'Bob', 'Adam', 'Bart', 'Lisa' 进行排序
print(L2)

Función de retorno

Las funciones de orden superior pueden recibir funciones como variables o devolver funciones como valores de retorno.

def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

f = lazy_sum(1, 3, 5, 7, 9)
# 它是:<function lazy_sum.<locals>.sum at 0x101c6ed90>,是一个函数
f() # 执行函数
  • Aquí la sum()función puede acceder al exterior args, y cuando la lazy_sumfunción de retorno sum, los parámetros y las variables se almacenan en la función devuelta , esto se llama "cierre (el cierre)", la estructura del programa tiene un gran poder.
  • Cada llamada lazy_sum()devuelve una nueva función, incluso si el mismo argumento para ellos no es ==el (por no decir que los resultados operativos varían, es decir, función de rango)
  • sum()Variable de función interna función de la variable de referencia externa llamada libre
    • Las variables libres a las que se hace referencia en el cierre solo están relacionadas con el cierre específico, y las variables libres a las que hace referencia cada instancia del cierre no interfieren entre sí.
    • Las modificaciones de una instancia de cierre a sus variables libres se pasarán a la siguiente invocación de la instancia de cierre.
  • Trampa de cierre:
def my_func(*args):
    fs = []
    for i in range(03):
        def func():
            return i * i
        fs.append(func)
    return fs

fs1, fs2, fs3 = my_func()
print fs1()
print fs2()
print fs3()

El resultado del programa no es el resultado 0, 1, 4 que imaginamos. El resultado real son los 4.
Porque no returnfunción de retorno , ijusto fuera de una función de una variable común (no una función del cierre de variables libres), antes de que la función de retorno ise haya asignado a un 2, y returndespués de que ise convierta en variables libres. Ya son 2 en este momento.

  • Nota : No se refiera a ninguna función que devuelva la variable de ciclo , o el seguimiento cambiará las variables (en el returnfrente).
def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs

Ejemplo de cierre:

# 返回一个计数器函数,每次调用它返回递增整数,多个计数器函数之间互不干扰
def createCounter():
    n = 0
    def counter():
        nonlocal n
        n += 1
        return n
    return counter
  • En otras palabras, un cierre es devolver una función, que posee independientemente la instancia de variable de la función externa. (Similar a un objeto pequeño)

Decorador

En la fase de ejecución del código, agregue dinámicamente funciones a una función existente. Esta función puede seleccionarse mediante muchas funciones. (Modo decorador de Java)

  • Es esencialmente una función de orden superior que devuelve una función.

En el patrón de diseño orientado a objetos (OOP), el decorador se denomina patrón de decoración. El modo de decoración de OOP debe implementarse a través de la herencia y la combinación.Además del decorador que admite OOP, Python directamente admite decoradores desde el nivel de sintaxis. El decorador de Python se puede implementar con funciones o clases.

Esa now()función agrega la función de registro de impresión log()como ejemplo:

  1. Agregue antes de la función original @log:
@log
def now():
    print("2020-11-23")

Esta sintaxis es equivalente a:now = log(now)

  • La primitiva se convierte en función decoradora de ejecución , es una función del reemplazo de la variable , función decoradora posterior para devolver una función.
  1. En now()función de las funciones de escritura anteriores , decorador definido:
def log(func): # func 为 now 函数!
    def wrapper(*args, **kw): # *args, **kw 接收任意类型的参数
        print(f'call {func.__name__}():')
        return func(*args, **kw)
    return wrapper

La función del decorador es devolver una función, por lo que debe definir una función para devolverla internamente.
Imprimir registro antes de llamar: complete la función que necesitamos agregar en esta función interna, y luego llame a la función original cuando regrese func.


Si la función decoradora necesita pasar parámetros, necesita anidar una función de orden superior que devuelva un decorador (también se pueden usar otros nombres):

# 装饰器函数
def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print(f'{text} {func.__name__}():')
            return func(*args, **kw)
        return wrapper
    return decorator

# 原函数
@log('execute')
def now():
    print('2020-11-23')

Importante : Para comprender @log('execute')el equivalente de:

now = log('execute')(now)
  • Primera ejecución log('execute'), la ejecución log()devuelve decorator()una función, luego la (now)llamada de argumentos decorator()devuelve wrapper()una función.
  • Intuitivamente, los dos paréntesis ejecutan dos funciones de afuera hacia adentro.

Después de completar la función decorativa, debido a que estamos @en la sintaxis de esta función para realizar nuestra función decorativa , y luego llamamos a la función original en nuestra función decoradora en, now = log(now)se ha asignado, __name__se convierte en wrapper:

  • Funcionalmente, se han cumplido los requisitos, pero algunas ejecuciones de código que dependen de firmas de funciones fallarán.
  • import functoolsEn la definición del wrapper()complemento:@functools.wraps(func)
  • Este código es equivalente a ejecutar :, wrapper.__name__ = func.__name__por lo que es perfecto

Función parcial

En el área local, establezca el valor predeterminado para la función.
int(x, base=10): La cadena a un número, basemodificando la banda digital puede.
Por ejemplo, necesitamos convertir muchos dígitos binarios, cada configuración de tiempo basees muy inconveniente:

import functools
# 创建函数变量int2,赋值为:【默认的参数base设置为2】的int函数 
int2 = functools.partial(int, base=2)
print(int2('1000000')) #输出: 64
  • Los parámetros aquí: el primero es la función a configurar, y el último será sustituido como los parámetros de la función (siga las reglas de las funciones de llamada ordinarias)
    • Si no se utiliza ningún parámetro de palabra clave, entonces es un parámetro posicional

parcial británico [ˈpɑːʃl] estadounidense [ˈpɑːrʃl] adj. parcial; parcial; injusto

Supongo que te gusta

Origin blog.csdn.net/zsq8187/article/details/110003643
Recomendado
Clasificación