坐在电脑前运行程序是不错的,但在你没有直接监督时运 行程序,也是有用的。计算机的时钟可以调度程序,在特定的时间和日期运行,或定期运行。例如,程序可以每小时抓取一个网站,检查变更,或在凌晨12点你睡觉时,执行 CPU 繁忙型任务。Python 的 time 和 datetime 模块提供了这些函数。 利用 subprocess 和 threading 模块,你还可以编程按时启动其他程序,来完成你想要的操作,节省时间。


文章目录

  • 1.1 time模块
  • 1.1.1 time.time()模块
  • 1.1.2 time.sleep()函数
  • 1.2 round() 函数——控制小数点位数
  • 秒表实验
  • 1.3 datetime模块
  • 1.4 timedelta模块
  • 1.4.1 暂停程序直到指定日期
  • 1.4.2 将datetime对象转换为字符串
  • 1.4.3 将字符串转化为datetime()格式
  • 1.5 多线程操作
  • 1.5.1 向线程的目标函数传递参数
  • 1.5.2 多线程引起的并发问题


1.1 time模块

time模块可以让Python程序读取计算机的本地时间,time模块的time.time()和time.sleep()是表有用的两个模块。

1.1.1 time.time()模块

Unix纪元是计算机编程中经常参考的时间,1970年1月1日0点,称为协调世界时间(UTC)。time.time()返回自那一刻所过的秒数,为一个浮点值。这个数字称为Unix纪元时间戳。

python 暂停按钮实现 python暂停几秒_多线程


时间戳可以让你分析程序运行的时间

#python3
#calculateTime.py TODO:output the period of time
import time
def calculate():
    #Calculate the time from start to end
    value=1
    for i in range(1,10000):
        value=value+1
    return value
startTime=time.time()
temp=calculate()
endTime=time.time()
print('The result is %s types long.'%(len(str(temp))))
print('Takes %s seconds to calculate.'%(endTime-startTime))

运行结果:

python 暂停按钮实现 python暂停几秒_python 暂停按钮实现_02


程序先引入time模块,然后先记录开始时间戳,然后运行程序中的自定义函数 calculate(),再记录结束时间戳,最后结束时间戳减去开始时间戳等于程序运行时间

1.1.2 time.sleep()函数

程序睡眠函数time.sleep(),通过传入参数即秒数来控制程序的暂停

python 暂停按钮实现 python暂停几秒_时间戳_03


新版本的Python键入Ctrl+C会马上终止,旧版本的要等到睡眠时间到了以后才能线束键入被中断

python 暂停按钮实现 python暂停几秒_ci_04

1.2 round() 函数——控制小数点位数

在处理时间戳时,为了更好的处理时间,通常采用round()函数来简化浮点值

python 暂停按钮实现 python暂停几秒_python 暂停按钮实现_05

秒表实验

我们可以写一个秒表,来记录每次开始和结束的时间,还有总时间。这种类型可以用来体育测试,记录百米赛跑的具体时间
#通过使用回车来 开始
#再按一次回车结束

#!python3
#calcuTime.py-calculate time cf circles
import time
#Display the object's details
print('Please ENTER to begin.Then,u can press ENTER more agnin to stop the calculating.Press Ctrl-C to exit')
input() #Press ENTER to begin
print('Started')
startTime=time.time() # Recorded the time for start
lastTime=startTime
circleNum=1 #circleNum为圈数
#TODO:Start tracking the circle times and every keyboard's time.
try:
    while True:
        input()
        CirclesTime=round(time.time()-lastTime,2)
        TotalTime=round(time.time()-startTime,2)
        #circleNum+=1
        print('Lap:%s Total:%s LapTime:%s'%(circleNum,TotalTime,CirclesTime),end='')
        circleNum+=1
        lastTime=time.time() #record the  new time for start
except KeyboardInterrupt:
    #Handle the Ctrl-C exception to stop error messages displaying
    print('Calculate time for circles has done')

为了避免程序运行出错,我们将程序的循环执行部分放入try语句中,一旦使用Ctrl-C来暂停,进入except语句不会出现错误提示,而是输出计算时间已结束(格式为except+错误信息:)

结果图:

python 暂停按钮实现 python暂停几秒_ci_06

1.3 datetime模块

datetime模块可以取得现在的时间以及UTC时间,而不是Unix时间戳,还可以单独显示当前的年月日,而且还可以推断在Unix纪元时间以后的多少秒后的现实时间,返回的数字分别为年 月 日 时 分 秒 微妙(浮点值)

python 暂停按钮实现 python暂停几秒_ci_07


fromtimestamp()函数传入一个时间参数后返回的为计算后的时间,距离Unix纪元时间的秒数所对应的时间,utcnow()函数为utc时间,即协调世界时间

python 暂停按钮实现 python暂停几秒_多线程_08


datetime对象之间还可以进行比较,通过查看逻辑值

python 暂停按钮实现 python暂停几秒_时间戳_09

1.4 timedelta模块

timedelta模块提供时间段而不是一个时刻。

要创建 timedelta 对象,就要用 datetime.timedelta()函数。datetime.timedelta()函数接受关键字参数 weeks、days、hours、minutes、seconds、milliseconds 和 microseconds。 没有 month 和 year 关键字参数,因为“月”和“年”是可变的时间,依赖于特定月份或年份。timedelta 对象拥有的总时间以天、秒、微秒来表示。这些数字分别保存 在 days、seconds 和 microseconds 属性中。total_seconds()方法返回只以秒表示的时 间。将一个 timedelta 对象传入 str(),将返回可读性更好的日期形式。

python 暂停按钮实现 python暂停几秒_ci_10

  1. 算术运算符可以对datetime对象所代表的值进行运算,这比自己手算要快的多,如果天数是好几年的话,需要记住每个月是否为30天或者31天以及平年或是闰年

python 暂停按钮实现 python暂停几秒_时间戳_11


用乘法来做datetime对象的加减

3

python 暂停按钮实现 python暂停几秒_python 暂停按钮实现_12


timedelta对象只是一个日期类的对象,并不是一个真正的数字变量,所以不能用于在timedelta()里面做算术运算,斗则会报错,不支持的类型

python 暂停按钮实现 python暂停几秒_时间戳_13

1.4.1 暂停程序直到指定日期

变量要以字母开头,不能以数字开头,此程序利用一个while 循环和time.sleep()函数来达到暂停的目的

#!python3
#cutTime-stop yhe process to the pointed date
import datetime
import time
NationalDayOf2020=datetime.datetime(2020,10,1,0,0,0)
while datetime.datetime.now()<NationalDayOf2020:
    time.sleep(1)

1.4.2 将datetime对象转换为字符串

Unix纪元戳和datetime对象都不是友好的可读对象。利用 strftime()方法,可以将 datetime 对象显示为字符串。(strftime()函数名中的f 表示格式,format)。

%Y

带世纪的年份,例如‘2020‘’’

%y

不带世纪的年份,‘00‘-’99’(1970-2069,从Unix纪元年开始)

%m

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

%B

完整的月份,例如‘September’

%b

简写的月份,比如‘Sep’

%j

一年中的第几天,‘001’至‘366’

%d

一月中的第几天,‘01’至‘31’

%w

一周中的第几天 ,‘0’至‘6’,星期一至星期日

%A

完整的周几,比如‘Monday’

%a

简写的周几,比如‘Tue’

%H

小时,24小时制,从‘00’至‘23’

%I

小时,12小时制,从‘01’至‘12’

%M

分,‘00’至‘59’

%S

秒,‘00’至‘59’

%p

‘AM’或“PM”

%%

%字符

向strftime()传入指定的参数,比如格式化字符以及斜杠,冒号等等,strftime()方法将传回一个对应的格式化数据

python 暂停按钮实现 python暂停几秒_python 暂停按钮实现_14

1.4.3 将字符串转化为datetime()格式

将字符串转化为datetime格式需要strptime()函数

python 暂停按钮实现 python暂停几秒_多线程_15


必须严格匹配所对应的日期格式,这样才不会出错

1.5 多线程操作

多线程从名称上来看即多个线程进行工作。什么是线程?线程的定义为CPU分配的最小单位,不分配系统资源,多个线程可共享一个进程所分配的其它硬件资源。线程为轻量化级操作,减轻了CPU的开销,不必来回撤销所分配给进程的资源,共享进程的资源即可,对CPU没有什么要求,线程即软件层面实现的虚拟处理器。利用分时系统等可实现并发执行。并发为在同一时间段内发生,并行意为在同一时刻发生,对处理器有需求,需要多核处理器。
下面的代码即程序需要等到while循环执行完以后才可以执行print函数。而多线程则不需要,可同时执行不同的代码块,执行效率会高很多,对CPU的利用率也高。

#!python3
#cutTime-stop yhe process to the pointed date
import datetime
import time
NationalDayOf2020=datetime.datetime(2020,10,1,0,0,0)
while datetime.datetime.now()<NationalDayOf2020:
    time.sleep(1)
print('It has done')

要想实现多线程操作,可以使用Python的threading模块,来安排一个新线程做它原本的工作,原来的线程可以继续执行其它的工作,比如print函数,而新线程继续执行上面休眠代码块。

#!python3
#multithreading.py-To start another new threading
import threading,time
print('Start this subject.')
def takeThread():
    time.sleep(3)
    print('The thread was waked up.')
newThread=threading.Thread(target=takeThread)
newThread.start()
print('The process has complished.')

在上面的代码中,我们创建了一个thread对象。利用函数threading.Thread()创建一个新的线程,并传入参数target=takeThread函数,此处传入的并不是takeThread(),目的不在于调用这个函数并返回它的值作为参数,而是创建一个执行这个作为参数的函数的新线程。所以会出现下图的先出现原先的线程执行的print函数所输出的 The process hascomplished,后出现新的线程转而去执行takeThread()函数,因为有睡眠函数,所以后出现。

效果图:

python 暂停按钮实现 python暂停几秒_python 暂停按钮实现_16


下面的函数则会直接输出,因为没有睡眠函数

#!python3
#multithreading.py-To start another new threading
import threading,time
print('Start this subject.')
def takeThread():
    #time.sleep(3)
    print('The thread was waked up.\n')
newThread=threading.Thread(target=takeThread)
newThread.start()
print('The process has complished.')

python 暂停按钮实现 python暂停几秒_ci_17

1.5.1 向线程的目标函数传递参数

通过import关键字引入threading线程模块,向args传入常规参数(Apple、Orange,Banana),向kwargs传入关键字参数分隔符sep,关键字参数可以作为字典的形式来提供给kwargs

python 暂停按钮实现 python暂停几秒_python 暂停按钮实现_18


python 暂停按钮实现 python暂停几秒_多线程_19


如果按照下面的格式来传入参数的话,直接调用的是print函数,而不是将它作为一个参数传递给threading,Thread()函数,不需要开启新线程便直接输出。

python 暂停按钮实现 python暂停几秒_多线程_20

1.5.2 多线程引起的并发问题

多线程提升处理器的效率时,同时也可能引发一系列不好的后果,并发可能并不具有异步性,即按照不同的时刻,只要处理步骤相同,就可得到相同的后果。可能导致变量的不恰当引用而导致发生不可逆转的错误,致使程序发生不进入人意的后果。
为了避免并发问题,绝不让多个线程读取或写入相同的变量。当创建一个新的Thread对象时, 要确保其目标函数只使用该函数中的局部变量。这将避免程序中难以调试的并发问题。