zoukankan      html  css  js  c++  java
  • 外部程序调用+装饰器-16

    pycharm简介

    现成的工具软件,都可以完成一些功能(wget下载文件,ffmpeg多媒体视频音频文件的切割,转换、合并视频,录制)

    有时需要扩展一下,添加一点功能(free查看某一固定点内存使用)

    有时需要把工具软件组合起来(free、gnuplot画图表)

    粘合各种外部程序和各种语言的库,实现功能,方法:

    os.system

    subprocess

    调用外部程序

    os库里面的system函数,等于打开操作系统的shell,敲入一串命令,比如mspaint 命令

    import os

    os.system('mspaint')

    print ('after call')

    直到外部程序退出了,代码才接着往下执行

    上面的最后一行打印的‘after call’直到我们关闭画笔程序才会接着往下执行

    组装参数

    工具软件命令行支持参数,组装出相应的参数

    import os

    os.system('mspaint e:\1.png')  #打开图片

    print ('after call')

    组装复杂参数

    ffmpeg

    录制屏幕右上角例子

    #coding = utf8

    import time,os

    #输出视频文件

    outputfile = 'd:/data/bandicam/tmp/' + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.mp4'

    #工具目录

    ffmpegDir = r'd:/data/bandicam/tmp/ffmpeg.exe'

    setting = [

      '-y -rtbufsize 100M -f gdigrab -framerate 10'   #帧率等

      ‘-offset_x 1000 -offset_y 0 -video_size 640*480, #录制指定屏幕区域

      ‘-draw_mouse 1 -i desktop -c:v libx264’,              #视频编码格式

      '-r 20 -preset medium -tune zerolatency -crt 35',  #视频压缩参数

      '-pix_fmt yuv420p -fs 100M -movflags +faststart "%s"' %outputfile             #大小限制等

    ]

    #将参数组合起来

    recordingCmdLine = ' '.join([ffmpegDir] + setting)

    #查看命令内容

    print (recordingCmdLine)

    #执行命令录制视频

    os.system(recordingCmdLine)

    返回值

    有些程序退出后会有一个退出码

      表示程序是否正确实现了其功能

      Linux的命令 比如 ls ; echo $?(退出码是0,表示命令执行成功)

    python在调用这些程序时,退出码作为返回值返回

    Windows

      如果是cmd.exe ,返回值就是进程的退出码(退出码为0)

    Linux

    会返回一个16位数字

    低位字节 表示结束进程的信号数值

    如果低位字节值为0,高位字节表示退出码       512转换为十六进制,两位代表一个字节   ‘%x’ %512 -》200,低位0,高位是2;退出码是2

    可以通过返回值来判断命令是否执行成功

    import os

    ret = os.system('cp /opt/file1 /home/hyz/file1')

    if ret == 0:

      print ('file copied.')

    else:

      print ('copy file failed!!')

    subprocess 获取第三方输入内容

    subprocess 库里面的check_output

    import subprocess

     #shell=True 表示使用终端shell执行程序,Windows下面就是cmd.exe

     #就是我们python程序调用cmd.exe,再由cmd.exe执行参数命令

    ret = subprocess.check_output('dir', shell = True,encoding = 'gbk')  encoding不填最终返回byte,填上参数自动解码成Unicode

    #如果有中文,需要decode,因为中文os,所以cmd.exe输出是gbk编码

    print(ret)

    #print (ret.decode('gbk'))

    subprocess.check_output 需要等到被调用程序退出,才能返回

    subprocess库里面的Popen类,可以:被调用程序运行时候,就获取其输出的信息;运行时,输入一些信息给被调用程序

    subprocess.Popen(args,stdin =None,stout = None,stderr = None,shell = False,encoding = None)

    args 参数要么是列表,要么是一个字符串 

       popen = Popen(args = ['mspaint',r'e:1.jpg'])

    shell = True 表示用shell去执行,args 应该是字符串;

    shell = False表示不是用shell去执行,args参数应该是一个列表

    非阻塞式调用

    非阻塞式调用外部程序

    from subprocess import PIPE,Popen

    process = Popen(

      args = 'mspaint',

      shell = True

      )

    print ('done')

    调用外部程序后,python程序继续执行

    输入输出重定向

    得到外部程序的输出

    from subprocess import PIPE,Popen

    popen = Popen(

      'dir c:',

      stout = PIPE,    管道,不指定会输入到终端

      shell = True,

      encoding = 'gbk')

    output, err = popen.communicate()

    print(output)

    import time,trackback

    try:

      while True:

      num = input('**请输入数字:‘)

      if num.isdigit():

        print('立方是: %s' %int(num)**3)

    except:

      print(traceback.format_exc())

    Popen = Popen(

      'python s4_1.py‘,

      stdin = PIPE ,

      stdout = PIPE,

      stderr = PIPE,

      shell = True,

      encoding = 'utf-8')

    inputList = ['3','4','37','55']

    out,err = popen.communicate(' '.join(inoutList)               #3回车,4回车,37回车,55  最后自动输入 EOF(end of file)

    print(out,err)

    装饰器

    函数里面定义函数

    def foo():

      def bar():

        print ('in bar()')  只在函数里使用

      print (‘in foo()’)

      bar()

    foo()

    执行结果:

    in foo()

    in bar()

    bar 的有效范围:函数内部

    在foo()函数外面使用bar()函数的办法:

    def foo():

      def bar():

        print ('in bar()') 

      print (‘in foo()’)

      return bar()

    inner = foo()          返回bar指向bar()

    inner()                   相当于调用bar()

    bar是一个函数对象

    函数里面定义类

    def foo():

      class My():

        pass

      print ('in foo()')

      My()

    foo()

    My的有效范围:函数内部

    定义类的静态的方法时,就使用了装饰器

      @staticmethod

      def jump():

        print ('3 meters high')

    装饰器的特点是用一个@开头的字符串

    在我们阅读别人的代码时,会经常碰到装饰器

    装饰器通常用来装饰函数

    装饰器主要用来给函数增加一点功能

    一般装饰器本身也是一个函数(callable)

    我们可以想象成它包含了被装饰的函数

    例子

    返回字符串的函数

    def hello():

      return 'hello'

    def hi():

      return 'hi'

    我们需要返回值多两个!

    def endsign(func):

      def wrapper():

        return func() + '!!'    闭包

      return wrapper

    @endsign

    def hello():

      return 'hello'

    #hell0 = endsign(hello)

    print (hello())  调用hello()

    有参数的函数

    要装饰的函数参数都不同

    def endsign(func):

      def wrapper(*args,**kargs):

        print('args:', args)

         print('kargs:',kargs)

        return func((*args,**kargs) + '!!'

      return wrapper

    @endsign

    def hello(arg1,arg2 = ' '):

      return 'hello %s %s ' %(arg1,arg2)

    @endsign

    def goodbye(targets):

      return 'goodbye %s ' %'  '.join(targets)

    装饰器本身带参数

    需要的结尾可能不同

    @endsign('!!')

    def hello(arg1,arg2 = ' '):

      return 'hello %s %s ' %(arg1,arg2)

    hello = endsign('!!')

    @endsign('??')

    def hi(arg1,arg2 = ' ');

      return 'hi %s %s' %(arg1,arg2)

    hi = endsign('??')(hi)

     def endsign(tail):

      def innerOne(func):

        def wrapper():

          return func() + '  ' +tail

        return wrapper

      return innerOne

    @enddign('??')

    def hello():

      return 'hello'

    #hello = endsign('??') (hello)

    print (hello())

    endsigns('??')(hello) = innerone(hello) = wrapper

    补充

    我们在写模块文件的时候,对里面的函数往往有些测试代码,调用一下上面写的函数

    如果忘了注释掉,在其他模块导入这个模块的时候,就会执行

    def sayHello():

      print("hello")

    def sayGoodbye():

      print("goodbye")

    print (__name__)

    if __name__ == "__main__"      __name__只在入口模块执行,作为入口模块才会执行,导入到其他文件后不执行

      print ('exec testing')

      sayHell0()

      sayGoodbye()

    可不可以有多个装饰器?可以,定义多个装饰器函数;可以定义多个装饰器修饰一个函数

    def endsign(func):

      def wrapper():

        return func() + '!!'   

      return wrapper

    def endsign2(func):

      def wrapper():

        return func() + '##'   

      return wrapper

    @endsign2

    @endsign 先执行里面的这个

    def hello():

      return 'hello'

    hello = endsign(hello)

    hell0 = endsign2(hello)

    print (hello()) 

      

  • 相关阅读:
    09 图书管理系统(SSM+LayUi)
    06 图书管理系统(SSM+LayUi)
    05 图书管理系统(SSM+LayUi)
    04 图书管理系统(SSM+LayUi)
    在使用IDEA创建SpringBoot的时候出现了Initialization failed for 'https://start.spring.io’Please check URL, network and proxy settings.的错误
    给项目添加Tomcat时找不到项目
    11 图书管理系统(SSM+LayUi)
    SNE降维与可视化
    非线性模型的回归和分类问题——决策树
    从线性回归到逻辑回归
  • 原文地址:https://www.cnblogs.com/hyzhang/p/7716243.html
Copyright © 2011-2022 走看看