@Pythonetc compilación, octubre de 2019


Una nueva selección de consejos y programación de Python de mi feed @pythonetc.

Colecciones anteriores


Si desea iterar varios objetos iterables a la vez, puede usar la función zip (no tiene nada que ver con el formato de archivo ZIP):

 from datetime import timedelta names = [ 'Eleven. Return and Revert', 'Wilderness', 'The Menagerie Inside', 'Evaporate', ] years = [ 2010, 2013, 2015, 2018, ] durations = [ timedelta(minutes=57, seconds=38), timedelta(minutes=48, seconds=5), timedelta(minutes=46, seconds=34), timedelta(minutes=43, seconds=25), ] print('Midas Fall LPs:') for name, year, duration in zip( names, years, durations ): print(f' * {name} ({year}) — {duration}') 

Resultado:

 Midas Fall LPs: * Eleven. Return and Revert (2010) — 0:57:38 * Wilderness (2013) — 0:48:05 * The Menagerie Inside (2015) — 0:46:34 * Evaporate (2018) — 0:43:25 


Puede detener el generador llamando explícitamente a g.close() , pero la mayoría de las veces, el recolector de basura lo hace por usted. Después de llamar al close , en el punto donde se pausó la función de generación, GeneratorExit inicia GeneratorExit :

 def gen(): try: yield 1 yield 2 finally: print('END') g = gen() print(next(g)) # prints '1' g.close() # prints 'END' 

No te olvides de tres aspectos. Primero, no puede continuar generando valores mientras procesa GeneratorExit :

 def gen(): try: yield 1 finally: yield 3 g = gen() next(g) g.close() # RuntimeError 

En segundo lugar, si el generador aún no se está ejecutando, la excepción no se lanzará, pero el generador seguirá en el estado "detenido":

 def gen(): try: yield 1 finally: print('END') g = gen() g.close() # nothing print(list(g)) # prints '[]' 

En tercer lugar, close no hace nada si el generador ya ha terminado de funcionar:

 def gen(): try: yield 1 yield 2 finally: print('END') g = gen() print(list(g)) print('Closing now') g.close() # END # [1, 2] # Closing now 


Las líneas f le permiten especificar el ancho del valor mostrado, así como otros especificadores de formato:

 >>> x = 42 >>> f'{x:5}+{x:15f}' ' 42+ 42.000000' 

También pueden contener expresiones calculadas, lo cual es útil cuando el ancho no se conoce de antemano:

 def print_table(matrix): cols_width = [ max(len(str(row[col])) for row in matrix) for col in range(len(matrix[0])) ] for row in matrix: for i, cell in enumerate(row): print( f'{cell:{cols_width[i]}} ', end='' ) print() albums = [ ['Eleven. Return and Revert', 2010], ['Wilderness', 2013], ['The Menagerie Inside', 2015], ['Evaporate', 2018], ] print_table(albums) 

Resultado:

 Eleven. Return and Revert 2010 Wilderness 2013 The Menagerie Inside 2015 Evaporate 2018 


Si su clase se deriva de otra, entonces la metaclase de su clase también debe derivarse de la metaclase de esa clase:

 from collections import UserDict from abc import ABCMeta # ABCMeta is a metaclass of UserDict class MyDictMeta(ABCMeta): def __new__(cls, name, bases, dct): return super().__new__(cls, name, bases, dct) class MyDict(UserDict, metaclass=MyDictMeta): pass 

Puede ser aconsejable obtener automáticamente la metaclase de esta otra clase:

 def create_my_dict_class(parents): class MyDictMeta(*[type(c) for c in parents]): def __new__(cls, name, bases, dct): return super().__new__(cls, name, bases, dct) class MyDict(*parents, metaclass=MyDictMeta): pass MyDict = create_my_dict_class((UserDict,)) 


__init__ permite modificar un objeto inmediatamente después de su creación. Si desea controlar lo que se creó, use __new__ :

 from typing import Tuple, Dict from cached_property import cached_property class Numbers: _LOADED: Dict[Tuple[int, ...], 'Numbers'] = {} def __new__(cls, ints: Tuple[int, ...]): if ints not in cls._LOADED: obj = super().__new__(cls) cls._LOADED[ints] = obj return cls._LOADED[ints] def __init__(self, ints: Tuple[int, ...]): self._ints = ints @cached_property def biggest(self): print('calculating...') return max(self._ints) print(Numbers((4, 3, 5)).biggest) print(Numbers((4, 3, 5)).biggest) print(Numbers((4, 3, 6)).biggest) 

Source: https://habr.com/ru/post/475684/


All Articles