1 subprocess模块

subprocess是Python的一个标准库模块,它允许你从Python代码中启动新的应用程序或命令,与它们交互并获取它们的输出。这个模块提供了一个简单而一致的接口来替代旧的模块和函数,如os.system()os.spawn*()等。

主要功能:

  1. 启动新进程:你可以使用subprocess来启动新的系统命令或应用程序。
  2. 与进程交互:你可以发送输入到进程,并从进程中读取输出。
  3. 等待进程完成:你可以等待进程完成,并获取其返回码。

主要函数和类:

  • **subprocess.run()**:从Python 3.5开始,这是执行子进程并等待其完成的推荐方法。
  • **subprocess.call()**:运行命令,等待它完成,然后返回返回码。
  • **subprocess.check_call()**:与call()类似,但如果命令返回非零值,则会引发异常。
  • **subprocess.check_output()**:运行命令并返回其输出。如果命令返回非零值,则会引发异常。
  • **subprocess.Popen()**:这是一个更强大的类,允许你启动并与子进程交互。

使用示例:

  1. 简单地运行命令

    1
    2
    import subprocess
    subprocess.run(["ls", "-l"])
  2. 获取输出

    1
    2
    result = subprocess.run(["echo", "Hello from subprocess!"], capture_output=True, text=True)
    print(result.stdout)
  3. 传递输入

    1
    2
    result = subprocess.run(["grep", "hello"], input="hello world\nhi there", text=True, capture_output=True)
    print(result.stdout)
  4. 错误处理

    1
    2
    3
    4
    try:
    result = subprocess.run(["false"], check=True)
    except subprocess.CalledProcessError as e:
    print(f"Command {e.cmd} failed with error {e.returncode}")

注意事项:

  • 安全性:当使用subprocess模块时,特别是当传递来自不可信来源的参数时,需要小心。避免使用shell=True,因为它可能会导致命令注入攻击。
  • 通信:与子进程的通信应该使用subprocess提供的方法,而不是直接使用sys.stdinsys.stdoutsys.stderr

总之,subprocess模块为Python提供了一个强大而灵活的工具,用于与系统命令和其他应用程序交互。正确和安全地使用它可以帮助你扩展Python的功能,使其能够与系统的其他部分无缝集成。

2 Python的logging模块介绍

logging是Python的标准库模块,提供了一个灵活的框架来记录应用程序的日志消息。与简单的print()语句相比,它提供了更多的功能和配置选项,使得在开发、调试和生产环境中跟踪应用程序的行为变得更加容易。

主要特点:

  1. 多级别日志:提供了多个日志级别,如DEBUG、INFO、WARNING、ERROR和CRITICAL,允许你根据需要记录不同的信息。
  2. 灵活的日志目标:可以将日志消息输出到控制台、文件、HTTP服务器或其他位置。
  3. 可配置性:可以通过配置文件或代码来配置日志系统,包括消息的格式、处理程序等。
  4. 线程安全:在多线程应用程序中安全地使用。

主要组件:

  1. Logger:这是一个记录日志的对象。你可以为应用程序创建多个记录器,每个记录器都有一个名称。
  2. Handler:决定如何处理每个日志消息。例如,StreamHandler将日志消息输出到控制台,而FileHandler将其写入文件。
  3. Formatter:决定日志消息的最终输出格式。
  4. Filter:提供了更细粒度的工具来决定输出哪些日志记录。

使用示例:

  1. 基本用法

    1
    2
    3
    4
    5
    6
    import logging

    logging.basicConfig(level=logging.INFO)
    logging.debug("This is a debug message")
    logging.info("Informational message")
    logging.error("An error has occurred!")
  2. 使用多个处理程序

    定义logger 设置等级 设置文本格式 设置写入头,写入头即输出到terminal还是输出到文本格式,将写入头与文本格式绑定 开始使用

    logger = logging.getLogger(“example_logger”)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    logger = logging.getLogger("example_logger")
    logger.setLevel(logging.DEBUG)

    # Create handlers
    c_handler = logging.StreamHandler()
    f_handler = logging.FileHandler("logfile.log")
    c_handler.setLevel(logging.WARNING)
    f_handler.setLevel(logging.ERROR)

    # Create formatters and add them to handlers
    c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
    f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    c_handler.setFormatter(c_format)
    f_handler.setFormatter(f_format)

    # Add handlers to the logger
    logger.addHandler(c_handler)
    logger.addHandler(f_handler)

    logger.warning("This is a warning")
    logger.error("This is an error")

注意事项:

  • 日志级别:确保正确设置日志级别,以避免在生产环境中记录过多的不必要信息。
  • 性能:虽然logging模块是为性能而设计的,但在高性能应用程序中频繁记录日志可能会产生开销。
  • 日志旋转:当将日志写入文件时,考虑使用RotatingFileHandlerTimedRotatingFileHandler来自动管理日志文件的大小和数量。

总的来说,logging模块为Python提供了一个强大而灵活的日志系统,使得跟踪和调试应用程序变得更加容易。