【发布时间】:2021-10-27 10:22:58
【问题描述】:
假设一个函数不能计算一个有效的返回值。例如,字典查找可能无法找到键。当函数返回一个值或不返回值时,这种情况的最佳实践是什么?
1.返回None: 比如dict.get()就是这种模式。这种方法的缺点是客户端需要检查返回值是否为None,并根据它做一些事情。
例如,
def getprice(car: Car) -> Optional[int]:
if ispriceless(car):
return None
return car.value
def client():
average_car_price_on_market = mean(
[getprice(car) for car in get_all_cars() if getprice(car) is not None]
)
(当然,我不必打两次getprice,但我只是想强调一下尴尬)
2。使用yield: 基本上这就像返回一个包含零个或一个元素的列表。上面的例子看起来像这样:
def getprice(car: Car) -> Generator[int, None, None]:
if not ispriceless(car):
yield car.value
def client():
average_car_price_on_market = mean(
[price for car in get_all_cars() for price in getprice(car)]
)
我觉得这一篇更容易阅读,但有些人可能会说它不那么明确?
3.使用异常: 这可能是最明确的方法,但我想知道人们如何看待异常处理的开销;我还看到了反对使用异常作为控制流的论点(例如,here)
【问题讨论】:
-
这取决于您要达到的目标。如果您的程序可以处理无价的汽车,并且您希望平均价格不包括这些,那么过滤方法是合适的。还有,当汽车无价时,
car.value的价值是多少?如果该属性是None,您可以简化为[car.value for get_all_cars() if car.value]。如果属性不存在,则可以使用getattr(car, 'value', None)。 -
我会说没有批准的一般策略:这取决于上下文。
标签: python exception coding-style anti-patterns