Python chuyển hướng thiết bị xuất chuẩn sang đường ống

Chuyển hướng thiết bị xuất chuẩn sang thứ mà hầu hết các nhà phát triển sẽ cần thực hiện vào lúc này hay lúc khác. Có thể hữu ích khi chuyển hướng thiết bị xuất chuẩn tới một tệp hoặc tới một đối tượng giống như tệp. Tôi cũng đã chuyển hướng thiết bị xuất chuẩn sang điều khiển văn bản trong một số dự án GUI trên máy tính để bàn của mình. Trong bài viết này, chúng ta sẽ xem xét những điều sau đây

  • Chuyển hướng thiết bị xuất chuẩn sang tệp (đơn giản)
  • Phương pháp chuyển hướng Shell
  • Chuyển hướng thiết bị xuất chuẩn bằng trình quản lý ngữ cảnh tùy chỉnh
  • Ngữ cảnh của Python 3. redirect_stdout()
  • Chuyển hướng thiết bị xuất chuẩn sang điều khiển văn bản wxPython

Cách dễ nhất để chuyển hướng thiết bị xuất chuẩn trong Python là chỉ định cho nó một đối tượng tệp đang mở. Hãy xem một ví dụ đơn giản

import sys

def redirect_to_file(text):
    original = sys.stdout
    sys.stdout = open('/path/to/redirect.txt', 'w')
    print('This is your redirected text:')
    print(text)
    sys.stdout = original

    print('This string goes to stdout, NOT the file!')

if __name__ == '__main__':Redirecting stdout / stderr
    redirect_to_file('Python rocks!')

Ở đây, chúng tôi chỉ nhập mô-đun sys của Python và tạo một hàm mà chúng tôi có thể chuyển các chuỗi mà chúng tôi muốn chuyển hướng đến một tệp. Chúng tôi lưu một tham chiếu đến sys. thiết bị xuất chuẩn để chúng tôi có thể khôi phục nó khi kết thúc chức năng. Điều này có thể hữu ích nếu bạn có ý định sử dụng thiết bị xuất chuẩn cho những thứ khác. Trước khi bạn chạy mã này, hãy nhớ cập nhật đường dẫn đến thứ gì đó sẽ hoạt động trên hệ thống của bạn. Khi bạn chạy nó, bạn sẽ thấy nội dung sau trong tệp của mình

This is your redirected text:
Python rocks!

Câu lệnh in cuối cùng đó sẽ chuyển đến thiết bị xuất chuẩn, không phải tệp


Chuyển hướng Shell

Chuyển hướng Shell cũng khá phổ biến, đặc biệt là trong Linux, mặc dù Windows cũng hoạt động theo cách tương tự trong hầu hết các trường hợp. Hãy tạo một ví dụ ngớ ngẩn về chức năng ồn ào mà chúng ta sẽ gọi là ồn ào. py

# noisy.py
def noisy(text):
    print('The noisy function prints a lot')
    print('Here is the string you passed in:')
    print('*' * 40)
    print(text)
    print('*' * 40)
    print('Thank you for calling me!')

if __name__ == '__main__':
    noisy('This is a test of Python!')

Bạn sẽ nhận thấy rằng chúng tôi đã không nhập mô-đun sys vào khoảng thời gian này. Lý do là chúng tôi không cần nó vì chúng tôi sẽ sử dụng chuyển hướng shell. Để thực hiện chuyển hướng trình bao, hãy mở một thiết bị đầu cuối (hoặc dấu nhắc lệnh) và điều hướng đến thư mục mà bạn đã lưu mã ở trên. Sau đó thực hiện lệnh sau

python noisy.py > redirected.txt

Ký tự lớn hơn (i. e. >) yêu cầu hệ điều hành của bạn chuyển hướng thiết bị xuất chuẩn sang tên tệp bạn đã chỉ định. Tại thời điểm này, bạn sẽ có một tệp có tên "redirected. txt" trong cùng thư mục với tập lệnh Python của bạn. Nếu bạn mở nó lên, tệp sẽ có nội dung sau

The noisy function prints a lot
Here is the string you passed in:
****************************************
This is a test of Python!
****************************************
Thank you for calling me!

Bây giờ không phải là khá mát mẻ?


Chuyển hướng thiết bị xuất chuẩn với trình quản lý ngữ cảnh

Một cách thú vị khác để chuyển hướng thiết bị xuất chuẩn là sử dụng trình quản lý ngữ cảnh. Hãy tạo một trình quản lý bối cảnh tùy chỉnh chấp nhận một đối tượng tệp để chuyển hướng thiết bị xuất chuẩn sang

import sys
from contextlib import contextmanager


@contextmanager
def custom_redirection(fileobj):
    old = sys.stdout
    sys.stdout = fileobj
    try:
        yield fileobj
    finally:
        sys.stdout = old

if __name__ == '__main__':
    with open('/path/to/custom_redir.txt', 'w') as out:
        with custom_redirection(out):
            print('This text is redirected to file')
            print('So is this string')
        print('This text is printed to stdout')

Khi bạn chạy mã này, nó sẽ ghi hai dòng văn bản vào tệp của bạn và một dòng vào thiết bị xuất chuẩn. Như thường lệ, chúng tôi đặt lại thiết bị xuất chuẩn ở cuối chức năng


Sử dụng contextlib. redirect_stdout

Trăn 3. 4 đã thêm hàm redirect_stdout vào mô-đun contextlib của họ. Hãy thử sử dụng điều đó để tạo trình quản lý bối cảnh để chuyển hướng thiết bị xuất chuẩn

import sys
from contextlib import redirect_stdout

def redirected(text, path):
    with open(path, 'w') as out:
        with redirect_stdout(out):
            print('Here is the string you passed in:')
            print('*' * 40)
            print(text)
            print('*' * 40)

if __name__ == '__main__':
    path = '/path/to/red.txt'
    text = 'My test to redirect'
    redirected(text, path)

Mã này đơn giản hơn một chút vì chức năng tích hợp sẵn thực hiện tất cả việc tạo và đặt lại thiết bị xuất chuẩn tự động cho bạn. Mặt khác, nó hoạt động khá giống với trình quản lý ngữ cảnh tùy chỉnh của chúng tôi


Chuyển hướng thiết bị xuất chuẩn trong wxPython

Python chuyển hướng thiết bị xuất chuẩn sang đường ống

Tôi đã nhiều lần viết về việc chuyển hướng thiết bị xuất chuẩn trong wxPython. Đoạn mã sau thực sự là từ một bài báo tôi đã viết vào năm 2009 và được cập nhật vào năm 2015

import sys
import wx

class MyForm(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None,
                          title="wxPython Redirect Tutorial")

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL
        log = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100),
                          style=style)
        btn = wx.Button(panel, wx.ID_ANY, 'Push me!')
        self.Bind(wx.EVT_BUTTON, self.onButton, btn)

        # Add widgets to a sizer
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        panel.SetSizer(sizer)

        # redirect text here
        sys.stdout = log

    def onButton(self, event):
        print "You pressed the button!"

# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm().Show()
    app.MainLoop()

Mã này chỉ tạo một khung đơn giản với bảng điều khiển có nhiều dòng điều khiển văn bản và một nút. Bất cứ khi nào bạn nhấn nút, nó sẽ in một số văn bản ra thiết bị xuất chuẩn, mà chúng tôi đã chuyển hướng đến điều khiển văn bản. Hãy dùng thử để xem nó hoạt động tốt như thế nào


kết thúc

Bây giờ bạn đã biết một số phương pháp khác nhau để chuyển hướng thiết bị xuất chuẩn sang tệp. Một số phương pháp tốt hơn những phương pháp khác. Cá nhân tôi nghĩ thật tuyệt khi Python 3 hiện đã tích hợp sẵn trình quản lý ngữ cảnh chỉ dành cho mục đích này. Nhắc mới nhớ, Python 3 cũng có chức năng chuyển hướng stderr. Tất cả các ví dụ này có thể được sửa đổi một chút để hỗ trợ chuyển hướng thiết bị xuất chuẩn hoặc cả thiết bị xuất chuẩn và thiết bị xuất chuẩn. Điều cuối cùng chúng tôi chạm vào là chuyển hướng thiết bị xuất chuẩn sang điều khiển văn bản trong wxPython. Điều này có thể thực sự hữu ích để gỡ lỗi hoặc lấy đầu ra từ một quy trình con, mặc dù trong trường hợp sau, bạn sẽ cần in đầu ra để nó được chuyển hướng chính xác