zoukankan      html  css  js  c++  java
  • 系统编程概述


    系统编程概述

      主要集中在介绍sys和os模块,sys模块负责导出与python解释器本身相关的组件,os则包含与python所在底层操作系统相对应的变量和函数。


    一、获取模块文档

    import sys
    dir(sys) #显示模块属性
    help(sys) #获取模块的帮助信息


    使用程序的两种方

    1、导入运行
      在统一进程中加载运行代码,生成模块对象,运行较快。
    2、命令行启动执行
      启动独立的进程运行

    sys模块

    sys.path          #模块搜索路径
    sys.modules         #已加载的模块
    sys.getrefcount    #对象引用次数
    sys.argv          #命令行参数
    sys.stdout       #标准流
    sys.stdin
    sys.stderr

    os模块

    该模块提供了POSIX工具,操作系统调用的跨平台移植标准。
    os.getpid()      #给出调用函数的进程ID
    os.path        #目录处理相关工具
    os.system      #运行shell命令,阻塞式。
    os.popen        #运行shell命令,可实现标准流控制,非阻塞。
    os.subprocess     #复杂流控制

    管道对象

    封装了_iter_方法,支持迭代,可实现进程间的通信。


    二、脚本运行上下文

    CWD、文件、import路径

      python会把脚本所在路径添加到模块搜索路径的最前面

    命令行参数

      sys.argv

    解析命令行参数

      使用getopt、optparse等模块

    shell环境变量

      os.environ

      一个子程序始终从它的父进程那里继承环境变量。

     

    标准流

      标准流是预先打开的python对象,在python启动时自动连接到程序里,默认是被绑定在控制台窗口。
      linux shell下标准流的用法
        (1)shell作为init的一个子进程,是操作提供提供给用户的交互接口,当shell被启动之后,标准输入就被绑定在shell窗口的控制台。
        (2)shell环境下执行shell命令,该命令以单独的进程运行,其执行结果应由执行命名控制,标准输出和标准错误可被指定到文件、控制台或管道等。
          例:
            wget -SO /dev/null http://url 2>/dev/null
              执行该命名之后,标准错误会被重定向到/dev/null。
        (3)管道
          将标准输出绑定到管道文件,并且将下一个程序的标准输入绑定到这个管道文件,从而实现进程之间的通信。
          例:
            echo "1" |xargs echo ;echo 1
        (4)标准输入,标准输出、标准错误
          这三个标准流对应于系统0,1,2这三个文件描述符。
      标准流的接口
        echo   #linux中典型的标准输出接口
        read   #linux中典型的标准输入接口,按行读取识别 。
        input   #python中典型的标准输入接口,按行读取识别 。
        print    #python中典型的标准输出接口

      实例讲解
        #teststream.py
        #读取标准输入,再进行处理

     1     def interact():
     2       print('Hello stream world')
     3 
     4       while True:
     5         try:
     6           reply = input('Enter a number>')
     7         except EOFError:
     8           break
     9         else:
    10           num = int(reply)
    11           print("%d squared is %d" % (num, num ** 2))
    12           print('Bye')
    13           
    14      if __name__ == '__main__':
    15        interact()
    16 
    17     #more.py实现分页显示
    18     def more(text, numlines=15):
    19       lines = text.splitlines()
    20       while lines:
    21         chunk = lines[:numlines]
    22         lines = lines[numlines:]
    23         for line in chunk: 
    24           print(line)
    25         if lines and input('more?') not in ['x', 'y']: break
    26 
    27     if __name__ == '__main__':
    28       import sys
    29       print(sys.stdin)
    30       #more(open(sys.argv[1]).read(), 10)    #该输入对象需要支持文件对象打开的方法
    31       more(sys.stdin.read(), 10)

            命令行执行
              python teststream.py < input.txt | python more.py
              该命令在执行时,如果teststream.py输出的信息过多的话,会导致more.py文件执行异常。

            异常解析
              teststream.py在执行时以input.txt为标准输入,标准输出被重定向到管道文件,more.py文件的标准输入文件被重定向到管道中,
              当more.py需要进行分页判断的时候,无法从控制台捕获用户的输入,会直接从管道文件读取,这时执行会出现异常。

            处理办法
              在more.py文件需要从控制台捕获用户输入的时候,可以先检查下当前的stdin是否被绑定在控制中。


    重定向流到python对象

      标准流的重定向不仅仅能够在shell环境下使用,可以在任何语言中实现,包括python:

    >>提供任何类似于文件read方法的对象可以指定给sys.stdin
    >>提供任何类似于文件write方法的对象可以指定给sys.stdout
    print,input只是简单的调用sys.stdin或sys.stdout对象的read或write方法,而sys.stdin和sys.stdout是直接与标准流对应的。


          标准流重定义python对象的实例:

     1           import sys
     2           class Output:
     3               def __init__(self):
     4                   self.text = ''
     5               def write(self, string):
     6                   self.text += string        #追加写
     7               def writelines(self, lines):    #提供列表对象,迭代写入
     8                   for line in lines: self.write(line)
     9           class Input:          
    10               def __init__(self, input=''):    #初始化输入流对象    
    11                   self.text = input    
    12               def read(self, size=None):    #按直接读取
    13                   if size == None:            #默认全部读取
    14                       res, self.text = self.text, ''
    15                   else:
    16                       res, self.text = self.text[:size], self.text[size:]    
    17                   return res
    18               def readlines(self):                #按行读取
    19                   eoln = self.text.find('
    ')    #根据
    来定位字符索引位置,根据索引来读取
    20                   if eoln == -1:
    21                        res, self,text = self.text, ''
    22                   else:
    23                        res, self.text = self.text[:eoln+1], self.text[eoln+1:]    
    24           class redirect(function, pargs, kargs, input):
    25               savesteams = sys.stdin, sys.stdout
    26               sys.stdin  = Input(input)        #重定向流到python输入和输出对象
    27               sys.stdout = Output()
    28               try:
    29                   result = function(*pargs, *kargs)
    30                   output = sys.stdout.text    #获取标准输出文本
    31               finally:
    32                   sys.stdin, sys.stdout = savesteams    #重置输入输出流
    33               return result, output
    34           
    35           if __name__ == '__main__':
    36               (result, output) = redirect(interact, (), {}, '4
    5
    6
    ')
    37               print(result)
    38         

          实用案例
            可利用输入和输出重定向到python对象的机制,实现GUI程序的输入和输出弹窗信息输出。

    三、实用工具类io.String和io.BytesIO

       该工具类提供了一个对象,将一个文件对象接口和内存字符串相映射:

    >>from io import StringIO
    >>buff =StringIO()
    >>buff.write('spam ')
    >>buff.getvalue()

    >>buff =StringIO('spam ')
    >>buff.readline()

      #字节使用参照以上用法

      捕获stderr流
        在python中使用sys.stderr.write()函数即可
      print函数中使用重定向
        print(stuff, file=afile) #原生支持流重定向,一次性的
      其他重定向选项:os.popen和子进程

    os.popen
    subprocess.Popen
    它们可以在python程序内部重定向另外一个程序的流,可实现读取另一个程序的输出,类似于shell中管道的功能。
    作用范围仅在启动的子程序中使用。

      为生成程序的标准输入流提供输入

    >>pipe = os.popen('python hello-in.py', 'w') #对stdin进行写操作,默认是对stdout进行读操作
    >>pipe.write('spam ') #可实现对另一程序的输入控制
    >>pipe.close()
    >>open('hello-in.txt').read()

    利用subprocess重定义输入和输出

    更细粒度地控制生成程序的流,并实现双向通信(访问一个程序的输入和输出),将一个程序的输出发送到另一程序的输入。
    示例:

    pipe = Popen('python reader.py', stdin=PIPE, stdout=PIPE)
    pipe.stdin.write(b'Lumberjack ') #写入标准输入
    pipe.stdin.close()
    output = pipe.stdout.read() #读取标准输出
    pipe.wait()
    print(output)

    以上示例在一个终端console上启动一个子程序并获取到了这个子程序的输出信息。

      比较

    os.popen实现的管道只能读或者写,处于单工运行状态,我们无法在代码中获取第二个脚本的输出。
    import os
    p1 = os.popen('python reader.py', 'r') #为标准输出提供输出管道(读操作)
    p2 = os.popen('python writer.py', 'w') #为标准输入提供输入管道(写操作)
    p2.write(p1.read()) #将p1的输出信息重定向到p2的输入
    x = p2.close() #该步骤无法获取p2的输出信息,默认打印在console上
    print(x)



  • 相关阅读:
    phpstorm使用svn爆出“cannot load supported formats” 的解决
    本地wamp的Internal Server Error错误解决方法
    mac下apache的多站点配置
    Git 一些错误的解决方法
    【总结整理】登录模块---摘自《人人都是产品经理》
    【总结整理】产品经理优秀品质----《结网》
    【总结整理】传统行业如何合理利用互联网思维----摘自《人人都是产品经理》
    【总结整理】租房产品创业的三个方向和三个产品---摘自《人人都是产品经理》
    【总结整理】KANO 模型
    【总结整理】关于GrowingIO、友盟、google analysis等数据分析
  • 原文地址:https://www.cnblogs.com/solitarywares/p/10149325.html
Copyright © 2011-2022 走看看