真正的问题是完整性。您的文件处理功能是对文件的完整处理,还是只是一系列处理步骤中的一个?如果它本身是完整的,则可以将所有文件访问封装在一个函数中。
def ver(filepath):
with open(filepath, "r") as f:
# do processing steps on f
return result
这具有在with
语句末尾完成资源(关闭文件)的很好的属性。
但是,如果可能需要处理已经打开的文件,则将您ver_1
和的区别ver_2
更有意义。例如:
def _ver_file(f):
# do processing steps on f
return result
def ver(fileobj):
if isinstance(fileobj, str):
with open(fileobj, 'r') as f:
return _ver_file(f)
else:
return _ver_file(fileobj)
这种显式类型测试通常不被接受,尤其是在Java,Julia和Go这样的语言中,这些语言直接支持基于类型或接口的调度。但是,在Python中,不支持基于类型的调度的语言。您可能偶尔会看到对Python中直接类型测试的批评,但是在实践中,它非常普遍且非常有效。它使函数具有高度的通用性,可以处理可能会出现的任何数据类型,也就是“鸭子类型”。注意下划线_ver_file
; 这是指定“专用”功能(或方法)的常规方式。尽管从技术上可以直接调用它,但它表明该功能并非旨在直接用于外部消耗。
2019更新:在Python 3鉴于最近的更新,例如该路径现在可能存储pathlib.Path
不仅仅是对象str
或bytes
(3.4+),以及该类型提示已经从神秘的主流了(大约3.6 +,但仍积极发展的),这里的更新的代码考虑了这些进步:
from pathlib import Path
from typing import IO, Any, AnyStr, Union
Pathish = Union[AnyStr, Path] # in lieu of yet-unimplemented PEP 519
FileSpec = Union[IO, Pathish]
def _ver_file(f: IO) -> Any:
"Process file f"
...
return result
def ver(fileobj: FileSpec) -> Any:
"Process file (or file path) f"
if isinstance(fileobj, (str, bytes, Path)):
with open(fileobj, 'r') as f:
return _ver_file(f)
else:
return _ver_file(fileobj)
your_function
在这方面可以使用可选的“ stream_name”参数。