在Python中重定向FORTRAN(通过F2PY调用)输出

2024-05-29 03:22:11 发布

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

我正试图找出如何重定向一些FORTRAN代码的输出,我已经为这些代码使用F2PY生成了一个Python接口。我试过:

from fortran_code import fortran_function
stdout_holder = sys.stdout
stderr_holder = sys.stderr
sys.stdout = file("/dev/null","w")
fortran_function()
sys.stdout.close()
sys.stderr.close()
sys.stdout = stdout_holder
sys.stderr = stderr_holder

这是在Python中重定向输出的实际方法,但在这种情况下似乎不起作用(即无论如何都会显示输出)。

我确实发现a mailing list post from 2002说“可以从pts设备读取消息,例如ttysnoop这样做”。关于ttysnoop的信息似乎很难在网上找到(我不认为它已经更新了好几年;例如,the first result on Google for "ttysnoop"只有tarballs、RPMs和.deb的死链接),并且this request for a port to OS X收到了“不走运,它需要一些特定于linux的utmp函数,我无法创建这些函数”的响应

对于如何重定向输出,我愿意接受任何建议(它不必使用ttysnoop)。

谢谢!


Tags: 函数代码fromforclosestderrstdoutsys
2条回答

这是我最近写的一个context manager,发现它很有用,因为我在处理pymssql时遇到了类似的问题。我也使用了文件描述符方法,但是我使用了context manager。我想到的是:

import contextlib


@contextlib.contextmanager
def stdchannel_redirected(stdchannel, dest_filename):
    """
    A context manager to temporarily redirect stdout or stderr

    e.g.:


    with stdchannel_redirected(sys.stderr, os.devnull):
        if compiler.has_function('clock_gettime', libraries=['rt']):
            libraries.append('rt')
    """

    try:
        oldstdchannel = os.dup(stdchannel.fileno())
        dest_file = open(dest_filename, 'w')
        os.dup2(dest_file.fileno(), stdchannel.fileno())

        yield
    finally:
        if oldstdchannel is not None:
            os.dup2(oldstdchannel, stdchannel.fileno())
        if dest_file is not None:
            dest_file.close()

我创建这个的上下文在this blog post。我想和你的差不多。

我在一个setup.py中这样使用它:

with stdchannel_redirected(sys.stderr, os.devnull):
    if compiler.has_function('clock_gettime', libraries=['rt']):
        libraries.append('rt')

stdin和stdout fds正由C共享库继承。

from fortran_code import fortran_function
import os

print "will run fortran function!"

# open 2 fds
null_fds = [os.open(os.devnull, os.O_RDWR) for x in xrange(2)]
# save the current file descriptors to a tuple
save = os.dup(1), os.dup(2)
# put /dev/null fds on 1 and 2
os.dup2(null_fds[0], 1)
os.dup2(null_fds[1], 2)

# *** run the function ***
fortran_function()

# restore file descriptors so I can print the results
os.dup2(save[0], 1)
os.dup2(save[1], 2)
# close the temporary fds
os.close(null_fds[0])
os.close(null_fds[1])

print "done!"

相关问题 更多 >

    热门问题