Iteradores, generadores, decorador
- iterador
- generador
- Las expresiones generadoras
- cierres
- decorador
iterador
La iteración es una de las características más potentes de Python es una manera de acceder a los elementos de la colección. Iterador puede recordar el objeto es una posición transversal.
Iterador objeto comenzó una visita del primer elemento de la colección hasta que se accede a todos los elementos sesión ha terminado. Iterador sólo se puede mover hacia adelante y no hacia atrás.
La creación de un iterador:
El uso de una clase como una necesidad de implementar dos métodos iterador (clase tiene un constructor, constructor de Python como clase __init__()
, objeto cuando se ejecuta la inicialización.): __iter__()
, Devuelve un iterador propio objeto .
__next__()
Las devoluciones iterador siguiente objeto iteración. Si no hay un siguiente valor puede ser devuelto, se debe lanzar StopIteration
una excepción.
Ejemplo 1: Creación de un iterador digital vuelve al valor inicial 1, aumentando gradualmente 1:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
Ejemplo 2:
class Counter(object):
def __init__(self, low, high):
self.current = low
self.high = high
def __iter__(self):
return self
def __next__(self):
#返回下一个值直到当前值大于 high
if self.current > self.high:
raise StopIteration
else:
self.current += 1
return self.current - 1
>>> c = Counter(5,10)
>>> for i in c:
... print(i, end=' ')
...
5 6 7 8 9 10
Nota: iteradores sólo pueden utilizarse una vez. Una vez lanzado StopIteration
, se seguirá la misma excepción:
>>> c = Counter(5,6)
>>> next(c)
5
>>> next(c)
6
>>> next(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in next
StopIteration
>>> next(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in next
StopIteration
Los iteradores en el bucle, por ejemplo:
>>> iterator = iter(c)
>>> while True:
... try:
... x = iterator.__next__()
... print(x, end=' ')
... except StopIteration as e:
... break
...
5 6 7 8 9 10
El uso de un iterador:
Iterador Hay dos métodos básicos: iter()
e next()
.
Cadenas, listas, tuplas o los objetos se pueden utilizar para crear un iterador:
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
Iterador objeto puede ser utilizado para la declaración poligonal convencional:
#!/usr/bin/python3
list = [1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")
También puede utilizar la función next ():
#!/usr/bin/python3
import sys # 引入 sys 模块
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
while True:
try:
print (next(it))
except StopIteration:
sys.exit()
iterador
En Python, utilizando las yield
funciones se llaman generador (generador).
La diferencia es que con una función ordinaria, el generador es una 返回迭代器
función 只能用于迭代操作
, más fácil de entender el punto 生成器就是一个迭代器。
durante una llamada para el generador en funcionamiento, cada vez que experimenta pausas función de rendimiento y guardar todos los datos de funcionamiento actual 返回 yield 的值
, 并在下一次执行 next() 方法时从当前位置继续运行
.
Llamar a una función de generador, devuelve un objeto iterador.
Ejemplo 1:
>>> def my_generator():
... print("Inside my generator")
... yield 'a'
... yield 'b'
... yield 'c'
...
>>> my_generator()
<generator object my_generator at 0x7fbcfa0a6aa0>
En el ejemplo anterior, utilice la instrucción rendimiento crea un generador simple, que puede ser utilizado en un bucle, al igual que cualquier otro iteradores como:
>>> for char in my_generator():
... print(char)
...
Inside my generator
a
b
c
Ejemplo 2:
>>> def counter_generator(low, high):
... while low <= high:
... yield low
... low += 1
...
>>> for i in counter_generator(5,10):
... print(i, end=' ')
...
5 6 7 8 9 10
En el While
ciclo, cada vez que se ejecute yield
cuando la declaración, y devuelve el valor de la variable de estado de baja a suspender generador. Cuando la siguiente llamada al generador, el generador se reanuda bajo valor variable y luego aumentar desde un lugar antes de la congelación. Generador continúa while
ciclo y una vez más llegó a yield
la declaración ...
Ejemplo 3:
#!/usr/bin/python3
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
# 输出:0 1 1 2 3 5 8 13 21 34 55
Utilizamos generalmente el generador para la evaluación perezosa. Tal generador es una buena manera de utilizar un procesamiento de datos de gran tamaño. Si no desea cargar todos los datos en la memoria, puede utilizar el generador, sólo una parte de los datos se pasan a usted.
os.path.walk()
La función es el ejemplo más típico de esto, se utiliza una función de devolución de llamada y la corriente os.walk
del generador. El uso de generadores de ahorro de memoria.
Podemos utilizar el generador para generar un número infinito de valores, tales como:
>>> def infinite_generator(start=0):
... while True:
... yield start
... start += 1
...
>>> for num in infinite_generator(4):
... print(num, end=' ')
... if num > 20:
... break
...
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Un generador de característica: no son reutilizables.
Las expresiones generadoras
La generación de una lista de expresiones es un tipo de alto rendimiento y la derivación del generador, para promover una mayor eficiencia de la memoria.
Por ejemplo, los intentos de todos los números del 1 al 9 se sumando los cuadrados:
>>> sum([x*x for x in range(1,10)])
Este ejemplo es en realidad la primera creada en la memoria una lista del valor de un cuadrado, y luego caminar a través de la lista, después de la liberación de la memoria de la suma final. Se puede entender el uso de memoria es una gran lista de qué.
Puede ser utilizado para salvar expresión generadora de memoria :
>>> sum(x*x for x in range(1,10))
generador de la gramática siempre se requiere para dirigir la expresión entre corchetes en un par, en ambos lados y no puedo coma. Expresión de uso Ejemplo Los siguientes ejemplos son Constructor válido:
>>> sum(x*x for x in range(1,10))
285
>>> g = (x*x for x in range(1,10))
>>> g
<generator object <genexpr> at 0x7fc559516b90>
Podemos generador y las expresiones generadoras vinculado, en el siguiente ejemplo vamos a leer el archivo '/var/log/cron'
y ver cualquier tarea determinada (por ejemplo buscamos 'anacron'
) ejecutar correctamente.
Podemos utilizar el shell
comando tail -f /etc/crontab |grep anacron
a hacer lo mismo (de acuerdo con Ctrl + C
terminar la ejecución de comandos).
>>> jobtext = 'anacron'
>>> all = (line for line in open('/etc/crontab', 'r') )
>>> job = ( line for line in all if line.find(jobtext) != -1)
>>> text = next(job)
>>> text
'25 6\t* * *\troot\ttest -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )\n'
>>> text = next(job)
>>> text
'47 6\t* * 7\troot\ttest -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )\n'
>>> text = next(job)
>>> text
'52 6\t1 * *\troot\ttest -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )\n'
cierres
Cierre (cierres) es una función devuelve una función por otro . Utilizamos los cierres para eliminar código duplicado. En el siguiente ejemplo, hemos creado un cierre simple de la suma digital.
>>> def add_number(num):
... def adder(number):
... #adder 是一个闭包
... return num + number
... return adder
...
>>> a_10 = add_number(10)
>>> a_10(21)
31
>>> a_10(34)
44
>>> a_5 = add_number(5)
>>> a_5(3)
8
decorador
Decorador (decoradores) algunos objetos que se utilizan para añadir dinámicamente un nuevo comportamiento, hemos utilizado los cierres es el mismo.
Crear un ejemplo sencillo, para imprimir algunas declaraciones antes y después de la ejecución de la función:
>>> def my_decorator(func):
... def wrapper(*args, **kwargs):
... print("Before call")
... result = func(*args, **kwargs)
... print("After call")
... return result
... return wrapper
...
>>> @my_decorator
... def add(a, b):
... #我们的求和函数
... return a + b
...
>>> add(1, 3)
Before call
After call
4