Настоящий вопрос заключается в полноте. Является ли ваша функция обработки файлов полной обработкой файла, или это всего лишь одна часть в цепочке этапов обработки? Если он завершен сам по себе, то не стесняйтесь инкапсулировать весь доступ к файлам внутри функции.
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» .