The real question is one of completeness. Is your file processing function the complete processing of the file, or is it just one piece in a chain of processing steps? If it is complete in and of its own, then feel free to encapsulate all file access within a function.
def ver(filepath): with open(filepath, "r") as f: # do processing steps on f return result
This has the very nice property of finalizing the resource (closing the file) at the end of the with statement.
If however there is possibly a need for processing an already-open file, then the distinction of your ver_1 and ver_2 makes more sense. For example:
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)
This kind of explicit type testing is often frowned upon, especially in languages like Java, Julia, and Go where type- or interface-based dispatching is directly supported. In Python, however, there is no language support for type-based dispatching. You may occasionally see criticism of direct type-testing in Python, but in practice it's both extremely common and quite effective. It enables a function to have a high degree of generality, handling whatever datatypes are likely to come its way, aka "duck typing." Note the leading underscore on _ver_file; that is a conventional way of designating a "private" function (or method). While it can technically be called directly, it suggests that function is not intended for direct external consumption.
2019 update: Given recent updates in Python 3, for example that paths are now potentially stored as pathlib.Path objects not just str or bytes (3.4+), and that type hinting has gone from esoteric to mainstream (circa 3.6+, though still actively evolving), here's updated code that takes these advances into account:
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)