Redirecting FORTRAN (called via F2PY) output in Python

后端 未结 2 482
长发绾君心
长发绾君心 2020-12-02 14:57

I\'m trying to figure out how to redirect output from some FORTRAN code for which I\'ve generated a Python interface by using F2PY. I\'ve tried:

from fortran         


        
相关标签:
2条回答
  • 2020-12-02 15:17

    Here's a context manager that I recently wrote and found useful, because I was having a similar problem with distutils.ccompiler.CCompiler.has_function while working on pymssql. I also used the file descriptor approach but I used a context manager. Here's what I came up with:

    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()
    

    The context for why I created this is at this blog post. Similar to yours I think.

    I use it like this in a setup.py:

    with stdchannel_redirected(sys.stderr, os.devnull):
        if compiler.has_function('clock_gettime', libraries=['rt']):
            libraries.append('rt')
    
    0 讨论(0)
  • 2020-12-02 15:27

    The stdin and stdout fds are being inherited by the C shared library.

    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!"
    
    0 讨论(0)
提交回复
热议问题