Python中的模块是能够将代码量较大的程序分割成多个有组织的、彼此独立但又能互相交互的代码片断,这些自我包含的有组织的代码段就是模块。Python容许“导入”其余模块以实现代码重用,从而也实现了将独立的代码文件组织成更大的程序系统。Python中,模块也是对象。在一个模块的顶层定义的全部变量都在被导入时成为了被导入模块的属性。html
一、python程序架构
一个Python程序一般包括一个顶层程序文件和若干个模块文件。顶层文件包含了程序的主要控制流程,模块文件是为顶层文件或其余模块提供各类功能性组件,模块首次导入(或重载)时,Python会当即执行模块文件的顶层程序代码(不在函数内的代码),而位于函数主体内的代码直到函数被调用后才会执行。
二、模块的执行环境
模块是被导入的,但模块也能够导入和使用其余模块,这些模块能够用Python或其它编程语言写成
模块可内含变量、函数以及类来进行其工做,而函数和类能够包含变量和其它元素
三、导入模块
在导入模块时只能使用模块名,而不能使用带.py后缀的模块文件名python
import语句: 导入指定的整个模块,包括生成一个以模块名命名的名称空间 import module1[,module2[,...moduleN]] 建议一个import语句只导入一个模块 import module as module_alias from-import语句: 经常使用于只导入指定模块的部分属性至当前名称空间 from module import name1[,name2[,...nameN]] import和from-import是赋值语句 import和from是可执行语句,相似于def,所以,它们能够嵌套在if测试中,出现于def中等等 Python执行到这些语句时才会对其进行解析,这意味着,全部来自模块的属性仅在import语句执行后才能使用 模块就是名称空间 模块的名称空间能够经过属性__dict__或dir(M)获取 模块属性可经过点号(.)运算符获取,格式为M.attr 模块是一个独立的做用域(本地变量就是全局变量)
四、import的工做机制
import语句导入指定的模块时会执行三个步骤
一、找到模块文件
在指定的路径下(sys.path)搜索模块文件
二、编译成字节码
文件导入时就会编译,所以,顶层文件的.pyc字节码文件在内部使用后会被丢弃,只有被导入的文件才会留下.pyc文件
三、执行模块的代码来建立其所定义的对象
模块文件中的全部语句会依次执行,从头至尾,而此步骤中任何对变量名的赋值运算,都会产生所获得的模块文件的属性
注意:模块只在第一次导入时才会执行如上步骤,后续的导入操做只不过是提取内存中已加载的模块对象,reload()可用于从新加载模块linux
time模块用来操做时间值
时间戳:time.time()
格式化时间:字符串表示,time.strftime('%Y-%m-%d')
结构化时间:元组表示,time.localtime(), time.gmtime()算法
asctime:返回时间格式Sun Mar 18 10:51:28 2018 In [1]: import time In [2]: time.asctime() Out[2]: 'Sun Mar 18 10:51:28 2018' In [3]: time.asctime(time.localtime()) Out[3]: 'Sun Mar 18 10:51:45 2018' ctime:将自纪元以来的时间以秒为单位转换为本地时间的字符串,至关于time.asctime(time.localtime()) In [4]: time.ctime() Out[4]: 'Sun Mar 18 10:55:26 2018' gmtime:当前UTC时间 In [7]: time.gmtime() Out[7]: time.struct_time(tm_year=2018, tm_mon=3, tm_mday=18, tm_hour=2, tm_min=58, tm_sec=1, tm_wday=6, tm_yday=77, tm_isdst=0) localtime:返回本地时间 In [9]: time.localtime() Out[9]: time.struct_time(tm_year=2018, tm_mon=3, tm_mday=18, tm_hour=11, tm_min=3, tm_sec=56, tm_wday=6, tm_yday=77, tm_isdst=0) strptime:将传入的时间转换为str格式的时间 In [11]: time.strptime('2018-3-18', '%Y-%m-%d') Out[11]: time.struct_time(tm_year=2018, tm_mon=3, tm_mday=18, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=77, tm_isdst=-1) strftime:将struct格式时间转换为指定格式的时间 In [13]: time.strftime('%Y-%m-%d') Out[13]: '2018-03-18' In [14]: time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) Out[14]: '2018-03-18 03:09:47' mktime:将struct时间转换为时间戳 In [15]: time.mktime(time.strptime('2018-3-18', '%Y-%m-%d')) Out[15]: 1521302400.0 sleep:睡眠时间 In [16]: time.sleep(5)
datetime模块用来操做时间
datetime.date:表示日期的类。经常使用的属性有year, month, day
datetime.time:表示时间的类。经常使用的属性有hour, minute, second, microsecond
datetime.datetime:表示日期时间
datetime.timedelta:表示时间间隔,即两个时间点之间的长度
timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
strftime("%Y-%m-%d")shell
>>> import datetime >>> import time #当前时间 >>> print(datetime.datetime.now()) 2018-03-18 12:10:27.199643 #格式化时间戳 >>> print(datetime.date.fromtimestamp(time.time())) 2018-03-18 #当前时间➕3天 >>> print(datetime.datetime.now() + datetime.timedelta(3)) 2018-03-21 12:10:52.869598 #当前时间➖3天 >>> print(datetime.datetime.now() + datetime.timedelta(-3)) 2018-03-15 12:11:04.721491 #当前时间➕3小时 >>> print(datetime.datetime.now() + datetime.timedelta(hours=3)) 2018-03-18 15:11:18.628036 #当前时间➖4小时 >>> print(datetime.datetime.now() + datetime.timedelta(hours=-4)) 2018-03-18 08:11:42.096182 #当前时间➕120分钟 >>> print(datetime.datetime.now() + datetime.timedelta(minutes=120)) 2018-03-18 14:11:53.305800
随机数编程
In [1]: import random In [2]: random.random() Out[2]: 0.9381887159573181 #随机返回1到10之间的整数 In [3]: random.randint(1,10) Out[3]: 8 #从1到10中,2为步长随机返回一个数 In [4]: random.randrange(1,10,2) Out[4]: 5 #随机返回序列中的元素 In [5]: random.choice([1,2,3,4]) Out[5]: 3 #打乱序列中的元素顺序 In [10]: l1 = [1,2,3,4] In [11]: random.shuffle(l1) In [12]: l1 Out[12]: [1, 2, 4, 3] #随机返回序列中的2个元素 In [13]: random.sample(l1,2) Out[13]: [2, 4]
例:生成验证码安全
import random def rand_num(): code = '' for i in range(8): add = random.choice([random.randrange(10),chr(random.randrange(65,91))]) code += str(add) print(code) rand_num()
os模块是两大核心系统模块中较大的那个,它包含了在C程序和shell脚本中常常用到的全部操做系统调用。os模块能够轻松实现不依赖于平台的操做系统调用,用os和os.path编写的脚本一般无需改动便可在其余平台上运行。
一、管理工具架构
In [3]: import os getpid:给出调用函数的进程的ID In [4]: os.getpid() Out[4]: 2017 getcwd:返回当前工做目录 In [5]: os.getcwd() Out[5]: '/home/ops-jym' chdir:改变程序运行目录 In [6]: os.chdir(r'/home') In [7]: os.getcwd() Out[7]: '/home' pathsep:输出用于分割文件路径的字符串 In [8]: os.pathsep Out[8]: ':' sep:输出操做系统特定的路径分隔符,win下为"\\",Linux下为"/" In [9]: os.sep Out[9]: '/' linesep:输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" In [10]: os.linesep Out[10]: '\n' pardir:获取当前目录的父目录字符串名 In [11]: os.pardir Out[11]: '..' curdir:返回当前目录 In [12]: os.curdir Out[12]: '.'
二、os.pathapp
isdir:检查给出的文件是不是目录 In [13]: os.path.isdir(r'/home/ops-jym'),os.path.isdir(r'/etc/issue') Out[13]: (True, False) isfile:检查给出的文件是不是文件 In [14]: os.path.isfile(r'/home/ops-jym'),os.path.isfile(r'/etc/issue' ...: ) Out[14]: (False, True) exists:检查文件是否存在 In [16]: os.path.exists(r'/etc/issue'),os.path.exists(r'/etc/123') Out[16]: (True, False) getsize:返回给出文件的大小 In [17]: os.path.getsize(r'/etc/issue') Out[17]: 23 split:将path分割成目录和文件名二元组返回 In [18]: os.path.split(r'/home/ops-jym') Out[18]: ('/home', 'ops-jym') join:将多个路径组合后返回,第一个绝对路径以前的参数将被忽略 In [19]: os.path.join(r'/home','ops-zhh') Out[19]: '/home/ops-zhh' splitext:剥离文件扩展名(最后一个 . 后面的内容) In [20]: os.path.splitext(r'/home/ops-jym/shell_script/lamp.sh') Out[20]: ('/home/ops-jym/shell_script/lamp', '.sh') normpath:对于路径中混用了win和linux的分隔符的,使用normpath来处理 In [21]: os.path.normpath(r'C:\123\123') Out[21]: 'C:\\123\\123' In [22]: os.path.normpath(r'/home//ops-jym') Out[22]: '/home/ops-jym' abspath:返回path规范化的绝对路径 In [23]: os.path.abspath(" ") Out[23]: '/home' In [24]: os.path.abspath('ops-jym') Out[24]: '/home/ops-jym'
三、运行shell命令dom
system:在Python脚本中运行shell命令 In [38]: os.system('ls -al') 总用量 3948560 drwxr-xr-x. 5 root root 87 1月 19 17:29 . dr-xr-xr-x. 18 root root 4096 3月 19 16:33 .. drwxr-xr-x. 2 root root 4096 12月 22 17:19 jiayimeng drwx------. 11 ops-jym ops-jym 4096 2月 23 10:34 ops-jym drwx------. 5 ops-zhh ops-zhh 4096 12月 26 14:53 ops-zhh -rw-r--r--. 1 root root 4043309056 12月 22 17:10 rhel-server-7.2-x86_64-dvd.iso Out[38]: 0 popen:运行shell命令并与其输入或输出流相链接(迭代器对象) In [39]: os.popen('cat /etc/issue').read() Out[39]: '\\S\nKernel \\r on an \\m\n\n'
上面的两个例子能够看出,system和popen都有其局限性,尽管两个函数自己有很好的可移植性,但其真正的可移植程度决定于所运行的命令,因此咱们使用subprocess模块来实现system和popen的功能。
四、其余工具
os.environ:获取和设置shell环境变量 os.fork:在类UNIX系统下派生新的子进程 os.pipe:负责进程间通讯 os.open:打开基于底层描述符的文件(与python内建open函数不一样) os.mkdir:建立新目录 os.mkfifo:建立新的命名管道 os.stat:获取文件底层信息 os.remove:根据路径名删除文件 os.walk:将函数或循环应用与整个目录树的各部分
更多os模块详细内容,请看这里 -->猛击这里
sys模块与os模块组成了Python系统相关工具集的核心部分。
In [41]: import sys #获取平台版本信息 In [42]: sys.platform,sys.maxsize,sys.version Out[42]: ('linux', 9223372036854775807, '3.6.4 (default, Dec 26 2017, 13:57:54) \n[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]') #模块搜索路径 In [43]: sys.path Out[43]: ['', '/usr/bin', '/usr/local/python3/lib/python36.zip', '/usr/local/python3/lib/python3.6', '/usr/local/python3/lib/python3.6/lib-dynload', '/usr/local/python3/lib/python3.6/site-packages', '/usr/local/python3/lib/python3.6/site-packages/IPython/extensions', '/root/.ipython'] #利用列表操做修改模块搜索路径(append,extend,insert,pop,remove,del) In [44]: type(sys.path) Out[44]: list In [45]: sys.path.append(r"/home") In [46]: sys.path Out[46]: ['', '/usr/bin', '/usr/local/python3/lib/python36.zip', '/usr/local/python3/lib/python3.6', '/usr/local/python3/lib/python3.6/lib-dynload', '/usr/local/python3/lib/python3.6/site-packages', '/usr/local/python3/lib/python3.6/site-packages/IPython/extensions', '/root/.ipython', '/home'] In [47]: sys.path.remove('/home') #查看已加载模块 In [50]: list(sys.modules.keys()) #查看对象的引用次数 In [50]: sys.getrefcount("sys") Out[50]: 626 In [51]: sys.getrefcount("os") Out[51]: 687 #显示为由字符串组成的列表的命令行参数 In [52]: sys.argv Out[52]: ['/bin/ipython3'] #标准流 sys.stdin、sys.stdout、sys.stderr #程序退出 sys.exit
更多sys模块详细内容 -->猛击这里
Python的hashlib模块提供了用于摘要的相关操做,代替了md5,sha模块。
MD5是最多见的摘要算法,速度很快,生成结果是固定的128 bit字节,一般用一个32位的16进制字符串表示。
import hashlib hash = hashlib.md5() hash.update(bytes('python',encoding='utf-8')) hash.update(bytes('hashlib',encoding='utf-8')) print(hash.hexdigest())
结果以下
377f64c42b532c45aeb9aefaab0b81c4
sha1是另外一种较为常见的摘要算法,调用与md5类似,SHA1的结果是160 bit字节,一般用一个40位的16进制字符串表示。
hash = hashlib.sha1() hash.update(bytes('python',encoding='utf-8')) hash.update(bytes('hashlib',encoding='utf-8')) print(hash.hexdigest())
结果以下
7459c50714857e221f9b9ee36314f385b90b6c82
SHA系列的摘要算法还包括SHA1, SHA224, SHA256, SHA384, SHA512,摘要长度越长,安全性就更高,相对应的,速度也就越慢。
import hashlib hash = hashlib.sha3_512() hash.update(bytes('python',encoding='utf-8')) hash.update(bytes('hashlib',encoding='utf-8')) print(hash.hexdigest()) 结果以下: 3242741c74818ee36c3fe17a1d98180554b384a1c162325343e423f74acc2da125b2dd191d2a5a3fb388a2640f426b2acf09a49576e833a4a5cf5a697ec2c787
上述的摘要算法让数据已经很安全了,不过,仍是有些瑕疵,即经过撞库能够反解,咱们能够在加一层保险
import hashlib hash = hashlib.sha3_512(bytes('abcd',encoding='utf-8')) hash.update(bytes('python',encoding='utf-8')) hash.update(bytes('hashlib',encoding='utf-8')) print(hash.hexdigest()) 结果以下: 0287ef90ce6a8f3d4ea4be5e5cc9f229267b17250a34faf62d9ee286819e8e4aad7783a63898bf76c2ffeaf657590cfaa62e34acbaba80105572ef0f64829cda
hashlib模块的应用比较普遍,好比应用在网上提供服务,同时附上了其摘要字符串,若是有人篡改了你的应用,其摘要字符串就发生了改变,人们就能发现应用发生了改变。