我知道有一个类似的问题已经被问过,但没有回答我的需要,因为我的情况有点不同。
我的代码:
def tFileRead(fileName, JSON=False):
with open(fileName) as f:
if JSON:
return json.load(f)
for line in f:
yield line.rstrip('\n')
我想做什么:
如果JSON
为真,则表示从json文件读取,我想返回json.load(f)
,否则,我想将文件的行放到生成器中。
我已经尝试过将生成器转换为json的替代方案,但是它非常混乱,速度非常快,并且效果不佳。
答案 0 :(得分:2)
我想到的第一个解决方案是显式返回一个生成器对象,该对象将提供您尝试实现的确切行为。
问题是:如果您显式返回了像return (line.rstrip('\n') for line in f)
这样的生成器对象,则文件将在返回后关闭,并且从文件中进一步读取会引发异常。
你应该在这里写两个函数:一个读取json文件,一个读取普通文件。然后你可以编写一个包装器来解决这两个函数中要调用的参数。
或者只是将迭代部分移动到另一个函数中:
def iterate_file(file_name):
with open(file_name) as fin:
for line in fin:
yield line.rstrip("\n")
def file_read(file_name, as_json=False):
if as_json:
with open(file_name) as fin:
return json.load(fin)
else:
return iterate_file(file_name)
答案 1 :(得分:1)
你可以yield from
加载JSON的字典,从而迭代dict中的键值对,但这不是你想要的行为。
def tFileRead(fileName, JSON=False):
with open(fileName) as f:
if JSON:
yield from json.load(f).items() # works, but differently
for line in f:
yield line.rstrip('\n')
如果您只能返回一个生成器会很好,但是这不会起作用,因为使用with
,文件会在函数返回时立即关闭,即在生成器被使用之前关闭。
def tFileRead(fileName, JSON=False):
with open(fileName) as f:
if JSON:
return json.load(f)
else:
return (line.rstrip('\n') for line in f) # won't work
或者,您可以定义另一个函数,仅用于从文件中生成行并在生成器中使用它:
def tFileRead(fileName, JSON=False):
if JSON:
with open(fileName) as f:
return json.load(f)
else:
def withopen(fileName):
with open(fileName) as f:
yield from f
return (line.rstrip('\n') for line in withopen(fileName))
但是一旦你在那里,你真的可以使用两个单独的函数来读取文件en-block作为JSON或迭代行...