• python之模块


    一、模块的定义与分类

    1. 模块的定义

    • 分文件: 10个文件.每个文件有50个函数,将一些功能相同或相似的函数,放在一个文件中,随用随拿,可以解决代码冗余,重复性,我们应该将这10个函数提取出来,放在一个文件中,随用随拿.
    • 一个模块就是一个py文件,这个模块存储很多相似的功能,相似的函数的集合体.

    2. 模块的优点

    • 节省代码.
    • 容易维护,组织结构更清晰.
    • 拿来主义,提高开发效率.

    3. 模块的分类

    • 内置模块,标准库.python解释器自带的,time,os,sys,等等.200多种.
    • 第三方库(模块),各种大神写的一些模块,通过pip install....安装.6000种.
    • 自己写的模块.自定义模块.

    例题

    1. 整2个文件,文件1是模块文件,文件2是执行文件
    让2调用1中模块进行执行
    2. 导入某一个功能或者函数
    from xxx import 相当于复制一份过来,容易覆盖当前的变量
    整2个文件from tbjx import name
    from tbjx import read1
    
    3. change
    # 执行文件的效果
    from tbjx import name
    from tbjx import change
    change()
    print(name)
    # 输出结果
    太白金星 # 正常输出的应该是barry
    # 模块文件的效果
    补全代码
    # 3总结:如果引用模块中的函数,如果此函数用到一些变量,这些变量还是从此模块中寻找,不会改变您当前执行文件的变量,这种情况是极值情况(工作中完全用不到)
    # 如果你要引用一些模块的变量,你的模块名字 补全内容
    

    流程控制语句__name__之所以能作为流程分流 但脚本运行和模块被引用的时候功能完全不一样

    最后一个模块的搜索路径

    凭什么我直接import time能找到这个模块

    寻找模块的路径 内存—>内置模块—> sys.path中找

    二、模块的导入(import)

    1.导入方法

    # import tbjx
    # # 当我引用tbjx模块的时候,实际上将tbjx.py执行一遍,加载到内存.
    # import tbjx
    # import tbjx
    # import tbjx
    # import tbjx
    # import tbjx
    
    # 只是第一次引用时,将此模块加载到内存.
    

    2.第一次导入模块发生的三件事

    1. 将tbjx.py文件加载到内存.
    2. 在内存中创建一个以tbjx命名的名称空间.
    3. 通过tbjx名称空间的名字.等方式引用此模块的名字(变量,函数名,类名等等).

    3.执行方法

    模块名加点的方式执行模块功能

    import tbjx
    n = 1
    # print(tbjx.name)
    # tbjx.read1()
    # tbjx.read2()
    

    4.被导入模块有独立的名称空间

    # 坑:通过tbjx.的方式引用此模块的名字时,一定一定是从此模块中寻找.
    # 通过import 引用模块 他有自己的独立名称空间,与当前执行文件没有关系.
    name = '李业'
    print(tbjx.name)
    
    def read1():
        print('in 02 模块import')
    
    tbjx.read1()
    
    # 输出结果
    太白金星
    

    5.为模块起别名(alias)

    优点:

    • 简单,便捷.
    • 有利于代码的简化

    起别名方法

    import cStringIO as ci
    # 将cStringIO这么长的模块名给他起了个别名,用起来方便
    

    起别名后的调用方法

    import 模块名 as 别名	   #导入模块中的所有成员
    别名.变量名		  	      #调用模块中的一个变量
    别名.函数名()	 		  #调用模块中的一个函数
    模块名.变量名		  	      #错误!!!这样调用将报错!!!
    模块名.函数名() 	 		  #错误!!!这样调用将报错!!!
    
    from 模块名 import 变量名 as 别名1, 函数名 as 别名2
    别名1
    别名2()
    变量名			#错误!!!这样调用将报错!!!
    函数名()		#错误!!!这样调用将报错!!!
    

    练习题

    # 原始写法
    result = input('请输入')
    if result == 'mysql':
         import mysql1
         mysql1.mysql()
     elif result == 'oracle':
         import oracle1
         oracle1.oracle()
     list.index()
     str.index()
     tuple.index()
    
    # 起别名
     result = input('请输入')
     if result == 'mysql':
         import mysql1 as sm
     elif result == 'oracle':
         import oracle1 as sm
     ''' 后面还有很多'''
     sm.db()  # 统一接口,归一化思想
     # 通过输入不同的数据库名称执行不同的模块中的代码
    

    三、导入多个模块(from…import...)

    1.导入和调用方法一

    import time
    import os
    import sys
    
    模块名.变量名		  	      #调用模块中的一个变量
    模块名.函数名()	 		  #调用模块中的一个函数
    

    2.导入和调用方法二

    from tbjx import name  # 从tbjx模块导入name功能
    from tbjx import read1 
    from tbjx import read2
    print(name)
    print(globals())
    read1()
    
    变量名					  	  	    #调用模块中的该变量 直接变量名
    函数名()	 			    	    #调用模块中的该函数 直接函数名
    

    注意: 这种方法于在调用时不需要使用前缀,可能会导致其与当前脚本中的成员命名冲突(后出现的成员会覆盖先出现的同名成员),对此可考虑使用别名

    3.from ... import ... 与import对比

    优点: from.. import 因为不用加模块名用起来更方便

    from tbjx import name
    print(name)
    

    缺点: 容易与本文件的名字产生冲突

    #容易产生冲突,后者将前者覆盖
    name = 'alex'
    from tbjx import name
    print(name)
    

    4.导入模块时的查找顺序

    • 内存中:如果这个模块已经成功加载过,就不会重复加载,直接使用内存中的
    • 内置路径中:python安装路径下(Lib)
    • PYTHONPATH:import时寻找模块的路径。
    • sys.path:是一个路径的列表。
    • 如果上面都找不到,就报错。

    查看被加载的模块

    import sys
    print(sys.modules)
    
    
    #输出结果
    {'builtins': <module 'builtins' (built-in)>, 'sys': <module 'sys' (built-in)>, '_frozen_importlib': <module '_frozen_importlib' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_thread': <module '_thread' (built-in)>,} 
    #以字典的形式存在
    

    5.sys.path及将自定义模块导入的方法

    获取当前系统中查找模块的路径

    import sys
    print(sys.path)
    
    #输出结果
    ['D:\My Documents\Pycharm', 'D:\My Documents\Pycharm', 'D:\Program Files\Python\python36.zip', 'D:\Program Files\Python\DLLs', 'D:\Program Files\Python\lib', 'D:\Program Files\Python', 'D:\Program Files\Python\lib\site-packages', 'D:\Program Files\PyCharm\helpers\pycharm_matplotlib_backend']
    

    说明:

    1. 列表的第一个元素始终是被执行的py文件所在的目录,因此当前py文件所在的路径中的模块始终是可以被直接使用的,第二个元素始终是当前的项目路径
    2. 系统自带的模块的路径也在其中,这也就说明了为什么在程序中能自由的使用内置模块.
    3. 系统从前往后依次寻找被导入模块,则路径中如果出现重名的模块,前面的会先生效,这也是为什么我们自定义的模块不要和系统内置的模块同名的原因(将会导致内置模块被覆盖)

    值得注意的是,sys.path中出现的路径的子目录并不会被查找到,对此有三种解决方案:

    1. 把我们自定义的模块放到系统默认的路径中,如D:Program FilesPythonlib
    2. 在环境变量中定义PYTHONPATH,在其中保存被导入模块的路径
    3. 手动修改sys.path表示的列表,将自定义的模块的路径添加到其中
      第一种方案并不好,因为会污染系统自带的模块库
      第二种方案也不好,因为系统环境变量的改变会影响到其他的项目
      第三种方案是通常的做法,既不会污染系统内置路径也不会影响其他项目,只在当前项目中有效.

    添加模块路径到默认路径中

    假设当前脚本为main.py,想要调用test_module3.py模块中的func3函数

    #三步走
    #第一步: 先获取当前py文件的绝对路径
    print(__file__) 
    
    执行结果:
    D:/test011/bin/main.py
    
    #第二步: 再获取test_module3.py这个模块的绝对路径
    import os
    print(os.path.dirname(__file__))
    
    执行结果:
    D:/test011/bin
    
    #第三步: 最后拼接,并将模块路径添加
    import os
    import sys
    
    sys.path.append(os.path.dirname(__file__) + '/dd')
    import test_module3
    test_module3.func3()
    #注:表示地址时,正斜杠“/”与反斜杠“”可以混用,此例中,将dd前面的"/"改成""也行
    
    

    6.在from 模块名 import *方式下限制被导入的成员

    在被导入的模块中,使用__all__ 属性,它是一个列表,其元素是允许被导入的成员名的字符串。注意:此方式对 import 模块名 及其他所有方式的导入都无效。

    # 模块中
    __all__ = ['f1','f2']
    
    def f1():
    	print('f1')
    
    def f2():
    	print('f2')
    

    7.__name__属性(***)

    __name__ 是Python内置的一个属性,Python中的函数、模块、类都有这个属性

    以脚本方式运行时,__name__值为__main__

    以模块方式被导入时,被导入模块中的__name__值为模块名(如my_module)

    模块中对模块成员的测试代码的通常写法

    # b.py
    #Pycharm中if __name__ == '__main__':可用main快速输入
    def main():
        可执行语句1
        可执行语句2
        ……
    if __name__ == '__main__':
        main()
    

    被别人引用时,名字为模块名(脚本名),脚本方式执行时,名字为main

    import b
    def a():
        pass
    b=a
    def c():
        print(b.__name__)
    c()
    
    执行结果:
    a
    注:可以用__name__显示变量指向内存地址所对应的函数名
    

    四、序列化模块

    1.序列化模块的用途

    将一种数据结构转换成特殊的序列(特殊字符,bytes),并且还可以转换回去

    凡是数据通过网络传出去最终的格式必须bytes

    2.json模块

    用途: 所有编程语言公认的一种序列,

    缺点: 支持的python的数据结构有限,只支持: int str bool dict list tuple None 除了(set())

    用法一 (两对儿,四个方法)
    dumps,loads # 用于网络传输 #原则一对一,一个dumps对应一个loads
    
    # 转换传输
    dic = {'username':'太白'}
    ret = json.dumps(dic,ensure_ascill=False,sort_keys=True)
    print(ret)
    
    # 反转回来
    ret_dict = json.loads(ret)
    print(ret_dict)
    
    将转换后的特殊字符串写入文件,再从文件中读取出来,再反转回来
    import json
    dic = {'username': '太白', 'password': 123,'status': False}
    
    with open('register.json',mode='w',encoding='utf-8') as f1:
    	ret = json.dumps(dic, ensure_ascii=False)
    	f1.write(ret+'
    ')
    with open('register.json',mode='r',encoding='utf-8') as f2:
    	for line in f2:
    		ret_dic = json.loads(line)
    		print(ret_dic)
    
    # 该题练习主题是: 先将转换写入文件,再从文件中读取出来,反转回来
    # register.json内容
    {"username": "太白", "password": 123, "status": false}
    # 输出结果
    {'username': '太白', 'password': 123, 'status': False}
    
    用法二
    dump,load # 用于单个数据的存取文件,只能用于单个字典,用法很狭窄
    import json
    dic = {'username': '太白', 'password': 123,'status': False}
    with open('jsonlx1.json',encoding='utf-8',mode='w') as f1:
        json.dump(dic,f1)
    
    
    with open('jsonlx1.json',encoding='utf-8') as f1:
        dic1 = json.load(f1)
    
    print(dic1,type(dic1))
    
    将多个数据存储到一个文件中
    l1 = ['wusir', '太白', '小黑1', 666]
    l2 = ['wusir', '太白', '小黑2', 666]
    l3 = ['wusir', '太白', '小黑3', 666]
    with open('pickle练习1.pickle',mode='wb') as f1:
        pickle.dump(l1,f1)
        pickle.dump(l2,f1)
        pickle.dump(l3,f1)
    
    with open('pickle练习1.pickle', mode='rb') as f1:
        ret1 = pickle.load(f1)
        ret2 = pickle.load(f1)
        ret3 = pickle.load(f1)
        print(ret1,ret2,ret3)
    
    

    3. pickle模块

    用途: 支持python的所有类型和数据对象

    缺点: 只能python使用

    用法一 (两对儿,四个方法)
    dumps,loads # 只能是网络传输用,直接转换成bytes
    
    # 转换传输
    l1 = ['wusir', '太白', '小黑', 666]
    ret = pickle.dumps(l1)
    print(ret)
    
    # 反转回来
    l2 = pickle.loads(ret)
    print(l2)
    
    
    用法二
    dump,load # 用于单个数据的存取文件,只能用于单个字典,用法很狭窄
    l1 = ['wusir', '太白', '小黑', 666]
    with open('a.pickle',mode='wb') as f1:
    	pickle.dump(l1,f1)
    

    shevle模块(不讲)

    用途: 只能是文件存取,shelve也是python提供给我们的序列化工具,比pickle用起来更简单一些

    用法

    import shelve
    f = shelve.open('shelve_file')
    f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'}  #直接对文件句柄操作,就可以存入数据
    f.close()
    
    import shelve
    f1 = shelve.open('shelve_file')
    existing = f1['key']  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
    f1.close()
    print(existing)
    

    五、sys模块

    用法

    import sys
    
    sys.path ***
    
    sys.version
    
    sys.argv
    
    for i in range(3)
    	print(i)
    sys.exit(n) # 强制退出
    
    

    六、OS模块

    用法

    import os
    print(os.getcwd()) # 获取当前的绝对路径
    os.chdir(r'/Users/wuqiang/work/PycharmProjects/python23') # 切换目录 相对于shell下cd
    print(os.curdir) # 返回当前路径
    
    # 和文件相关
    os.makedirs('目录1/目录2')
    os.makedirs('dirname1/dirname2/dirname4') #创建多级目录
    os.removedirs('dirname1/dirname2/dirname4') #递归删除多级目录
    os.mkdir('abc') #创建单级目录
    os.rmdir('abc') #删除单级目录
    print(os.listdir('/Users/wuqiang/work/PycharmProjects/python23')) #查看目录下文件类似ls
    print(os.stat('/Users/wuqiang/work/PycharmProjects/python23')) #获取状态,文件信息
    print(os.environ) #获取环境变量
    
    # 路径相关
    print(os.path.abspath('day17.py')) # 获取绝对路径
    print(os.path.split(os.path.abspath('day17.py'))) #将文件路径和文件名分割
    print(os.paty.dirnaem('day17.py'))
    print(__file__) #动态获取当前文件的绝对路径
    print(os.path.dirname(os.path.dirname(__file__))) #获取爷爷级目录
    print(os.path.basename('day17.py')) #获取文件名
    print(os.path.exists('day17.py')) # 判断文件是否存在
    print(os.path.isabs('/Users/wuqiang/work/PycharmProjects/python23/day17')) #判断是不是绝对路径
    print(os.path.isfile('/Users/wuqiang/work/PycharmProjects/python23/day17')) #判断是不是存在的文件
    print(os.path.isdir('day17.py')) #判断是否是一个目录
    print(os.path.exists('day17.py')) #判断这个路径或文件是否存在
    print(os.path.join('/Users/wuqiang/work/PycharmProjects/python23/day17','day17.py'))#将路径和文件拼接在一起
    print(os.path.getatime('/Users/wuqiang/work/PycharmProjects/python23/day17'))#最后访问时间
    print(os.path.getmtime('/Users/wuqiang/work/PycharmProjects/python23/day17'))#最后修改时间
    print(os.path.getsize('/Users/wuqiang/work/PycharmProjects/python23/day17')) #文件的大小
    
    

    七、hashlib (加密)

    用途: 加密模块,摘要算法,散列算法,它是一堆加密算法的集合

    • 密码加密
    • 文件的一致性校验

    hashlib如何加密:

    • 将一个bytes类型的数据,通过hashlib进行加密返回一个等长度的16进制数字

    • 过程不可逆

    • 相同的bytes类型的数据通过相同的加密码方法得到的数字绝对相同

    • 不相同的bytes类型的数据通过相同的加密方法得到的数字绝对不相同

    密码加密用法:
    ret = hashlib.mkd5()
    ret.update('123'.encode('utf-8'))
    print(ret.hexdigest())
    # 输出结果
    202cb962ac59075b964b07152d234b70
    
    获取文件md5值函数写法:
    def encryption(path):
    	import hashlib
    	ret = hashlib.md5()
    	with open(path, mode='rb') as f1:
    		while 1:
    			content = f1.read(1024)
    			if  content:
    				ret.update(content)
    			else:
    				return ret.hexdigest()
    a = encryption('/Users/wuqiang/Downloads/python-3.7.4rc1-embed-win32.zip')
    print(a)
    #输出结果
    
    
    加固定盐
    ret = hashlib.md5('xxx教育'.encode('utf-8'))
    ret.update('123'.encode('utf-8'))
    s = ret.hexdigest()
    print(s,type(s))
    
    #输出结果
    2230499227e2134dc58609d8c8997cd9 <class 'str'>
    
    加动态的盐
    username = input('输入用户名:').strip()
    password = input('输入密码').strip()
    ret = hashlib.md5(username[::2].encode('utf-8'))
    ret.update(password.encode('utf-8'))
    s = ret.hexdigest()
    print(s)
    
    sha系列: 安全系数高,耗时高.加盐,加动态盐
    ret = hashlib.sha512()
    ret.update('123456fdklsajflsdfjsdlkafjafkl'.encode('utf-8'))
    s = ret.hexdigest()
    print(s,type(s))
    
  • 相关阅读:
    extjs 小总结
    button 带有自动提交功能。
    跑马灯效果 extjs
    ExtJs之Ext.data.Store
    dojochina ext .rar
    后台得到extjs中gridpanel选中行的某个值
    关于JavaScript“跨域”问题的总结
    Eclipse+php插件+Xdebug搭建PHP完美开发/调试环境指南
    [修补 Patch] 重命名上传文件的解决办法
    容器Collection_2
  • 原文地址:https://www.cnblogs.com/zanao/p/11099496.html
Copyright © 2020-2023  润新知