Python 支持文件名、路径和缓冲区输入

Python 支持文件名、路径和缓冲区输入,python,io,Python,Io,Python包中的一个常见要求是允许文件输入为字符串文件名、pathlib.Path或已打开的缓冲区。我通常像这样把缓冲区分开 def foo_from_文件(文件名,*args,**kwargs): 打开(文件名)为f时: 来自缓冲区的foo_(f,*args,**kwargs) def foo_来自_缓冲区(f): f、 readline() #做点什么 返回 但从用户的角度来看,一个更干净的方法可能是 def foo(file_or_buffer): if hasattr(fil

Python包中的一个常见要求是允许文件输入为字符串文件名、pathlib.Path或已打开的缓冲区。我通常像这样把缓冲区分开

def foo_from_文件(文件名,*args,**kwargs):
打开(文件名)为f时:
来自缓冲区的foo_(f,*args,**kwargs)
def foo_来自_缓冲区(f):
f、 readline()
#做点什么
返回
但从用户的角度来看,一个更干净的方法可能是

def foo(file_or_buffer):
    if hasattr(file_or_buffer, "readline"):  # ???
        f = file_or_buffer
    else:
        f = open(file_or_buffer)

    f.readline()
(这个特定的实现不是很好,因为失败时它不会关闭()

file\u或\u buffer
是Python方法中的常见参数,还是将两者分开?如何最好地实现它?

根据我之前关于可能已作为参数传入或未作为参数传入的已打开数据库连接的描述,当传入的任何内容都有
读线时,可以使用“不做任何事情”:

from contextlib import nullcontext
from pathlib import Path
from io import StringIO

def foo(file_or_buffer):
    if hasattr(file_or_buffer, "readline"):
        cm = nullcontext(file_or_buffer)
    else:
        cm = open(file_or_buffer)

    with cm as f:
        line = f.readline()
        print(line)
    
pa = Path(__file__)

foo(pa)
foo(f"{pa}")

with pa.open() as fi:
    foo(fi)
with pa.open() as fi:
    buffer = StringIO(fi.read())
foo(buffer)

输出:
from contextlib import nullcontext

from contextlib import nullcontext

from contextlib import nullcontext

from contextlib import nullcontext