return-in-generator (B901)
源自 flake8-bugbear linter。
此规则不稳定且处于预览状态。使用需要 --preview
标志。
作用
检查同时包含 yield
或 yield from
语句的函数中是否有 return {value}
语句。
为什么这不好?
在生成器函数中使用 return {value}
在 Python 2 中是语法上无效的。在 Python 3 中,return {value}
*可以*在生成器中使用;但是,yield
和 return
的组合可能会导致令人困惑的行为,因为 return
语句将导致生成器引发带有提供的值的 StopIteration
,而不是将值返回给调用者。
例如,给定
from collections.abc import Iterable
from pathlib import Path
def get_file_paths(file_types: Iterable[str] | None = None) -> Iterable[Path]:
dir_path = Path(".")
if file_types is None:
return dir_path.glob("*")
for file_type in file_types:
yield from dir_path.glob(f"*.{file_type}")
读者可能会认为 get_file_paths()
将返回目录中 Path
对象的可迭代对象;但实际上,list(get_file_paths())
的计算结果为 []
,因为 return
语句导致生成器引发带有值 dir_path.glob("*")
的 StopIteration
>>> list(get_file_paths(file_types=["cfg", "toml"]))
[PosixPath('setup.cfg'), PosixPath('pyproject.toml')]
>>> list(get_file_paths())
[]
对于生成器中故意使用 return
的情况,请考虑抑制此诊断。
示例
from collections.abc import Iterable
from pathlib import Path
def get_file_paths(file_types: Iterable[str] | None = None) -> Iterable[Path]:
dir_path = Path(".")
if file_types is None:
return dir_path.glob("*")
for file_type in file_types:
yield from dir_path.glob(f"*.{file_type}")
建议改为