@Pythonetc-Zusammenstellung, Oktober 2019


Eine neue Auswahl von Python-Tipps und -Programmierungen aus meinem @ pythonetc-Feed.

Frühere Kollektionen


Wenn Sie mehrere iterierbare Objekte gleichzeitig durchlaufen möchten, können Sie die zip Funktion verwenden (sie hat nichts mit dem ZIP-Dateiformat zu tun):

 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}') 

Ergebnis:

 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 


Sie können den Generator stoppen, indem Sie explizit g.close() aufrufen. g.close() der Garbage Collector dies für Sie. Nach dem Aufruf von close wird GeneratorExit an dem Punkt gestartet, an dem die Generierungsfunktion angehalten wurde:

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

Nicht über die drei Aspekte vergessen. Erstens können Sie während der Verarbeitung von GeneratorExit keine weiteren Werte generieren:

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

Zweitens, wenn der Generator nicht läuft, wird die Ausnahme nicht geworfen, aber der Generator geht immer noch in einen Zustand „Stopped“:

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

Drittens macht close nichts, wenn der Generator bereits fertig ist:

 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 


f-Leitungen ermöglichen, die Breite der Ausgangswerte und andere Formatierungsbezeich einzustellen:

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

Und doch können sie den berechneten Ausdruck enthalten, was nützlich ist, wenn die Breite nicht im Voraus bekannt ist:

 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) 

Ergebnis:

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


Wenn Ihre Klasse von einer anderen Klasse abgeleitet ist, muss auch die Metaklasse Ihrer Klasse von der Metaklasse dieser Klasse abgeleitet sein:

 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 

Es kann ratsam sein, automatisch die Metaklasse dieser anderen Klasse abzurufen:

 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__ ermöglicht es Ihnen , das Objekt zu ändern , nachdem es erstellt wird. Wenn Sie möchten , um das Set zu steuern, verwenden __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/de475684/


All Articles