繁体   English   中英

在循环中,可选择将输出写入文件

[英]In a loop, optionally write output to files

我写了一个函数,它迭代地计算一些量X,Y ,返回最终结果。 此外,此代码将X,Y的每次迭代保存到文件中。 这是基本结构:

def myFunc():
    X,Y = 0,0
    file1 = open(output1,"w")
    file2 = open(output2,"w")
    for i in range(1000):
        X,Y = someCalculation(X,Y) #calculations happen here
        file1.write(X)
        file2.write(Y)
    file1.close()
    file2.close()
    return X,Y

但是,如果在调用函数时省略了文件名output1output2 ,我需要这个函数来执行相同的计算,而不向相关文件附加任何内容

这是我的混乱解决方案:

def myFunc(output1=None,output2=None):
    X,Y = 0,0
    if (output1 != None): file1 = open(output1,"w")
    if (output2 != None): file2 = open(output2,"w")
    for i in range(1000):
        X,Y = someCalculation(X,Y) #calculations happen here
        if (output1 != None): file1.write(X)
        if (output2 != None): file2.write(Y)
    if (output1 != None): file1.close()
    if (output2 != None): file2.close()
    return X,Y

有没有更好、更干净的方法来写这个?

创建一个忽略写入的虚拟文件对象,并支持上下文管理器接口:

class NoFile:
    def __enter__(self): return self
    # Propagate any exceptions that were raised, explicitly.
    def __exit__(self, exc_type, exc_value, exc_tb): return False
    # Ignore the .write method when it is called.
    def write(self, data): pass
    # We can extend this with other dummy behaviours, e.g.
    # returning an empty string if there is an attempt to read.

当文件名is None时,创建一个辅助函数来创建其中一个而不是普通文件:

def my_open(filename, *args, **kwargs):
    return NoFile() if filename is None else open(filename, *args, **kwargs)

使用with块来管理文件生命周期,无论如何你都应该这样做 - 但现在使用my_open而不是open

def myFunc(output1=None,output2=None):
    X, Y = 0, 0
    with my_open(output1, 'w') as f1, my_open(output2, 'w') as f2:
        for i in range(1000):
            X, Y = someCalculation(X, Y) #calculations happen here
            f1.write(X)
            f2.write(Y)
    return X, Y

您可以创建一个具有无操作write方法的虚拟类。 ExitStack用于确保所有打开的文件都自动关闭。

from contextlib import ExitStack


class NoWrite:
    def write(self, value):
        pass


def myFunc(output1=None, output2=None):
    X,Y = 0,0
    with ExitStack() as es:
        file1 = es.enter_context(open(output1, "w")) if output1 is not None else NoWrite()
        file2 = es.enter_context(open(output2, "w")) if output2 is not None else NoWrite()

        for i in range(1000):
            X,Y = someCalculation(X, Y) #calculations happen here
            file1.write(X)
            file2.write(Y)
    return X,Y

由于您似乎在每一步都记录了X和/或Y值,因此您可能需要考虑使用logging模块,为适当的记录器创建FileHandler ,而不是将输出文件名传递给myFunc本身。

import logging

# configuration of the logger objects is the responsibility
# of the *user* of the function, not the function itself.
def myFunc():
    x_logger = logging.getLogger("myFunc.x_logger")
    y_logger = logging.getLogger("myFunc.y_logger")

    X,Y = 0,0
    for i in range(1000):
        X,Y = someCalculation(X, Y)
        x_logger.info("%s", X)
        y_logger.info("%s", Y)
    return X,Y

更简单:写入操作系统定义的“空设备”文件,写入时无效。

标准库os模块定义了一个字符串常量devnull ,它标识该文件的路径:Mac 和 Linux 上'/dev/null' ,Windows 上'NUL' (我想后者实际上不是路径)。

import os
def myFunc(output1=os.devnull,output2=os.devnull):
    # as before, with no special conditional logic

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM