Eine neue Auswahl an Python-Tipps und -Programmierungen aus meinem @ pythonetc-Feed.← Frühere VeröffentlichungenDie Reihenfolge der Blöcke ist except
wichtig: Wenn eine Ausnahme von mehreren Blöcken abgefangen werden kann, wird sie vom oberen Block abgefangen. Dieser Code funktioniert nicht wie vorgesehen:import logging
def get(storage, key, default):
try:
return storage[key]
except LookupError:
return default
except IndexError:
return get(storage, 0, default)
except TypeError:
logging.exception('unsupported key')
return default
print(get([1], 0, 42))
print(get([1], 10, 42))
print(get([1], 'x', 42))
except IndexError
funktioniert nicht, da es sich IndexError
um eine Unterklasse handelt LookupError
. Eine spezifischere Ausnahme sollte immer höher sein:import logging
def get(storage, key, default):
try:
return storage[key]
except IndexError:
return get(storage, 0, default)
except LookupError:
return default
except TypeError:
logging.exception('unsupported key')
return default
print(get([1], 0, 42))
print(get([1], 10, 42))
print(get([1], 'x', 42))
Python unterstützt die gleichzeitige Zuweisung. Dies bedeutet, dass sich alle Variablen unmittelbar nach der Auswertung aller Ausdrücke ändern. Darüber hinaus können Sie jeden Ausdruck verwenden, der die Zuweisung unterstützt, und nicht nur Variablen:def shift_inplace(lst, k):
size = len(lst)
lst[k:], lst[0:k] = lst[0:-k], lst[-k:]
lst = list(range(10))
shift_inplace(lst, -3)
print(lst)
shift_inplace(lst, 5)
print(lst)
Python verwendet nicht automatisch die Addition negativer Zahlen, anstatt sie zu subtrahieren. Betrachten Sie ein Beispiel:class Velocity:
SPEED_OF_LIGHT = 299_792_458
def __init__(self, amount):
self.amount = amount
def __add__(self, other):
return type(self)(
(self.amount + other.amount) /
(
1 +
self.amount * other.amount /
self.SPEED_OF_LIGHT ** 2
)
)
def __neg__(self):
return type(self)(-self.amount)
def __str__(self):
amount = int(self.amount)
return f'{amount} m/s'
Dieser Code funktioniert nicht:v1 = Velocity(20_000_000)
v2 = Velocity(10_000_000)
print(v1 - v2)
Witzig, aber dieser Code funktioniert:v1 = Velocity(20_000_000)
v2 = Velocity(10_000_000)
print(v1 +- v2)
# 10022302 m/s
Dieser Teil wurde von einem Telegrammbenutzer geschrieben. Orsinium.Eine Funktion kann nicht sowohl ein Generator als auch eine reguläre Funktion sein. Wenn es im Hauptteil einer Funktion verwendet wird yield
, wird es zu einem Generator:def zeros(*, count: int, lazy: bool):
if lazy:
for _ in range(count):
yield 0
else:
return [0] * count
zeros(count=10, lazy=True)
zeros(count=10, lazy=False)
list(zeros(count=10, lazy=False))
Eine reguläre Funktion kann jedoch einen anderen Iterator zurückgeben:def _lazy_zeros(*, count: int):
for _ in range(count):
yield 0
def zeros(*, count: int, lazy: bool):
if lazy:
return _lazy_zeros(count=count)
return [0] * count
zeros(count=10, lazy=True)
zeros(count=10, lazy=False)
Und diese Option kann in Fällen mit einfachen Ausdrucksgeneratoren nützlich sein:def zeros(*, count: int, lazy: bool):
if lazy:
return (0 for _ in range(count))
return [0] * count
Beim Erstellen des Generatorverständnisses müssen Sie Klammern verwenden:>>> g = x**x for x in range(10)
File "<stdin>", line 1
g = x**x for x in range(10)
^
SyntaxError: invalid syntax
>>> g = (x**x for x in range(10))
>>> g
<generator object <genexpr> at 0x7f90ed650258>
Sie können jedoch weggelassen werden, wenn das Verständnis das einzige Argument für die Funktion ist:>>> list((x**x for x in range(4)))
[1, 1, 4, 27]
>>> list(x**x for x in range(4))
[1, 1, 4, 27]
Dies gilt nicht für Funktionen mit mehreren Argumenten:>>> print((x**x for x in range(4)), end='\n')
<generator object <genexpr> at 0x7f90ed650468>
>>>
>>>
>>> print(x**x for x in range(4), end='\n')
File "<stdin>", line 1
SyntaxError: Generator expression must be parenthesized if not sole argument