我的@pythonetc feed提供了一系列新的Python技巧和编程。← 以前的出版物块的顺序很except
重要:如果一个异常可以被多个块捕获,那么上一个块将捕获该异常。此代码将无法正常工作: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
因为它IndexError
是子类而无法工作LookupError
。更具体的异常应该总是更高: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支持并发分配。这意味着在评估所有表达式后,所有变量都会立即更改。此外,您可以使用任何支持赋值的表达式,而不仅仅是变量: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不会自动使用负数加法而不是减法。考虑一个例子: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'
此代码不起作用:v1 = Velocity(20_000_000)
v2 = Velocity(10_000_000)
print(v1 - v2)
有趣,但是此代码有效:v1 = Velocity(20_000_000)
v2 = Velocity(10_000_000)
print(v1 +- v2)
# 10022302 m/s
这部分是由电报用户编写的。 si。函数不能同时是生成器函数和常规函数。如果在函数主体中使用yield
它,那么它将变成生成器: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))
但是,常规函数可能会返回另一个迭代器: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)
此选项在使用简单表达式生成器的情况下可能很有用:def zeros(*, count: int, lazy: bool):
if lazy:
return (0 for _ in range(count))
return [0] * count
创建生成器理解时,必须使用括号:>>> 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>
但是,如果理解是该函数的唯一参数,则可以忽略它们:>>> list((x**x for x in range(4)))
[1, 1, 4, 27]
>>> list(x**x for x in range(4))
[1, 1, 4, 27]
对于具有多个参数的函数,情况并非如此:>>> 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