Tipps und Tricks aus meinem Telegrammkanal @pythonetc, Oktober 2019


Es ist eine neue Auswahl von Tipps und Tricks zu Python und Programmierung aus meinem Telegramm-Kanal @pythonetc.

Frühere Publikationen


Wenn Sie mehrere Iterables 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}') 

Ausgabe:

 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 


Ein Generator kann gestoppt werden. Sie können g.close() explizit aufrufen, aber normalerweise erledigt der Garbage Collector das für Sie. Sobald close aufgerufen wird, wird GeneratorExit an der Stelle GeneratorExit , an der die Generatorfunktion angehalten wurde:

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

Kümmere dich um drei Dinge. Erstens können Sie beim Umgang mit GeneratorExit keine Werte liefern:

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

Zweitens wird die Ausnahme nicht ausgelöst, wenn ein Generator noch nicht gestartet wurde, der Generator jedoch weiterhin angehalten wird:

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

Drittens macht close nichts, wenn ein 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 


Mit f-Strings können Sie die Breite für den gedruckten Wert sowie andere Formatbezeichner angeben:

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

Sie können auch ausgewertete Ausdrücke enthalten, die nützlich sein können, wenn die Breite im Voraus unbekannt 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) 

Ausgabe:

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


Wenn Ihre Klasse von einer anderen Klasse abgeleitet ist, muss die Metaklasse Ihrer Klasse auch 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 eine gute Idee sein, die Metaklasse dieser anderen Klasse automatisch 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__ können Sie ein Objekt direkt nach der Erstellung ändern. Wenn Sie steuern möchten, was erstellt wird, sollten __new__ stattdessen __new__ verwenden:

 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/de475686/


All Articles