0
app = Flask(__name__)
@app.route("/")
def hello():
    address="someserver"
    global FTP
    ftp = FTP(address)
    ftp.login()
    return ftp.retrlines("LIST")

if __name__ == "__main__":
    app.run()

...これにより、次の出力が得られます。

226-Options: -l 226 1 matches total

問題は、なぜこれが retrlines の出力を表示しないのか、どうすればよいのかということです。

4

1 に答える 1

2

ftplib.FTPクラスのドキュメントにretrlinesは、オプションのコールバックを取ると書かれています - コールバックが提供されていない場合、「デフォルトのコールバックは行を出力しますsys.stdout。これは、メソッドが提供されたデータを実際には返さretrlinesないことを意味します。各行を受け取ったときに、渡される可能性のある callable に渡すだけです。これにより、いくつかのオプションが残ります。

  1. 複数回呼び出された結果を格納できる callable を渡します。

    def fetchlines(line=None):
        if line is not None:
            # As long as we are called with a line
            # store the line in the array we added to this function
            fetchlines.lines.append(line)
        else:
            # When we are called without a line
            # we are retrieving the lines
            # Truncate the array after copying it
            # so we can re-use this function
            lines = fetchlines.lines[:]
            fetchlines.lines = []
            return lines
    
    fetchlines.lines = []
    
    @app.route("/")
    def hello():
        ftp = FTP("someaddress")
        ftp.login()
        ftp.dir(fetchlines)
        lines = fetchlines()
        return "<br>".join(lines)
    
  2. sys.stdoutファイルのようなオブジェクト(cStringIOたとえばから)に置き換えてから、後でファイルを読み取るだけです。

    from cStringIO import StringIO
    from sys import stdout
    
    # Save a reference to stdout
    STANDARD_OUT = stdout
    
    @app.route("/")
    def hello():
        ftp = FTP("someaddress")
        ftp.login()
    
        # Change stdout to point to a file-like object rather than a terminal
        file_like = StringIO()
        stdout = file_like
    
        ftp.dir()
    
        # lines in this case will be a string, not a list
        lines = file_like.getvalue()
    
        stdout = STANDARD_OUT
        file_like.close()
    
        return lines
    

これらの手法はどちらも、多くの負荷がかかった状態ではうまく機能しません。また、実際の並行性の下でもうまく機能しません。それを解決する方法はありますが、それは別の日にします。

于 2012-12-15T03:10:27.337 に答える