如何在Python函数中同时接受文件名和类文件对象?

2024-09-29 02:27:42 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的代码中,我有一个load_dataset函数,它读取文本文件并进行一些处理。最近我考虑添加对类似文件的对象的支持,我想知道最好的方法。目前我有两种实现方法:

首先,类型检查:

if isinstance(inputelement, basestring):
   # open file, processing etc
# or
# elif hasattr(inputelement, "read"):
elif isinstance(inputelement, file):
   # Do something else

或者,两个不同的参数:

^{pr2}$

不过,这两种解决方案都不能让我太信服,尤其是第二种,因为我看到了太多的陷阱。在

将类似文件的对象或字符串接受到执行文本读取的函数中,最干净(也是最具Pythonic)的方法是什么?在


Tags: 文件对象方法函数代码类型ifload
3条回答

将文件名或类文件对象作为参数的一种方法是实现可以同时处理这两者的context manager。可以找到一个实现here,为了得到一个自包含的答案,我引用:

class open_filename(object):
"""Context manager that opens a filename and closes it on exit, but does
nothing for file-like objects.
"""
def __init__(self, filename, *args, **kwargs):
    self.closing = kwargs.pop('closing', False)
    if isinstance(filename, basestring):
        self.fh = open(filename, *args, **kwargs)
        self.closing = True
    else:
        self.fh = filename

def __enter__(self):
    return self.fh

def __exit__(self, exc_type, exc_val, exc_tb):
    if self.closing:
        self.fh.close()

    return False

可能的用法:

^{pr2}$

不要同时接受文件和字符串。如果您要接受类似文件的对象,那么这意味着您不会检查类型,只需对实际参数(readwrite,等等)调用所需的方法。如果您要接受字符串,那么您将得到open-ing文件,这意味着您无法模拟参数。所以我会说接受文件,让调用者传递一个类似文件的对象,不要检查类型。在

Python遵循duck类型,您可以通过函数检查这是否是您需要的对象文件对象。例如,hasattr(obj, 'read')对{}。 要将字符串转换为文件对象,还可以使用以下构造:

if not hasattr(obj, 'read'):
    obj = StringIO(str(obj))

在这段代码之后,您可以安全地使用obj作为文件。在

相关问题 更多 >