1. 程式人生 > >Python3--Subprocess模組學習總結

Python3--Subprocess模組學習總結

Subprocess模組學習整理

1. subprocess模組的用途

subprocess模組用於主動建立新的程序,以執行使用者預期的任務,例如在Windows的CMD執行執行一些指令,或在Linux下執行一些shell指令等。
該模組中的介面,可以替換一些舊版本的模組或函式:

os.system
os.spawn*

以下將通過對官方文件及subprocess模組原始碼做剖析式分析

2. class

subprocess模組共有5個類:
Popen(Object)
CompletedProcess(object)
SubprocessError(Exception)
–CalledProcessError(SubprocessError

)
–TimeoutExpired(SubprocessError)

2.1 SubprocessError

subprocess模組的異常類基類,虛實現

2.2 CalledProcessError

繼承自SubprocessError異常基類,當建立的程序執行返回值非0(執行出錯)時,該異常將會丟擲

2.3 TimeoutExpired

繼承自SubprocessError異常基類,當建立的程序執行時間超出使用者設定的超時時間時,該異常將會丟擲

2.4 CompletedProcess

該類的例項時subprocess的run方法的返回值,代表run方法建立的程序任務執行完畢。
該類只有一個實際作用的方法–check_returncode

class CompletedProcess(object):
    """A process that has finished running.

    This is returned by run().

    Attributes:
      args: The list or str args passed to run().
      returncode: The exit code of the process, negative for signals.
      stdout: The standard output (None if not captured).
      stderr: The standard error (None if not captured).
    """
def __init__(self, args, returncode, stdout=None, stderr=None): self.args = args self.returncode = returncode self.stdout = stdout self.stderr = stderr def __repr__(self): args = ['args={!r}'.format(self.args), 'returncode={!r}'.format(self.returncode)] if self.stdout is not None: args.append('stdout={!r}'.format(self.stdout)) if self.stderr is not None: args.append('stderr={!r}'.format(self.stderr)) return "{}({})".format(type(self).__name__, ', '.join(args)) def check_returncode(self): """Raise CalledProcessError if the exit code is non-zero.""" if self.returncode: raise CalledProcessError(self.returncode, self.args, self.stdout, self.stderr)

2.5 Popen

該類時subprocess模組的核心類,一切與建立程序相關的操作,最終都是以先建立該類的例項為前提,再操作Popen的例項進行方法的呼叫。
subprocess模組中的很多類方法,都是對Popen類進行的封裝,例如subprocess.runsubprocess.call等,
而另外還有一些方法,是對上述已封裝的方法的進一步封裝,例如subprocess.check_callsubprocess.check_output等。

Popen類例項化常用入參解析

    def __init__(self, args, bufsize=-1, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
                 shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0,
                 restore_signals=True, start_new_session=False,
                 pass_fds=(), *, encoding=None, errors=None):
        """Create new Popen instance."""
member description usage
args A string, or a sequence of program arguments args = [“ls”, “-l”]
args = “cmd”
stdin executed programs’ standard input proc=Popen(args, stdin=PIPE,
stdout=PIPE, stderr=PIPE) – 等待stdin
out, err = proc.communicate(input=xxx)
stdout/stderr executed programs’ standard output error output as above
shell If true, the command will be executed through the shell
cwd Sets the current directory before the child is executed
universal_newlines universal_newlines is true, file objects for stdin, stdout and stderr are opened in text mode using the specified encoding. Otherwise, file objects are opened in binary mode
encoding Text mode encoding and error handling to use for file objects stdin, stdout and stderr proc=Popen(args, shell=True, encoding=’gbk’, stdout=PIPE)

同時,Popen支援通過with語句操作的context managers功能

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Popen的主要方法

func description
Popen.poll() Check if child process has terminated. Set and return returncode attribute.
Popen.wait(timeout=None) Wait for child process to terminate. Set and return returncode attribute.
Note: This will deadlock when using stdout=PIPE or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use Popen.communicate() when using pipes to avoid that.
Note: The function is implemented using a busy loop (non-blocking call and short sleeps). Use the asyncio module for an asynchronous wait: see asyncio.create_subprocess_exec.
Popen.communicate(input=None, timeout=None) Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached.
Wait for process to terminate. The optional input argument should be data to be sent to the child process, or None, if no data should be sent to the child. If streams were opened in text mode, input must be a string. Otherwise, it must be bytes
communicate() returns a tuple (stdout_data, stderr_data)
The child process is not killed if the timeout expires, so in order to cleanup properly a well-behaved application should kill the child process and finish communication
Popen.kill() Kills the child
Popen.pid The process ID of the child proces
Popen.returncode The child return code, set by poll() and wait() (and indirectly by communicate()). A None value indicates that the process hasn’t terminated yet.