Python语法速查:系统交互

neevop 十二月 10, 2022

Exit

Exits the interpreter by raising SystemExit exception.

import sys
sys.exit()                        # Exits with exit code 0 (success).
sys.exit(<el>)                    # Prints to stderr and exits with 1.
sys.exit(<int>)                   # Exits with passed exit code.

Print

print(<el_1>, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
  • Use 'file=sys.stderr' for messages about errors.
  • Use 'flush=True' to forcibly flush the stream.

Pretty Print

from pprint import pprint
pprint(<collection>, width=80, depth=None, compact=False, sort_dicts=True)
  • Levels deeper than ‘depth’ get replaced by ‘…’.

Input

Reads a line from user input or pipe if present.

<str> = input(prompt=None)
  • Trailing newline gets stripped.
  • Prompt string is printed to the standard output before reading input.
  • Raises EOFError when user hits EOF (ctrl-d/ctrl-z⏎) or input stream gets exhausted.

Command Line Arguments

import sys
scripts_path = sys.argv[0]
arguments    = sys.argv[1:]

Argument Parser

from argparse import ArgumentParser, FileType
p = ArgumentParser(description=<str>)
p.add_argument('-<short_name>', '--<name>', action='store_true')  # Flag.
p.add_argument('-<short_name>', '--<name>', type=<type>)          # Option.
p.add_argument('<name>', type=<type>, nargs=1)                    # First argument.
p.add_argument('<name>', type=<type>, nargs='+')                  # Remaining arguments.
p.add_argument('<name>', type=<type>, nargs='*')                  # Optional arguments.
args  = p.parse_args()                                            # Exits on error.
value = args.<name>
  • Use 'help=<str>' to set argument description that will be displayed in help message.
  • Use 'default=<el>' to set the default value.
  • Use 'type=FileType(<mode>)' for files. Accepts ‘encoding’, but ‘newline’ is None.

Open

Opens the file and returns a corresponding file object.

<file> = open(<path>, mode='r', encoding=None, newline=None)
  • 'encoding=None' means that the default encoding is used, which is platform dependent. Best practice is to use 'encoding="utf-8"' whenever possible.
  • 'newline=None' means all different end of line combinations are converted to ‘\n’ on read, while on write all ‘\n’ characters are converted to system’s default line separator.
  • 'newline=""' means no conversions take place, but input is still broken into chunks by readline() and readlines() on every ‘\n’, ‘\r’ and ‘\r\n’.

Modes

  • 'r' - Read (default).
  • 'w' - Write (truncate).
  • 'x' - Write or fail if the file already exists.
  • 'a' - Append.
  • 'w+' - Read and write (truncate).
  • 'r+' - Read and write from the start.
  • 'a+' - Read and write from the end.
  • 't' - Text mode (default).
  • 'b' - Binary mode ('br', 'bw', 'bx', …).

Exceptions

  • 'FileNotFoundError' can be raised when reading with 'r' or 'r+'.
  • 'FileExistsError' can be raised when writing with 'x'.
  • 'IsADirectoryError' and 'PermissionError' can be raised by any.
  • 'OSError' is the parent class of all listed exceptions.

File Object

<file>.seek(0)                      # Moves to the start of the file.
<file>.seek(offset)                 # Moves 'offset' chars/bytes from the start.
<file>.seek(0, 2)                   # Moves to the end of the file.
<bin_file>.seek(±offset, <anchor>)  # Anchor: 0 start, 1 current position, 2 end.
<str/bytes> = <file>.read(size=-1)  # Reads 'size' chars/bytes or until EOF.
<str/bytes> = <file>.readline()     # Returns a line or empty string/bytes on EOF.
<list>      = <file>.readlines()    # Returns a list of remaining lines.
<str/bytes> = next(<file>)          # Returns a line using buffer. Do not mix.
<file>.write(<str/bytes>)           # Writes a string or bytes object.
<file>.writelines(<collection>)     # Writes a coll. of strings or bytes objects.
<file>.flush()                      # Flushes write buffer. Runs every 4096/8192 B.
  • Methods do not add or strip trailing newlines, even writelines().

Read Text from File

def read_file(filename):
    with open(filename, encoding='utf-8') as file:
        return file.readlines()

Write Text to File

def write_to_file(filename, text):
    with open(filename, 'w', encoding='utf-8') as file:
        file.write(text)

Paths

from os import getcwd, path, listdir, scandir
from glob import glob
<str>  = getcwd()                   # Returns the current working directory.
<str>  = path.join(<path>, ...)     # Joins two or more pathname components.
<str>  = path.abspath(<path>)       # Returns absolute path.
<str>  = path.basename(<path>)      # Returns final component of the path.
<str>  = path.dirname(<path>)       # Returns path without the final component.
<tup.> = path.splitext(<path>)      # Splits on last period of the final component.
<list> = listdir(path='.')          # Returns filenames located at path.
<list> = glob('<pattern>')          # Returns paths matching the wildcard pattern.
<bool> = path.exists(<path>)        # Or: <Path>.exists()
<bool> = path.isfile(<path>)        # Or: <DirEntry/Path>.is_file()
<bool> = path.isdir(<path>)         # Or: <DirEntry/Path>.is_dir()
<stat> = os.stat(<path>)            # Or: <DirEntry/Path>.stat()
<real> = <stat>.st_mtime/st_size/  # Modification time, size in bytes, …

DirEntry

Unlike listdir(), scandir() returns DirEntry objects that cache isfile, isdir and on Windows also stat information, thus significantly increasing the performance of code that requires it.

<iter> = scandir(path='.')          # Returns DirEntry objects located at path.
<str>  = <DirEntry>.path            # Returns whole path as a string.
<str>  = <DirEntry>.name            # Returns final component as a string.
<file> = open(<DirEntry>)           # Opens the file and returns a file object.

Path Object

from pathlib import Path
<Path> = Path(<path> [, ...])       # Accepts strings, Paths and DirEntry objects.
<Path> = <path> / <path> [/ ...]    # First or second path must be a Path object.
<Path> = Path()                     # Returns relative cwd. Also Path('.').
<Path> = Path.cwd()                 # Returns absolute cwd. Also Path().resolve().
<Path> = Path.home()                # Returns user's home directory (absolute).
<Path> = Path(__file__).resolve()   # Returns script's path if cwd wasn't changed.
<Path> = <Path>.parent              # Returns Path without the final component.
<str>  = <Path>.name                # Returns final component as a string.
<str>  = <Path>.stem                # Returns final component without extension.
<str>  = <Path>.suffix              # Returns final component's extension.
<tup.> = <Path>.parts               # Returns all components as strings.
<iter> = <Path>.iterdir()           # Returns directory contents as Path objects.
<iter> = <Path>.glob('<pattern>')   # Returns Paths matching the wildcard pattern.
<str>  = str(<Path>)                # Returns path as a string.
<file> = open(<Path>)               # Also <Path>.read/write_text/bytes().

OS Commands

import os, shutil, subprocess
os.chdir(<path>)                    # Changes the current working directory.
os.mkdir(<path>, mode=0o777)        # Creates a directory. Permissions are in octal.
os.makedirs(<path>, mode=0o777)     # Creates all path's dirs. Also: `exist_ok=False`.
shutil.copy(from, to)               # Copies the file. 'to' can exist or be a dir.
shutil.copytree(from, to)           # Copies the directory. 'to' must not exist.
os.rename(from, to)                 # Renames/moves the file or directory.
os.replace(from, to)                # Same, but overwrites 'to' if it exists.
os.remove(<path>)                   # Deletes the file.
os.rmdir(<path>)                    # Deletes the empty directory.
shutil.rmtree(<path>)               # Deletes the directory.
  • Paths can be either strings, Paths or DirEntry objects.
  • Functions report OS related errors by raising either OSError or one of its subclasses.

Shell Commands

<pipe> = os.popen('<command>')      # Executes command in sh/cmd. Returns its stdout pipe.
<str>  = <pipe>.read(size=-1)       # Reads 'size' chars or until EOF. Also readline/s().
<int>  = <pipe>.close()             # Closes the pipe. Returns None on success.

Sends ‘1 + 1’ to the basic calculator and captures its output:

>>> subprocess.run('bc', input='1 + 1\n', capture_output=True, text=True)
CompletedProcess(args='bc', returncode=0, stdout='2\n', stderr='')

Sends test.in to the basic calculator running in standard mode and saves its output to test.out:

>>> from shlex import split
>>> os.popen('echo 1 + 1 > test.in')
>>> subprocess.run(split('bc -s'), stdin=open('test.in'), stdout=open('test.out', 'w'))
CompletedProcess(args=['bc', '-s'], returncode=0)
>>> open('test.out').read()
'2\n'