Prawdziwe pytanie dotyczy kompletności. Czy twoja funkcja przetwarzania plików jest kompletnym przetwarzaniem pliku, czy jest to tylko jeden element w szeregu etapów przetwarzania? Jeśli jest on sam w sobie kompletny, możesz obudować cały dostęp do pliku w ramach funkcji.
def ver(filepath):
with open(filepath, "r") as f:
# do processing steps on f
return result
Ma to bardzo przyjemną właściwość finalizowania zasobu (zamykania pliku) na końcu with
instrukcji.
Jeśli jednak istnieje potrzeba przetworzenia już otwartego pliku, wówczas rozróżnienie twojego ver_1
i ver_2
ma większy sens. Na przykład:
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)
Tego rodzaju jawne testowanie typów jest często lekceważone , szczególnie w takich językach, jak Java, Julia i Go, gdzie bezpośrednie wysyłanie oparte na typie lub interfejsie jest obsługiwane. Jednak w Pythonie nie ma obsługi języka dla wysyłania opartego na typach. Czasami możesz spotkać się z krytyką bezpośrednich testów typu w Pythonie, ale w praktyce jest to zarówno bardzo powszechne, jak i dość skuteczne. Umożliwia dużej ogólności funkcji, obsługując wszystkie typy danych, które mogą się pojawić, czyli „pisanie kaczek”. Zwróć uwagę na wiodący znak podkreślenia na _ver_file
; jest to konwencjonalny sposób oznaczania funkcji „prywatnej” (lub metody). Chociaż technicznie można go wywołać bezpośrednio, sugeruje, że funkcja nie jest przeznaczona do bezpośredniego zużycia zewnętrznego.
Aktualizacja 2019: Biorąc pod uwagę najnowsze aktualizacje w Pythonie 3, na przykład ścieżki są teraz potencjalnie przechowywane jako pathlib.Path
obiekty nie tylko str
lub bytes
(3.4+), a podpowiedzi typu zmieniły się z ezoterycznych na główny nurt (około 3.6+, choć wciąż aktywnie się rozwija), oto: zaktualizowany kod, który uwzględnia te postępy:
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
tym względzie można zastosować opcjonalny argument „nazwa_strumienia” .