精华内容
下载资源
问答
  • python反复执行某个命令

    千次阅读 2019-04-08 13:56:02
    /usr/bin/env python #coding=utf-8 # 以需要的时间间隔执行某个命令 importtime, os defre_exe(cmd, inc=60): whileTrue: os.system(cmd); time.sleep(inc) re_exe("echo %time%",5) ...

    #! /usr/bin/env python

    #coding=utf-8

    # 以需要的时间间隔执行某个命令

      

    import time, os

      

    def re_exe(cmd, inc = 60):

     while True:

      os.system(cmd);

      time.sleep(inc)

      

    re_exe("echo %time%"5)

    展开全文
  • 请勿用作商业或者非法用途前言有很多小伙伴会跑来交流群问我们,为什么在 AirtestIDE 可以跑通的脚本,转用 Pycharm 来执行就会出现一大堆问题,难道 Airtest 的脚本只能够在 AirtestIDE 上面跑吗?答案当然是否定的...

    此文章来源于项目官方公众号:“AirtestProject”

    版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途

    前言

    有很多小伙伴会跑来交流群问我们,为什么在 AirtestIDE 可以跑通的脚本,转用 Pycharm 来执行就会出现一大堆问题,难道 Airtest 的脚本只能够在 AirtestIDE 上面跑吗?

    答案当然是否定的。 Airtest 实际上也是基于 python 语法的测试框架,所以在 Pycharm 上面跑 Airtest 脚本当然是可以的。

    但是对于 pycharm 新手来说,有可能会遇到以下问题:

    1.环境中未安装 Airtest 库,导致找不到模块

    2.未在脚本中连接设备

    3.Airtest 的截图文件使用相对路径时,程序找不到

    4.在 pycharm 运行完脚本后不知道怎么看 airtest 的报告

    1.环境中未安装 Airtest 库,导致找不到模块

    之前在官网上看过我们 “本地环境跑 Airtest 脚本” 这个教程的童鞋都知道,使用本地 python 环境跑 Airtest 或者 poco 脚本之前,需要先安装上这俩个库(使用 pip install airtest 和 pip install pocoui 来安装)。

    在 Pycharm 上面跑 Airtest 脚本也是如此,必须保证脚本运行环境下装有 Airtest 库,才可以跑 Airtest 相关的脚本,否则就会出现很多童鞋都反馈过的问题 -- 找不到 Airtest 模块:

    a2667214789df2cafd39dc68d8f76772.png

    ① 如何检查 pycharm 的运行环境中有没有安装 Airtest 库呢?

    我们可以打开 pycharm,依次选择左上角的 文件-->设置,然后在弹出的设置框中选择 项目-->Project Interpreter :

    b7688e3c1488fe34bffcd8b437278f1b.png

    然后可以看到 pycharm 当前使用的 python 环境以及该环境中装有的第三方库。可以看到示例图中的 python 环境是没有安装 airtest 库的,如果在该环境下跑 airtest 的脚本,就会报 no module named airtest 的错误。

    解决办法很简单,在 package 那一行的最右边,点击 +,输入 Airtest ,然后再点击 install package 安装即可。

    c9dbe09575424889ee8fa9cf669225bb.png

    46aae85f8feaf10941228cbfa6071afa.png

    安装完成之后会提示安装成功:

    d931a6cbd5a495136c44a089224b5192.png

    efa9a8bce366302b98e83a34c1a0dee5.png

    ② 虚拟环境问题

    还有些童鞋反馈,他们在本地某个 python 环境上是装好了 airtst 库的,但是在 pycharm 上新建了一个基于这个本地 python 的环境,却始终找不到这个 airtest 库。

    这个就涉及到了 pycharm 的虚拟环境的问题。新建环境默认建的是虚拟环境,这个虚拟环境的意思基于本地某个 python 环境,复制了一个不带任何第三方包的 干净的 Python 虚拟环境 ,已经安装到本地 Python 环境中的所有第三方包都不会复制过来。

    9174931e87a813f7881fddd3eeef6acc.png

    所以这就是为什么尽管童鞋们在本地环境上安装了 airtest 库,并在 pycharm 根据这个本地 python 来新建环境的时候,并不会带上 airtest 库的原因。

    如果不想使用虚拟环境,而是想要用本地的 python 环境来跑脚本,我们可以设置使用现有的 python 环境,这样就可以引入完整的带有安装好的第三方库的环境了:

    315b3a399bfea6dab8a1bf800b45ecb3.png

    2.未在脚本中连接设备

    在 AirtestIDE 中,我们可以在设备窗口中一键连接上我们的测试设备,然后再在脚本编辑窗口录制 Airtest 脚本即可。

    但是在 pycharm 编写 Airtest 脚本的时候,童鞋们往往忘记在初始化脚本的时候添加设备连接参数,导致运行 Airtest 脚本时出现各种设备未连接的报错,其中典型的报错有:

    23078309c0117d02adb521c5be215c10.png

    下面举几个添加设备参数的例子:

    # 方法一:在auto_setup()接口添加设备

    auto_setup(__file__,devices=["Android://127.0.0.1:5037/SJE5T17B17"])

    # 方法二:用connect_device()方法连接设备

    dev = connect_device("Android://127.0.0.1:5037/SJE5T17B17")

    # 方法三:用init_device()方法连接设备

    init_device(platform="Android",uuid="SJE5T17B17")

    以上三种方法任选其一即可,另外这三个接口的详细使用方法,我们在往期推文 “用 1 行代码搞定自动化测试的设备连接问题” 中有详细介绍,有需要的童鞋可以认真看一下~

    对于使用了备选连接参数才可以正常连接上的设备,比如模拟器、MIUI11 等,我们也需要在连接设备的字符串后面加上这些连接参数(以 auto_setup 接口为例):

    auto_setup(__file__,devices=["Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP&&ori_method=ADBORI"])

    3.airtest 的截图文件使用相对路径时,程序找不到

    在 AirtestIDE 录制截图脚本的时候,截图文件都默认保存在当前脚本的所在路径下,且截图脚本上默认填写的路径也是相对路径:

    touch(Template(r"tpl1590718697837.png", rgb=True, record_pos=(-0.383, 0.717), resolution=(1080, 1920)))

    程序可以根据这个相对路径找到截图文件的原因在于,我们利用 auto_setup(__file__) 初始化脚本的时候,传入了一个 basedir(参数值为file,即当前脚本所在路径),程序会默认根据这个 basedir 去寻找脚本中存在的相对路径。

    所以当我们在 pycharm 上新建项目,并把在 AirtestIDE 上跑通的测试脚本复制粘贴过来时,这个 basedir 就变成了 pycharm 新建项目的所在路径,程序会根据新建项目的所在目录去寻找截图脚本中的相对路径。

    因此我们要把脚本中用到的截图文件,也复制到新建项目的所在目录下,这样才可以让程序根据截图脚本上的相对路径正确找到我们的截图文件。

    如果我们没有一并把截图文件复制到新建项目的目录下,就直接运行脚本,会出现 airtest.aircv.error.FileNotExistError: File not exist: tpl1590718697837.png 的报错:

    7487da694ed1a7464598b9bcea9984ba.png

    当然我们也可以选择把截图脚本上面的相对路径,改成绝对路径,这样程序也能够根据绝对路径找到我们的截图文件:

    touch(Template(r"D:/test/tpl1590718697837.png", rgb=True, record_pos=(-0.383, 0.717), resolution=(1080, 1920)))

    4.在 pycharm 运行完脚本后不知道怎么看 airtest 的报告

    之前我们在使用 AirtestIDE 的时候,运行完脚本以后,我们就可以点击顶部菜单栏上的查看报告按钮,帮助我们快捷地生成并打开相应的 html 报告。

    但在 pycharm 执行完脚本以后,就没有什么快捷按钮帮助我们生成报告了,所以需要生成报告的童鞋,务必记住在要在脚本中调用生成报告的接口来帮助我们生成报告,以 simple_report() 这个生成报告的接口为例,我们可以使用如下方式生成 airtest 的报告:

    # generate html report

    from airtest.report.report import simple_report

    simple_report(__file__, logpath=True)

    simple_report() 的详细使用方法可以参考我们的往期推文 “从.air 脚本到纯.py 脚本的距离究竟有多远” ,里面不仅详细介绍了 simple_report() 的使用方法,还给我们介绍了脚本初始化接口 auto_setup() 的详细用法。

    ①脚本报错导致最后的生成报告语句没有执行

    有些童鞋把生成脚本的语句放在了脚本的最后面,希望跑完测试脚本以后,能够生成一个测试报告。但是有时候程序还没有运行到生成报告的脚本时就报错了,导致程序终止运行,最终没有生成报告。

    其实我们是希望不论测试用例能不能执行通过,都可以给我们一个报告反馈,所以我们可以使用 try-finally 语句,无论是否发生异常都将执行最后的代码:

    try:

    touch(Template(r"tpl1590718697837.png", threshold=0.9, record_pos=(0.378, 0.098), resolution=(1080, 1920)))

    finally:

    # generate html report

    simple_report(__file__, logpath=True)

    Airtest 官网:airtest.netease.com/

    Airtest 教程官网:airtest.doc.io.netease.com/

    搭建企业私有云服务:airlab.163.com/b2b

    关注下方公众号,可以查看更多往期教程,回复 “交流群” 可以加入我们的官方开发者交流群

    1948ee735a453a5903235770f5def9d4.png

    展开全文
  • 实现一个shell脚本,不停地询问用户要执行什么操作,直到用户输入quit才会退出,否则脚本一直这样运行下去。我们直到while循环是在测试条件满足的情况下执行循环体,一直到条件不满足时终止循环,如果我们需要的循环...

    实现一个shell脚本,不停地询问用户要执行什么操作,直到用户输入quit才会退出,否则脚本一直这样运行下去。我们直到while循环是在测试条件满足的情况下执行循环体,一直到条件不满足时终止循环,如果我们需要的循环是在测试条件不满足的情况下执行循环体,而当测试条件满足以后就停止并结束循环。

    解决方案:

    当然只要对测试条件进行修改,我们就还是可以使用while来实现这样的需求。不过bash为我们提供了更适合这种情况的语句:until语句#!/bin/bash

    QUIT_COMMAND=quit

    #直到用户输入的字符串是quit时,until循环才会退出

    until [ "$USER_INPUT" = "$QUIT_COMMAND" ]

    do

    echo "Please input command"

    echo "(type command $QUIT_COMMAND to exit)"

    read USER_INPUT

    echo

    echo ">>your command is $USER_INPUT"

    #对用户的输入进行匹配

    case $USER_INPUT IN

    "open")

    echo ">>opening..."

    ;;

    "close")

    echo ">>closed"

    ;;

    *)

    echo ">>Unknown command"

    ;;

    esac

    echo

    done

    echo "Bye."

    exit 0

    在bash手册中,until的语法和while语句的语法一样,都是在循环的前面先测试一个条件,以此来决定是否要执后面的循环体。

    如果把do和条件测试放到同一行,则两者中间需要用分号;分隔。即until xxx;do xxxx;done

    如果把都和条件测试分别放到不同行,则可以省略分号。即until  xxx

    do

    xxx

    done

    在测试命令[]中,这里使用了=来比较两个字符串是否相等。在条件表达式中比较两个整数的大小关系与比较两个字符串是否相等,使用的是不同的操作符。其他字符串的操作符还有:-n STRING                              #字符串长度如果为非0则返回真

    -z STRING                              #字符串长度如果为0 则返回真

    STRING1 = STRING2             #两个字符串相同则返回真

    STRING1! = STRING2            #两个字符串不相同则返回真

    只有当用户输入的命令为“quit”时,until后面的条件测试[ "$USER_INPUT" =  “$QUIT_COMMAND”]

    为真,循环结束。

    拓展练习:

    使用until循环写一个脚本,测试192.168.1.30--192.168.1.130区间的网段是否在线。#!/bin/bash

    NETWORK=192.168.1

    IP=30

    #也可以写成until [ ! "$IP" -lt 130 ]

    until [ "$IP" -ge 130 ]

    do

    echo -en "Testing machine at IP address:${NETWORK}.${IP}..."

    ping -c1 -w1 ${NETWORK}.${IP} > /dev/null 2>&1

    #-c是指ping的次数,-w是指执行的最后期限,也就是执行的时间,单位为秒

    #将标准输出或者错误输出的定向到/dev/null

    if [ "$?" -eq 0 ]

    #$?上一条命令执行后返回的状态

    then

    echo "OK"

    else

    echo "Failed"

    fi

    let IP=$ip+1

    done

    提示:shell内建的测试命令[ 和 ] 的两侧需要空格

    在测试命令[]中,使用-eq来比较两个字符串是否相等,比较两个整数的大小关系,以及比较两个字符串是否相等,使用的是不同的操作符

    bash中的until条件测试应该下载循环体的上部,和某些语言中的until不同

    ---------------脚本来源于shell编程艺术,仅作个人笔记使用,如侵权请联系删除

    展开全文
  • 1.4 从python启动其他程序 import subprocess calobj= subprocess.Popen('C:\\Windows\\System32\\calc.exe') #exe的存放地址,返回一个Popen 对象 Popen对象有两个方法:POLL方法和WAIT方法 calobj.poll():若此...

    1. 基础语法

    1.1 time模块

    (1)time.time()函数

    import time

    time = time.time()

    #返回一个浮点数,称为UNIX纪元时间戳,即1970.1.1 00:00 开始的秒数

    (2)time.sleep()函数

    time.sleep(5)

    #希望程序暂停的时间

    (3)round()四舍六入五成双

    now = time.time()

    round(now,2)

    #round函数取到小数点后几位,5前为奇数,舍5入1;5前为偶数,舍5不进

    1.2 datetime模块

    import datetime

    dt = datetime.datetime.now()

    #返回一个datetime对象(年,月,日,时,分,秒),dt.year,dt.month等得到特定时刻的datetime对象

    (1)datetime 与 time转换

    datetime.datetime.fromtimestamp(10000)

    >>>datetime.datetime(1970,1,12,5,46,40)

    datetime.datetime.fromtimestamp(time.time())

    >>>datetime.datetime(2015,2,27,11,13,0,604980)

    #函数 fromtimestamp相互转换

    (2)timedelta数据类型

    delta = datetime.timedelta(days,hours,minutes,seconds)

    #返回以(天,秒,微秒)来表示

    delta.total_seconds()

    #返回以秒计算的时间

    #timedelta表示一段时间,并且可以计算

    (3)将datetime对象转换为字符串

    datetime.strftime()函数将datetime对象转换为格式化的字符串

    datetime.strptime()函数将格式化的字符串转换为datetime对象

    strftime指令strftime指令含义%Y 带世纪的年份,如‘2014’

    %y 不带世纪的年份,‘00’-‘99’

    %m 数字表示的月份,‘01’-‘12’

    %B 完整的月份,‘July’

    %b 简写的月份,‘Jul’

    %d 一月中的第几天,‘01’-‘31’

    %j 一年中的第几天,‘001’-‘366’

    %w 一周中的第几天,‘0’(周日)-‘6’(周六)

    %A 完整的周几,‘Monday’%a简写的周几,‘Mon’

    %H 小时(24h),'00'-'23'%h小时(12h),‘01’-‘12’

    %M 分

    %S 秒

    %p ‘AM/'PM’

    %% %

    dt = datetime.datetime(2017,11,12,11,12,0)

    dt.strftime('%Y/%m/%d%H:%M:%S) #datetime 到字符串

    datetime.datetime.strptime('2015/10/21 16:29:00' , '%Y/%m/%d%H:%M:%S') #格式化字符串到datetime对象

    >>> dt = datetime.datetime(2017,11,12,11,12,0)

    >>> dt.strftime('%Y/%m/%d%H:%M:%S')

    '2017/11/12 11:12:00'

    >>> datetime.datetime.strptime('2015/10/21 16:29:00' , '%Y/%m/%d%H:%M:%S')

    datetime.datetime(2015, 10, 21, 16, 29)

    回顾 Python 的时间函数

    在 Python 中,日期和时间可能涉及好几种不同的数据类型和函数。下面回顾了表示时间的 3 种不同类型的值:Unix 纪元时间戳(time 模块中使用)是一个浮点值或整型值,表示自 1970 年1 月 1 日午夜 0 点(UTC)以来的秒数。

    datetime 对象(属于 datetime 模块)包含一些整型值,保存在 year、 month、 day、hour、 minute 和 second 等属性中。

    timedelta 对象(属于 datetime 模块)表示的一段时间,而不是一个特定的时刻。

    下面回顾了时间函数及其参数和返回值:time.time()函数返回一个浮点值,表示当前时刻的 Unix 纪元时间戳。

    time.sleep(seconds)函数让程序暂停 seconds 参数指定的秒数。

    datetime.datetime(year, month, day, hour, minute, second)函数返回参数指定的时刻的 datetime 对象。如果没有提供 hour、 minute 或 second 参数,它们默认为 0。

    datetime.datetime.now()函数返回当前时刻的 datetime 对象。

    datetime.datetime.fromtimestamp(epoch)函数返回 epoch 时间戳参数表示的时刻的 datetime 对象。

    datetime.timedelta(weeks, days, hours, minutes, seconds, milliseconds, microseconds)函数返回一个表示一段时间的 timedelta 对象。该函数的关键字参数都是可选的,不包括 month 或 year。

    total_seconds()方法用于 timedelta 对象,返回 timedelta 对象表示的秒数。

    strftime(format)方法返回一个字符串,用 format 字符串中的定制格式来表示datetime 对象表示的时间。详细格式参见表 15-1。

    datetime.datetime.strptime(time_string, format)函数返回一个 datetime 对象,它的时刻由 time_string 指定,利用 format 字符串参数来解析。详细格式参见表 15-1。

    1.3 多线程

    (1)多线程启动

    import threading

    #创建一个Thread对象

    threadobj = threading.Thread(target = fx) #fx为想要以第二线程启动的函数名称

    #第二个线程开始

    threadobj.start()

    (2)多参数

    #常规参数作为一个列表传给args,关键字参数作为一个字典传给kwargs

    threadobj = threading.Thread(target = print , args =['cats','dog','rabbit'] , kwargs = {'sep}':'&')

    threadobj.start()

    >>>'cats&dog&rabbit

    注意:多线程可能会由于同时读写变量,导致相互干扰产生并发问题,当创建一个新的Thread对象时,要确保目标函数只使用该函数中的局部变量,从而避免并发问题。

    1.4 从python启动其他程序

    import subprocess

    calobj= subprocess.Popen('C:\\Windows\\System32\\calc.exe')

    #exe的存放地址,返回一个Popen 对象

    Popen对象有两个方法:POLL方法和WAIT方法

    calobj.poll():若此进程在调用poll方法时仍在执行,则返回None,若进程终止:返回0为无错终止,返回1则为错误导致终止

    calobj.wait():将阻塞,直到启动的进程终止(希望你的程序暂停,知道用户完成其他程序)

    Popen的命令行参数:想Popen穿第一个列表,第一个字符是可执行程序名,后续字符串是该程序启东市,传递给该程序的命令行参数。

    subprocess.Popen(['C:\\Windows\\notepad.exe'.'C:\\'hello.txt'])

    2.项目

    2.1 超级秒表

    假设要记录在没有自动化的枯燥任务上花了多少时间。你没有物理秒表,要为笔记本或智能手机找到一个免费的秒表应用,没有广告,且不会将你的浏览历史发送给市场营销人员,又出乎意料地困难(在你同意的许可协议中,它说它可以这样做。

    你确实阅读了许可协议,不是吗?)。你可以自己用 Python 写一个简单的秒表程序。

    总的来说,你的程序需要完成:记录从按下回车键开始,每次按键的时间,每次按键都是一个新的“单圈”。

    打印圈数、总时间和单圈时间。

    这意味着代码将需要完成以下任务:在程序开始时,通过调用 time.time()得到当前时间,将它保存为一个时间戳。在每个单圈开始时也一样。

    记录圈数,每次用户按下回车键时加 1。

    用时间戳相减,得到计算流逝的时间。

    处理 KeyboardInterrupt 异常,这样用户可以按 Ctrl-C 退出。

    打开一个新的文件编辑器窗口,并保存为 stopwatch.py。

    第 1 步:设置程序来记录时间

    #! python3

    # stopwatch.py - A simple stopwatch program.

    import time

    # Display the program's instructions.

    print('Press ENTER to begin. Afterwards, press ENTER to "click" the stopwatch.Press Ctrl-C to quit.')

    input() # press Enter to begin

    print('Started.')

    startTime = time.time() # get the first lap's start time

    lastTime = startTime

    lapNum = 1

    # TODO: Start tracking the lap times.

    第 2 步:记录并打印单圈时间

    #! python3

    # stopwatch.py - A simple stopwatch program.

    import time

    --snip--

    # Start tracking the lap times.

    try:

    while True:

    input()

    lapTime = round(time.time() - lastTime, 2)

    totalTime = round(time.time() - startTime, 2)

    print('Lap #%s:%s(%s)' % (lapNum, totalTime, lapTime), end='')

    lapNum += 1

    lastTime = time.time() # reset the last lap time

    except KeyboardInterrupt:

    # Handle the Ctrl-C exception to keep its error message from displaying.

    print('\nDone.')

    第 3 步:类似程序的想法

    时间追踪为程序打开了几种可能性。虽然可以下载应用程序来做其中一些事情,但自己编程的好处是它们是免费的,而且不会充斥着广告和无用的功能。可以编写类似的程序来完成以下任务:创建一个简单的工时表应用程序,当输入一个人的名字时,用当前的时间记录下他们进入或离开的时间。

    为你的程序添加一个功能,显示自一项处理开始以来的时间,诸如利用 requests模块进行的下载(参见第 11 章)。

    间歇性地检查程序已经运行了多久,并为用户提供了一个机会,取消耗时太长的任务。

    2.2 多线程下载XKCD线程

    第 1 步:修改程序以使用函数

    #! python3

    # multidownloadXkcd.py - Downloads XKCD comics using multiple threads.

    import requests, os, bs4, threading

    os.makedirs('xkcd', exist_ok=True) # store comics in ./xkcd

    def downloadXkcd(startComic, endComic):

    for urlNumber in range(startComic, endComic):

    # Download the page.

    print('Downloading page http://xkcd.com/%s...' % (urlNumber))

    res = requests.get('http://xkcd.com/%s' % (urlNumber))

    res.raise_for_status()

    soup = bs4.BeautifulSoup(res.text)

    # Find the URL of the comic image.

    comicElem = soup.select('#comic img')

    if comicElem == []:

    print('Could not find comic image.')

    else:

    comicUrl = comicElem[0].get('src')

    # Download the image.

    print('Downloading image%s...' % (comicUrl))

    res = requests.get(comicUrl)

    res.raise_for_status()

    # Save the image to ./xkcd.

    imageFile = open(os.path.join('xkcd', os.path.basename(comicUrl)), 'wb')

    for chunk in res.iter_content(100000):

    imageFile.write(chunk)

    imageFile.close()

    # TODO: Create and start the Thread objects.

    # TODO: Wait for all threads to end.

    第 2 步:创建并启动线程

    #! python3

    # multidownloadXkcd.py - Downloads XKCD comics using multiple threads.

    --snip--

    # Create and start the Thread objects.

    downloadThreads = [] # a list of all the Thread objects

    for i in range(0, 1400, 100): # loops 14 times, creates 14 threads

    downloadThread = threading.Thread(target=downloadXkcd, args=(i, i + 99))

    downloadThreads.append(downloadThread)

    downloadThread.start()

    第 3 步:等待所有线程结束

    #! python3

    # multidownloadXkcd.py - Downloads XKCD comics using multiple threads.

    --snip--

    # Wait for all threads to end.

    for downloadThread in downloadThreads:

    downloadThread.join()

    print('Done.')

    Unix 哲学

    程序精心设计,能被其他程序启动,这样的程序比单独使用它们自己的代码更强大。 Unix 的哲学是一组由 UNIX 操作系统(现代的 Linux 和 OS X 也是基于它)的程序员建立的软件设计原则。它认为:编写小的、目的有限的、能互操作的程序,胜过大的、功能丰富的应用程序。

    较小的程序更容易理解,通过能够互操作,它们可以是更强大的应用程序的构建块。智能手机应用程序也遵循这种方式。如果你的餐厅应用程序需要显示一间咖啡店的方位,开发者不必重新发明轮子,编写自己的地图代码。餐厅应用程序只是启动一个地图应用程序,同时传入咖啡店的地址,就像 Python 代码调用一个函数,并传入参数一样。

    你在本书中编写的 Python 程序大多符合 Unix 哲学,尤其是在一个重要的方面:它们使用命令行参数,而不是 input()函数调用。如果程序需要的所有信息都可以事先提供,最好是用命令行参数传入这些信息,而不是等待用户键入它。这样,命令行参数可以由人类用户键入,也可以由另一个程序提供。这种互操作的方式,让你的程序可以作为另一个程序的部分而复用。

    唯一的例外是,你不希望口令作为命令行参数传入,因为命令行可能记录它们,作为命令历史功能的一部分。在需要输入口令时,程序应该调用 input()函数。

    2.3 项目:简单的倒计时程序

    就像很难找到一个简单的秒表应用程序一样,也很难找到一个简单的倒计时程序。让我们来写一个倒计时程序,在倒计时结束时报警。

    总的来说,程序要做到:从 60 倒数。

    倒数至 0 时播放声音文件(alarm.wav)。

    这意味着代码将需要做到以下几点:在显示倒计时的每个数字之间,调用 time.sleep()暂停一秒。

    调用 subprocess.Popen(),用默认的应用程序播放声音文件。

    打开一个新的文件编辑器窗口,并保存为 countdown.py。

    第 1 步:倒计时

    #! python3

    # countdown.py - A simple countdown script.

    import time, subprocess

    timeLeft = 60

    while timeLeft > 0:

    print(timeLeft, end='')

    time.sleep(1)

    timeLeft = timeLeft - 1

    # TODO: At the end of the countdown, play a sound file.

    第 2 步:播放声音文件

    #! python3

    # countdown.py - A simple countdown script.

    import time, subprocess

    --snip--

    # At the end of the countdown, play a sound file.

    subprocess.Popen(['start', 'alarm.wav'], shell=True)

    第 3 步:类似程序的想法

    倒计时是简单的延时,然后继续执行程序。这也可以用于其他应用程序和功能,

    诸如:利用 time.sleep()给用户一个机会,按下 Ctrl-C 取消的操作,例如删除文件。你的程序可以打印“Press Ctrl-C to cancel”,然后用 try 和 except 语句处理所有KeyboardInterrupt 异常。

    对于长期的倒计时,可以用 timedelta 对象来测量直到未来某个时间点(生日?周年纪念?)的天、时、分和秒数。

    小结

    对于许多编程语言,包括 Python, Unix 纪元(1970 年 1 月 1 日午夜, UTC)是一个标准的参考时间。虽然 time.time()函数模块返回一个 Unix 纪元时间戳(也就是自 Unix 纪元以来的秒数的浮点值),但 datetime 模块更适合执行日期计算、格式化和解析日期信息的字符串。

    time.sleep()函数将阻塞(即不返回)若干秒。它可以用于在程序中暂停。但如果想安排程序在特定时间启动, http://nostarch.com/automatestuff/上的指南可以告诉你如何使用操作系统已经提供的调度程序。

    threading 模块用于创建多个线程,如果需要下载多个文件或同时执行其他任务,这非常有用。但是要确保线程只读写局部变量,否则可能会遇到并发问题。

    最后, Python 程序可以用 subprocess.Popen()函数,启动其他应用程序。命令行参数可以传递给 Popen()调用,用该应用程序打开特定的文档。另外,也可以用 Popen()启动 start、 open 或 see 程序,利用计算机的文件关联,自动弄清楚用来打开文件的应用程序。通过利用计算机上的其他应用程序, Python 程序可以利用它们的能力,满足你的自动化需求。

    3.习题

    1.什么是 Unix 纪元?

    许多日期和时间程序使用的一个参考时刻。该时刻是 1970 年 1 月 1 日,UTC。

    2.什么函数返回自 Unix 纪元以来的秒数?

    time.time()

    3.如何让程序刚好暂停 5 秒?

    time.sleep(5)

    4.round()函数返回什么?

    返回与传入参数最近的整数。例如,round(2.4)返回 2。

    5.datetime 对象和 timedelta 对象之间的区别是什么?

    datetime 对象表示一个特定的时刻。timedelta 对象表示一段时间。

    6.假设你有一个函数名为 spam()。如何在一个独立的线程中调用该函数并运行其中的代码?

    threadObj = threading.Thread(target=spam)

    7.为了避免多线程的并发问题,应该怎样做?

    threadObj.start()

    8.如何让Python 程序运行 C:\ Windows\System32 文件夹中的calc.exe 程序?

    subprocess.Popen('c:\\Windows\\System32\\calc.exe')

    4.实践项目

    4.1 美化的秒表

    #! python3

    # stopwatch.py - A simple stopwatch program.

    import time

    # Display the program's instructions.

    print('Press enter to begin. Afterwards, press ENTER to "click" the stopwatch. Press Ctrl-C to quit.')

    input() # press Enter to begin

    print('Started.')

    startTime = time.time() # get the first lap's start time

    lastTime = startTime

    lapNum = 1

    # Start tracking the lap times.

    try:

    while True:

    input()

    lapTime = round(time.time() - lastTime, 2)

    totalTime = round(time.time() - startTime, 2)

    print('Lap #' + str(lapNum).rjust(2) + ':' + ('%.2f' % totalTime).rjust(6) + ' (' + ('%.2f' % lapTime).rjust(5) + ')', end=' ')

    lapNum += 1

    lastTime = time.time() # reset the last lap time

    except KeyboardInterrupt:

    # Handle the Ctrl-C exception to keep its error message from displaying.

    print('\nDone.')

    input('click any key to exit')

    4.2 计划的web漫画下载

    在按规定的时刻检查是否有漫画更新,有的话进行下载。这里用到了schedule模块,以运行计算器为例:

    import schedule,subprocess

    def job():

    subprocess.Popen('C:\\Windows\\System32\\calc.exe')

    schedule.every().day.at("20:41").do(job) #在每一天的规定时刻运行job

    while True:

    schedule.run_pending() #运行所有可以运行的任务

    参考:

    1.计算明天和昨天的日期

    #! /usr/bin/env python

    #coding=utf-8

    # 获取今天、昨天和明天的日期

    # 引入datetime模块

    import datetime

    #计算今天的时间

    today = datetime.date.today()

    #计算昨天的时间

    yesterday = today - datetime.timedelta(days = 1)

    #计算明天的时间

    tomorrow = today + datetime.timedelta(days = 1)

    #打印这三个时间

    print(yesterday, today, tomorrow)

    2.计算上一个的时间

    方法一:

    #! /usr/bin/env python

    #coding=utf-8

    # 计算上一个的时间

    #引入datetime,calendar两个模块

    import datetime,calendar

    last_friday = datetime.date.today()

    oneday = datetime.timedelta(days = 1)

    while last_friday.weekday() != calendar.FRIDAY:

    last_friday -= oneday

    print(last_friday.strftime('%A,%d-%b-%Y'))

    方法二:借助模运算寻找上一个星期五

    #! /usr/bin/env python

    #coding=utf-8

    # 借助模运算,可以一次算出需要减去的天数,计算上一个星期五

    #同样引入datetime,calendar两个模块

    import datetime

    import calendar

    today = datetime.date.today()

    target_day = calendar.FRIDAY

    this_day = today.weekday()

    delta_to_target = (this_day - target_day) % 7

    last_friday = today - datetime.timedelta(days = delta_to_target)

    print(last_friday.strftime("%d-%b-%Y"))

    3.计算歌曲的总播放时间

    #! /usr/bin/env python

    #coding=utf-8

    # 获取一个列表中的所有歌曲的播放时间之和

    import datetime

    def total_timer(times):

    td = datetime.timedelta(0)

    duration = sum([datetime.timedelta(minutes = m, seconds = s) for m, s in times], td)

    return duration

    times1 = [(2, 36),

    (3, 35),

    (3, 45),

    ]

    times2 = [(3, 0),

    (5, 13),

    (4, 12),

    (1, 10),

    ]

    assert total_timer(times1) == datetime.timedelta(0, 596)

    assert total_timer(times2) == datetime.timedelta(0, 815)

    print("Tests passed.\n"

    "First test total:%s\n"

    "Second test total:%s" % (total_timer(times1), total_timer(times2)))

    4.反复执行某个命令

    #! /usr/bin/env python

    #coding=utf-8

    # 以需要的时间间隔执行某个命令

    import time, os

    def re_exe(cmd, inc = 60):

    while True:

    os.system(cmd);

    time.sleep(inc)

    re_exe("echo %time%", 5)

    5.定时任务

    #! /usr/bin/env python

    #coding=utf-8

    #这里需要引入三个模块

    import time, os, sched

    # 第一个参数确定任务的时间,返回从某个特定的时间到现在经历的秒数

    # 第二个参数以某种人为的方式衡量时间

    schedule = sched.scheduler(time.time, time.sleep)

    def perform_command(cmd, inc):

    os.system(cmd)

    def timming_exe(cmd, inc = 60):

    # enter用来安排某事件的发生时间,从现在起第n秒开始启动

    schedule.enter(inc, 0, perform_command, (cmd, inc))

    # 持续运行,直到计划时间队列变成空为止

    schedule.run()

    print("show time after 10 seconds:")

    timming_exe("echo %time%", 10)

    6.利用sched实现周期调用

    #! /usr/bin/env python

    #coding=utf-8

    import time, os, sched

    # 第一个参数确定任务的时间,返回从某个特定的时间到现在经历的秒数

    # 第二个参数以某种人为的方式衡量时间

    schedule = sched.scheduler(time.time, time.sleep)

    def perform_command(cmd, inc):

    # 安排inc秒后再次运行自己,即周期运行

    schedule.enter(inc, 0, perform_command, (cmd, inc))

    os.system(cmd)

    def timming_exe(cmd, inc = 60):

    # enter用来安排某事件的发生时间,从现在起第n秒开始启动

    schedule.enter(inc, 0, perform_command, (cmd, inc))

    # 持续运行,直到计划时间队列变成空为止

    schedule.run()

    print("show time after 10 seconds:")

    timming_exe("echo %time%", 10)

    网络爬虫判断页面是否更新

    1、304页面http状态码

    当第二次请求页面访问的时候,该页面如果未更新,则会反馈一个304代码,而搜索引擎也会利用这个304http状态码来进行判断页面是否更新。

    首先第一次肯定是要爬取网页的,假设是A.html,这个网页存储在磁盘上,相应地有个修改时间(也即是更新这个文件的时间)。

    那么第二次爬取的时候,如果发现这个网页本地已经有了,例如A.html,这个时候,你只需要向服务器发送一个If-Modified-Since的请求,把A.html的修改时间带上去。

    如果这段时间内,A.html更新了,也就是A.html过期了,服务器就会HTTP状态码200,并且把新的文件发送过来,这时候只要更新A.html即可。 如果这段时间内,A.html的内容没有变,服务器就会返返回HTTP状态码304(不返回文件内容),这个时候就不需要更新文件。

    2、Last-Modified文件最后修改时间

    这是http头部信息中的一个属性,主要是记录页面最后一次的修改时间,往往我们会发现,一些权重很高的网站,及时页面内容不更新,但是快照却还是能够每日更新,这其中就有Last-Modified的作用。通产情况下,下载网页我们使用HTTP协议,向服务器发送HEAD请求,可以得到页面的最后修改时间LastModifed,或者标签ETag。将这两个变量和上次下载记录的值的比较就可以知道一个网页是否跟新。这个策略对于静态网页是有效的。是对于绝大多数动态网页如ASP,JSP来说,LastModifed就是服务器发送Response的时间,并非网页的最后跟新时间,而Etag通常为空值。所以对于动态网页使用LastModifed和Etag来判断是不合适的,因此Last-Modified只是蜘蛛判断页面是否更新的一个参考值,而不是条件。

    3、比对文件大小

    搜索引擎还会取出之前页面文件,和现在的文件进行对比,不过因为大部分网站都是一种替换式更新,往往比对文件大小很难说明问题,因此常见与页面链接变化配合使用。

    4、使用MD5数字签名

    每次下载网页时,把服务器返回的数据流ResponseStream先放在内存缓冲区,然后对ResponseStream生成MD5数字签名S1,下次下载同样生成签名S2,比较S2和S1,如果相同,则页面没有跟新,否则网页就有跟新。需要说明的是用md5算法对文本刘签名的速度是极快的,M级的数据可以在毫秒内完成。这种策略虽然也把页面数据从服务器传输到了本地机,但是省掉了页面的I/O操作,对系统性能的提升是很有帮助的。

    展开全文
  • 现实中,会需要反复以需要的时间间隔执行某个命令。 这个时候借助time.sleep和sys.argv提供了一种简单的解决办法。 import time import os import sys def main(cmd, inc=60): while True: os.system(cmd) ...
  • 一、背景说明以前就感觉进步的速度和博客的数量成正比,所以很长一段时间内想...但Python执行系统命令这个问题,从学Python之初就一直在困扰,到最近又反复几次在上边遇到问题,实在是受不了。二、Python执行系统...
  • Python执行系统命令这个问题,从学Python之初就一直在困扰,到最近又反复几次在上边遇到问题,实在是受不了。 二、Python执行系统命令的实现方式 2.1 执行命令不需要获取命令输出–os.system 有时候我们只需要执行...
  • python定时执行脚本实例定时任务代码实例周期性执行实例反复执行实例 定时任务代码实例 #! /usr/bin/env python3 #coding=utf-8 #引入time, os, sched,这三个是必备的 import time, os, sched # time.time 参数...
  • 反复执行Python, Python如何使程序重复运行,Python的周期基本1主题= (\u201Clinux系统\u201D、\u201CMysql数据库\u201D,\u201CPython语言\u201D)#定义一个元组,三个元素代表三个课程2 = 0 #和定义变量num作为初始...
  • 一、背景说明以前就感觉进步的速度和博客的数量成正比,所以很长一段时间内想...但Python执行系统命令这个问题,从学Python之初就一直在困扰,到最近又反复几次在上边遇到问题,实在是受不了。二、Python执行系统...
  • 一、背景说明以前就感觉进步的速度和博客的数量成正比,所以很长一段时间内想...但Python执行系统命令这个问题,从学Python之初就一直在困扰,到最近又反复几次在上边遇到问题,实在是受不了。二、Python执行系统...
  • 一个可以加速反复执行相同简单IP /域名查找过程的工具
  • 函数是带名字的代码块,用于完成具体的工作需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用该任务的函数,让python运行其中的代码,你将发现,通过使用函数,程序编写,阅读,测试和...
  • Python开发过程中,有一些函数的结果可能会被反复调用,如果这个函数耗时较少还无伤大雅。但是,如果一个函数耗时10分钟,或者频繁的发送rest请求,那么耗时就会呈现非线性上升。那么,对于很多开发人员抱怨的...
  • 它使用一个平台特定的时间函数,尽可能提供最准确的事件计算,并减少反复执行代码时启动或关闭开销对时间计算的影响。 16.9.1 模块内容 timeit定义了一个公共类Timer。Timer的构造函数有两个参数,一个是要测量时间...
  • 二、循环的三要素虽然循环是反复执行某个动作,但是循环也会停止的,没有停止的循环就是死循环;程序如果写出死循环,这个程序就有问题,所以任何一个程序都会有结束条件,结束条件往往是和变量关联的。循环的三...
  • 但是在如此反复的测试操作中,就需要用到自动化测试方法去解决这方面的需求。在python中我们可以通过第三方库paramiko,对linux的云服务器进行操作。如下命令先行安装pip install paramikoparamiko包含两个核心组件...
  • 一、while循环while语句非常灵活,可用于在条件为真时反复执行代码块。x = 1while x <= 100:print(x)x+= 1二、for循环为序列(或其他可迭代对象)中每个元素执行代码块。numbers = [1, 2, 3, 4, 5]for number ...
  • 因为工作需要写了一个C++多线程调用Python的模块,大概是一秒钟创建五个线程,差不多30秒之后执行完毕退出线程,有140个线程同时运行,开始程序可以正常运行,但是在运行差不多十多分钟之后,当执行到PyArg_Parse()...
  • 3.(2019高一下·浙江期末)数制转换。将一个K进制(k<=10)数x转换成十进制数可采用如下方法:主要方法是从右向左,依次取数x的各位数字,分别计算出该数从右边数起的第i位数字与k(i-1)的积,再将其累加,直到所有的...
  • 前言平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来。自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,或者针对...
  • 专注Python、AI、大数据 @七步编程 ...在Python开发过程中,有一些函数的结果可能会被反复调用,如果这个函数耗时较少还无伤大雅。但是,如果一个函数耗时10分钟,或者频繁的发送rest请求,那么耗时就会呈现非线性...
  • 零基础学Python量化投资,超值线上课程反复回看超值网络课程量化投资是一种严谨、系统化的投资方式,相比起传统投资,量化投资风险低回报高,但是它要求投资者使用数据处理分析、计算机编程技术、金融工程建模等方式...
  • 一、前言平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来。自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,或者...
  • Python开发过程中,有一些函数的结果可能会被反复调用,如果这个函数耗时较少还无伤大雅。 但是,如果一个函数耗时10分钟,或者频繁的发送rest请求,那么耗时就会呈现非线性上升。 那么,对于很多开发人员抱怨的...
  • 前言平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来。自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,或者针对...
  • 经过多次反复尝试,终于解决了CentOS8下apache运行python3的所有问题 从CentOS官网下载DVD的ios包,下载列表里面有很多网站可以选择,可以反复尝试几个,因为不同的服务器速度不同,我最后选择的是163的镜像,在我...
  • 零基础学Python量化投资,超值线上课程反复回看超值网络课程量化投资是一种严谨、系统化的投资方式,相比起传统投资,量化投资风险低回报高,但是它要求投资者使用数据处理分析、计算机编程技术、金融工程建模等方式...
  • 前言平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来。自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,或者针对...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 669
精华内容 267
关键字:

python反复执行

python 订阅