Справжнє питання - це повнота. Чи ваша функція обробки файлів - це повна обробка файлу, чи це лише одна деталь у ланцюжку етапів обробки? Якщо він є повним і власним, тоді сміливо інкапсулюйте весь доступ до файлів у межах функції.
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
можна використовувати в цьому відношенні.