A verdadeira questão é de completude. Sua função de processamento de arquivos é o processamento completo do arquivo ou é apenas uma parte de uma cadeia de etapas de processamento? Se estiver completo por si só, fique à vontade para encapsular todo o acesso a arquivos em uma função.
def ver(filepath):
with open(filepath, "r") as f:
# do processing steps on f
return result
Isso tem a propriedade muito agradável de finalizar o recurso (fechando o arquivo) no final da with
instrução.
Se, no entanto, houver a necessidade de processar um arquivo já aberto, a distinção entre você ver_1
e ver_2
faz mais sentido. Por exemplo:
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)
Esse tipo de teste explícito de tipo geralmente é desaprovado , especialmente em linguagens como Java, Julia e Go, nas quais o envio por tipo ou por interface é diretamente suportado. No Python, no entanto, não há suporte à linguagem para envio baseado em tipo. Ocasionalmente, você pode ver críticas ao teste de tipo direto no Python, mas na prática é extremamente comum e bastante eficaz. Ele permite que uma função tenha um alto grau de generalidade, manipulando quaisquer tipos de dados que possam aparecer no seu caminho, também conhecido como "digitação de pato". Observe o sublinhado principal em _ver_file
; essa é uma maneira convencional de designar uma função "privada" (ou método). Embora tecnicamente possa ser chamado diretamente, ele sugere que a função não se destina ao consumo externo direto.
2019 atualização: Dado atualizações recentes em Python 3, por exemplo, que os caminhos estão agora potencialmente armazenados como pathlib.Path
objetos e não apenas str
ou bytes
(3.4+), e que a indicação de tipo passou de esotérico para integrar (cerca 3.6+, embora ainda em evolução ativamente), aqui está código atualizado que leva esses avanços em consideração:
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
pode ser usado nesse sentido.