目录
名字冲突与避免
在test.py里写下面一段代码,用正则表达式包re进行匹配,匹配出123开头的字符。如果我们在test.py同级写一个re.py,那么Python解释器在进行导入时就会报错。因为Python把执行文件所在目录放进了sys.path里面,python先找到执行文件所在目录里的re.py而不去找python内置的re.py。
因此,写代码的时候应注意文件命名,避免与python内置模块冲突。
以上实验对time、sys等不起作用,因为time、sys等模块是用C语言直接实现的,是内嵌进Python解释器中的。
import re
print(re.findall(r'123', '123456'))
# ['123']
设置BASE_DIR保证程序能找到模块位置
我们知道Python从sys.path里面找模块位置。那么,写好的程序部署到其他环节下就会找不到自定义模块。如何保证程序一定能找到模块的位置呢?
我们把上一篇博文中的程序修改一下,建立两个包。bin包下是程序入口bin.py。my_module包时自定义模块,其中main.py实现逻辑,calc.py实现公用的算法。当bin.py放在bin包下的时候,Python将D:\dev\day21\bin加到sys.path里面,所以找不到和bin同级别的my_module包。此时,bin.py下的from my_module import main就会报错找不到my_module。
解决这个问题的办法是,把这个项目的根基目录D:\dev\day21加进sys.path里面。以后大家都可以用from pkg.subpkg的方式找到所有自定义的模块。为了防止同一个程序在不同环境(计算机)上运行导致的路径不一致(别的计算机上可能是/usr/local/dev/day21),需要找到一个和运行的计算机无关,只与我程序有关的计算路径的办法。
具体做法是,通过程序入口bin.py,找到bin.py的绝对路径,再向上找2层父目录就得到了day21的路径,将这个day21的路径加入sys.path即可。
__file__ 变量的值是被执行文件的文件名bin.py。os.path.abspath(__file__)得到bin.py的绝对路径。对bin.py绝对路径,找所在目录(上一层),再找所在目录(再上一层),得到day21的路径,这就是BASE_DIR,加入到sys.path即可。此时在day21下面找my_module就能找到了。
# bin.py
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from my_module import main
if __name__ == '__main__':
main.run()
time
time模块里面的函数都与时间相关。我们已经用过time.sleep(2)函数来是线程睡眠2秒。time提供的其他函数,可以获取用于计算的时间戳,用于取数的结构化时间,还提供了时间和字符串相互转换的函数等有用工具,具体的例子见下面代码和注释。
import time
# 时间戳 做计算用
# 1970-01-01 00:00:00 - now
print(time.time())
# 1578209561.4799075 sec
# 当地时间,结构化时间,取数用
t = time.localtime()
print(t)
print(t.tm_year, t.tm_wday)
# time.struct_time(tm_year=2020, tm_mon=1, tm_mday=5,
# tm_hour=15, tm_min=38, tm_sec=11, tm_wday=6, tm_yday=5, tm_isdst=0)
# 2020 6
# 格林尼治时间,结构化时间,取数用
t = time.gmtime()
print(t)
# time.struct_time(tm_year=2020, tm_mon=1, tm_mday=5,
# tm_hour=7, tm_min=38, tm_sec=11, tm_wday=6, tm_yday=5, tm_isdst=0)
# 将结构化时间转换为时间戳
t = time.mktime(time.localtime())
# 将结构化时间转换为字符串
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
# 将字符串转换为结构化时间
print(time.strptime('2019-12-24 17:50:01', '%Y-%m-%d %H:%M:%S'))
# 直接将结构化时间打印出可读性较好的当前时间,不能自定义格式
print(time.asctime())
# 直接将时间戳打印出可读性较好的当前时间,不能自定义格
print(time.ctime())
# Sun Jan 5 16:10:55 2020
# Sun Jan 5 16:10:55 2020
# 另一种比较友好的显示时间的函数
import datetime
print(datetime.datetime.now())
# 2020-01-05 16:10:55.715002
random
random模块提供与随机数和随机操作相关的函数。生成某个区间内的随机整数、随机浮点数、从有序对象里面随机取出元素、从有序对象里面随机取样n个元素、打乱有序对象元素的顺序等等。用法举例见下面代码和注释。
import random
# 产生0-1之间的随机浮点数
print(random.random())
# 产生任意区间的随机浮点数
print(random.uniform(2.3, 7.9))
# 产生[1,9]之间的随机整数
print(random.randint(1, 9))
# 产生[1,9)之间的随机整数
print(random.randrange(1, 9))
s = ['mysql', 'oracle', 'db2']
# 从有序对象中随机选取一个
print(random.choice(s))
# mysql
# 随机取样,从有序对象中随机取n个组成取样
sample = random.sample(s, 2)
print(sample)
# ['db2', 'oracle']
# 打乱次序
li = [1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(li)
print(li)
# [1, 5, 4, 3, 6, 9, 7, 2, 8]