La verdadera pregunta es de integridad. ¿Es su función de procesamiento de archivos el procesamiento completo del archivo, o es solo una pieza en una cadena de pasos de procesamiento? Si está completo por sí solo, no dude en encapsular todo el acceso a archivos dentro de una función.
def ver(filepath):
with open(filepath, "r") as f:
# do processing steps on f
return result
Esto tiene la muy buena propiedad de finalizar el recurso (cerrar el archivo) al final de la with
declaración.
Sin embargo, si existe la necesidad de procesar un archivo ya abierto, entonces la distinción de su ver_1
y ver_2
tiene más sentido. Por ejemplo:
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)
Este tipo de prueba de tipo explícito a menudo está mal visto , especialmente en lenguajes como Java, Julia y Go, donde el despacho basado en tipo o interfaz es directamente compatible. En Python, sin embargo, no hay soporte de idioma para el despacho basado en tipos. Es posible que de vez en cuando vea críticas de las pruebas de tipo directas en Python, pero en la práctica es extremadamente común y bastante efectivo. Permite que una función tenga un alto grado de generalidad, manejando cualquier tipo de datos que puedan aparecer, también conocido como "escritura de pato". Tenga en cuenta el guión bajo principal en _ver_file
; esa es una forma convencional de designar una función (o método) "privada". Si bien técnicamente se puede llamar directamente, sugiere que la función no está destinada al consumo externo directo.
Actualización de 2019: Dadas las actualizaciones recientes en Python 3, por ejemplo, que las rutas ahora se almacenan potencialmente como pathlib.Path
objetos no solo str
o bytes
(3.4+), y ese tipo de sugerencia ha pasado de esotérico a mainstream (circa 3.6+, aunque todavía evoluciona activamente), aquí está Código actualizado que tiene en cuenta estos avances:
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
puede usar un argumento opcional "stream_name" para este respecto.