我想创建一个接受3个参数的函数,每个参数都可以传递给open
函数,我的函数将传递给open
然后使用它,或者它可以是一个文件对象,然后我的函数可以使用它而无需打开它。
所以,就像这样
def work_with_files(file1, file2, file3):
files_to_close = []
file_objects = []
try:
for file in (file1, file2, file3):
if not is_file_object(file):
opened_file = open(file.argument_for_open)
file_objects.append(opened_file)
files_to_close.append(opened_file)
else:
file_objects.append(file.file_object)
work_with_files(file_objects)
finally:
for file in files_to_close:
file.close()
在C ++中我会使用boost::variant
,在haskell中我可能会使用Either
。什么是最pythonic的方式来做到这一点?我应该将什么作为参数传递,is_file_object
应该如何工作?
答案 0 :(得分:1)
您可以使用contextlib.ExitStack
(因此fileobjs会在with
内自动关闭)并概括您的函数(如果它是一个字符串) - 然后将其传递给open
,否则假设它已经是一个文件类似于.close()
...
from contextlib import ExitStack
def work_with_files(*args):
with ExitStack() as stack:
fileobjs = [
stack.enter_context(open(obj) if isinstance(obj, str) else obj)
for obj in args
]
# do something with fileobjs list
做某事可能是这样的:
from itertools import chain
for line in chain.from_iterable(fileobjs):
print(line)
答案 1 :(得分:0)
您可以使用isinstance
功能:
isinstance(file_name,file)
如果object参数是classinfo参数的实例,或者是(直接,间接或虚拟)子类的实例,则返回true。如果classinfo是类型对象(新样式类)并且object是该类型的对象或其(直接,间接或虚拟)子类,则也返回true。
另外:
文件对象使用C的stdio包实现,可以使用内置的open()函数创建。
您可以使用try-except语句来处理file objects
:
try:
open('file-name')
except IOError:
#do stuff
答案 2 :(得分:0)
如果您不想检查参数类型,可以使用try-except结构完全按照您的意愿执行:
def work_with_files(file1, file2, file3):
# ensure that each file* variable is a file-like object
try: file1 = open(file1) # if it opens, then file1 was a filepath
except: pass # else, file1 was already a file-like object
try: file2 = open(file2)
except: pass
try: file3 = open(file3)
except: pass
do_stuff_with_files(file1, file2, file3)
for f in (file1, file2, file3): f.close() # close the files