创建自定义sys.stdout类?

Duc*_*uck 6 python stdout

我想要做的只是让一些终端命令的输出打印到wx.TextCtrl小部件.我认为最简单的方法是创建一个自定义的stdout类,并将write函数重载为widget的.

stdout类:

class StdOut(sys.stdout):
    def __init__(self,txtctrl):
        sys.stdout.__init__(self)
        self.txtctrl = txtctrl

    def write(self,string):
        self.txtctrl.write(string)
Run Code Online (Sandbox Code Playgroud)

然后我会做以下事情:

sys.stdout = StdOut(createdTxtCtrl)    
subprocess.Popen('echo "Hello World!"',stdout=sys.stdout,shell=True)
Run Code Online (Sandbox Code Playgroud)

结果是以下错误:

Traceback (most recent call last):
File "mainwindow.py", line 12, in <module>
from systemconsole import SystemConsole
File "systemconsole.py", line 4, in <module>
class StdOut(sys.stdout):
TypeError: Error when calling the metaclass bases
file() argument 2 must be string, not tuple
Run Code Online (Sandbox Code Playgroud)

任何解决这个问题的想法都将受到赞赏.

Ale*_*lli 13

sys.stdout不是一个class,这是一个实例(类型file).

那么,就这样做:

class StdOut(object):
    def __init__(self,txtctrl):
        self.txtctrl = txtctrl
    def write(self,string):
        self.txtctrl.write(string)

sys.stdout = StdOut(the_text_ctrl)
Run Code Online (Sandbox Code Playgroud)

无需继承file,只需制作一个像这样的简单文件对象! 鸭子打字是你的朋友......

(请注意,在Python中,与大多数其他OO语言一样,但与Javascript不同,您只能从类AKA类型继承,永远不会从类/类型的实例继承;-).

  • 我尝试了这个,结果是:Traceback(最近一次调用最后一次):文件"blade_gui.py",第179行,在OnNew subprocess.Popen('echo"Hello World!"',stdout = sys.stdout,shell =真)文件"C:\ Python26\lib\subprocess.py",第614行,在__init__ errread,errwrite)= self._get_handles(stdin,stdout,stderr)文件"C:\ Python26\lib\subprocess.py",第734行,在_get_handles中c2pwrite = msvcrt.get_osfhandle(stdout.fileno())AttributeError:'StdOut'对象没有属性'fileno' (5认同)
  • 你需要的不仅仅是`write`,你还需要`flush`,也许还有其他一些,取决于它将如何使用. (4认同)
  • `subprocess`可以执行用任何语言编写的程序(不仅仅是Python!),因此需要一个"真正的OS级文件"(即带有FD的文件,也称为fileno) - 无法传递任何东西作为` stdout =``subprocess.Popen`除了真正的操作系统级文件(包括,幸运的是,`subprocess.PIPE`,它允许你的父进程接收子进程的输出 - 但是,在子进程中缓冲通常意味着这不是不管你想要什么,所以我总是建议使用`pexpect`或`wexpect`代替). (2认同)