在发生器内返回参数

时间:2016-07-29 15:38:43

标签: python json generator readfile

我知道有一个类似的问题已经被问过,但没有回答我的需要,因为我的情况有点不同。

我的代码:

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的替代方案,但是它非常混乱,速度非常快,并且效果不佳。

2 个答案:

答案 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或迭代行...