• Python基础(十)-模块


    模块初识

    一般把不同功能代码放到不同py文件,一个py文件就是一个模块

    三种模块库:

    1、Python标准库

    2、第三方库

    3、自定义库

    导入模块:import 库名 (Python解释器只认识执行文件的路径(sys.path),导入自定义库时也只会从执行文件的路径开始找

    import sys
    print(sys.path)
    
    结果:
    ['E:\PyCharm\Personal_practice\cmdb', 'E:\PyCharm\Personal_practice\cmdb', 'D:\Program Files (x86)\python\python35\python35.zip', 'D:\Program Files (x86)\python\python35\DLLs', 'D:\Program Files (x86)\python\python35\lib', 'D:\Program Files (x86)\python\python35', 'D:\Program Files (x86)\python\python35\lib\site-packages']

    导入后的两个效果:

    1、先执行模块所有代码 2、引入变量名

    引入多个模块:import a,b,c

    导入模块并重命名:from project.app01 import views as v

    在调用模块下方法时,不建议 from a import *  (全部引入)这么写可能会与自己当前定义的函数冲突

    包:

    用来组织模块,避免模块名重复产生冲突(文件夹中包含__init.py__文件)

    导入模块时,解释器解释该py文件
    当导入包(文件夹)时,解释器解释__init__.py文件

    模块导入过程详解

    在Python中使用import语句导入模块时,python通过三个步骤来完成这个行为。 
    1:在python模块加载路径中查找相应的模块文件 
    2:将模块文件编译成中间代码 
    3:执行模块文件中的代码
    
    在python中模块的导入动作只发生一次。也就是说当一个模块在一个文件中被导入过一次以后,当另外的文件继续需要导入这个模块时,python首先会在sys.modules这个变量中查出是否已经
    导入过这个模块,如果已经导入过则上面三个步骤不会执行,直接引用之前导入的内存中的内容。 在步骤2中,python首先会查找对应模块的.pyc文件,看该文件的最后修改时间是否比对应的.py文件的走后修改时间早,如果遭遇.py文件的最后修改时间,则重新编译模块并重新生成
    字节码文件。注意,一个python程序的顶层文件不会生成.pyc文件。
    当python完成步骤2以后会执行python文件中的语句,以生成对应的对象属性,比如def语句生成该模块的一个函数属性等。因为这个特性,假如模块中有一个print语句 ,
    那么, 当该模块被第一次加载的时候,该输出语句就会将内容输出,但是由于模块只能被import一次,所以,当模块第二次被加载的时候,上面这三个步骤都不会被执行,
    那么,这个输出不会再次出现。

    多层包调用:

    假如引入模块a.py在执行文件b同级目录c下里,在b中引入模块a:from c import a

    假如引入模块a.py在执行文件b同级目录c/d下里,在b中引入模块a: from c.d import a

       调用a下cal方法:a.cal() 或者 from c.d.a import cal   cal()

    __name__使用:

    if __name__=='__main__' 在执行文件才成立

    1.用于调用文件,测试模块代码(返回是文件名)

    2.用于执行文件,强调不可调用

    常用模块介绍

    1、time模块

     1 import time
     2 print(time.time())  #时间戳-计算
     3 print(time.localtime(time.time()))  #结构化时间-显示  struct_time
     4 print(time.gmtime())  #0时区结构化时间
     5 print(time.mktime(time.localtime()))  #结构化时间转化成时间戳
     6 print(time.strftime('%Y-%m-%d %X',time.localtime()))  #结构化时间转化成字符串时间(格式化时间format)
     7 print(time.strptime('2016-12-12 18:22:56','%Y-%m-%d %X'))  # format时间转化成结构化时间
     8 
     9 print(time.ctime())
    10 print(time.ctime(1423441244))  #将时间戳直接转化成字符串时间固定格式(%a %b %d %H:%M:%S %Y)
    11 
    12 print(time.asctime()) #等同下条
    13 print(time.strftime('%a %b %d %H:%M:%S %Y',time.localtime()))  #将结构化时间转化成字符串时间格式同上
    14 
    15 #执行结果
    16 1481596470.6987557
    17 time.struct_time(tm_year=2016, tm_mon=12, tm_mday=13, tm_hour=10, tm_min=34, tm_sec=30, tm_wday=1, tm_yday=348, tm_isdst=0)
    18 time.struct_time(tm_year=2016, tm_mon=12, tm_mday=13, tm_hour=2, tm_min=34, tm_sec=30, tm_wday=1, tm_yday=348, tm_isdst=0)
    19 1481596470.0
    20 2016-12-13 10:34:30
    21 time.struct_time(tm_year=2016, tm_mon=12, tm_mday=12, tm_hour=18, tm_min=22, tm_sec=56, tm_wday=0, tm_yday=347, tm_isdst=-1)
    22 Tue Dec 13 10:34:30 2016
    23 Mon Feb  9 08:20:44 2015
    24 Tue Dec 13 10:34:30 2016
    25 Tue Dec 13 10:34:30 2016

    两张图搞定time模块之间关系:

    2、random模块

     1 import random
     2 
     3 print(random.random())  #返回固定取值范围0到1之间的随机浮点数
     4 print(random.uniform(1,4)) #随机返回可定义取值范围1到4之间的浮点数
     5 
     6 print(random.randint(1,4))  #两个值[1,4]随机返回定义取值范围内的一个整数
     7 print(random.randrange(1,4))  #[1,4)和range一样  同上
     8 
     9 print(random.choice([1,2,3,[1],'123'])) #随机返回一个值
    10 print(random.sample([1,2,3,[1],'123'],3))  #随机返回定义的几个值
    11 
    12 f=[1,2,'3']
    13 random.shuffle(f)    #返回打乱顺序的列表
    14 print(f)
    15 
    16 ###执行结果
    17 0.2171299686228637
    18 3.7457633609923873
    19 2
    20 1
    21 2
    22 ['123', 1, 3]
    23 ['3', 2, 1]

    生成验证码:

     1 import random
     2 def v_code():
     3     code=''
     4     for i in range(5):
     5         num=random.randint(0,9)
     6         alf=chr(random.randint(65,90))
     7         add=random.choice([num,alf])
     8         code+=str(add)
     9     return code
    10 print(v_code())
    View Code

    3、os模块

    os.getcwd()  #获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")  #改变当前脚本工作目录;相当于shell下cd
    os.curdir  #返回当前目录: ('.')
    os.pardir  #获取当前目录的父目录字符串名:('..')
    os.makedirs('dirname1/dirname2')   #可生成多层递归目录
    os.removedirs('dirname1')    #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')    #生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')    #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')    #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()  #删除一个文件
    os.rename("oldname","newname")  #重命名文件/目录
    os.stat('path/filename')  #获取文件/目录信息
    os.sep    #输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep    #输出当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    os.pathsep    #输出用于分割文件路径的字符串 win下为;,Linux下为:
    os.name    #输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
    os.system("bash command")  #运行shell命令,直接显示
    os.environ  #获取系统环境变量
    os.path.abspath(path)  #返回path规范化的绝对路径
    os.path.split(path)  #将path分割成目录和文件名二元组返回
    os.path.dirname(path)  #返回path的目录。其实就是os.path.split(path)的第一个元素
    os.path.basename(path)  #返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
    os.path.exists(path)  #如果path存在,返回True;如果path不存在,返回False
    os.path.isabs(path)  #如果path是绝对路径,返回True
    os.path.isfile(path)  #如果path是一个存在的文件,返回True。否则返回False
    os.path.isdir(path)  #如果path是一个存在的目录,则返回True。否则返回False
    os.path.join(path1[, path2[, ...]])  #将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    os.path.getatime(path)  #返回path所指向的文件或者目录的最后存取时间
    os.path.getmtime(path)  #返回path所指向的文件或者目录的最后修改时间
    View Code

    4、sys模块

    sys.argv           命令行参数List,第一个元素是程序本身路径
    sys.exit(n)        退出程序,正常退出时exit(0)
    sys.version        获取Python解释程序的版本信息
    sys.maxint         最大的Int值
    sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       返回操作系统平台名称
    #进度条显示
    import sys
    import time
    for i in range(100):
        sys.stdout.write('#')
        time.sleep(0.1)
        sys.stdout.flush()
    View Code

    5、re模块

    正则表达式用来对字符串进行模糊匹配(功能比字符串方法强大很多,我懂的)

    元字符:

     1 . 通配符 可以替代所有字符除了换行符
    
     2 ^ 匹配开头
     3 $ 匹配结束
     4 
     5 
     6 * 匹配0到无穷次
     7 + 匹配1到无穷次
     8 ? 匹配0到1次
     9 {} 自定义匹配次数
    10 
    11 [] 字符集  只认识三种特殊字符: -(取值范围) ^(非) (转移符),其他均为普通字符
    12 |  表示或 管道两侧整体作为元素
    13 () 分组符
    14   转移符 
    1 d  匹配任何十进制数;它相当于类 [0-9]。
    2 D 匹配任何非数字字符;它相当于类 [^0-9]。
    3 s  匹配任何空白字符;它相当于类 [ 	
    
    fv]。
    4 S 匹配任何非空白字符;它相当于类 [^ 	
    
    fv]。
    5 w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    6 W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
    7   匹配一个特殊字符边界,比如空格 ,&,#等
    ###事例###
    
    print(re.findall('abc*','ab'))
    print(re.findall('abc*','abccccabdd'))
    print(re.findall('abc+','ababccc'))
    print(re.findall('^abc','abcabccc'))
    print(re.findall('^abcd','abcabccc'))
    
    print(re.findall('abc?','ababcccc'))
    
    print(re.findall('abc{3}','abccabcccccc'))
    
    print(re.findall('[a-c]','ab9999cwzAA'))   #['a', 'b', 'c']
    print(re.findall('[a-c]+','ab9999cwzAA'))  #['ab', 'c']
    print(re.findall('[^0-9]+','abc99cdd11cc'))  #['abc', 'cdd', 'cc']
    print(re.findall('[a\\c]+','acccc'))    #python解释器 re模块 都有转义 ['a\cccc']
    print(re.findall(r'[a\c]+','acccc'))                 #['a\cccc']
    
    print(re.findall('a|bc','babcbabccc'))  #['a', 'bc', 'a', 'bc']
    
    print(re.findall(r'I','I am I&nnnnn'))
    
    print(re.findall('a(bc)+','abcabcbccc'))  #显示(bc)其实匹配的是a(bc)+
    print(re.findall('a(?:bc)+','abcabcbccc'))   # ?: 去除分组优先级 正常输出匹配['abc','abcbc']
    print(re.findall('(?:abc)+','abcabccccadc'))
    
    ret=re.search('(?P<id>d{2})/(?P<name>w{3})','23/com')
    print(ret.group())       #23/com
    print(ret.group('id'))   #23
    print(ret.group('name')) #com


    * + ? {}都是贪婪匹配,尽可能多的匹配,加上?就变成惰性匹配
    print(re.findall('abc*?','abccccc') #返回['ab']

    re模块常用方法:

     1 re.findall('ab','abcabc')  #列表返回所有匹配字符串['ab','ab']
     2 
     3 print(re.search('abc','abcabcabc').group())  #匹配第一个立即返回一个匹配对象,没匹配到返回None
     4                                  <_sre.SRE_Match object; span=(0, 3), match='abc'>
     5                                  通过group()方法取值
     6 
     7 re.match()  #相当于re.search() 但是只匹配开头
     8 
     9 ret=re.split('[ab]','abcd')     #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
    10 print(ret)#['', '', 'cd']
    11 
    12 print(re.sub('d','A','123abc3d'))   #AAAabcAd  默认替换所有
    13 print(re.sub('d','A','123abc3d',2)) #AA3abc3d 指定替换个数
    14 print(re.subn('d','A','123abc3d'))  #('AAAabcAd', 4)
    15 print(re.subn('d','A','123abc3d',2))#('AA3abc3d', 2)  只是返回值不同

    6、hashlib

    用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

    import hashlib
     
    # ######## md5 ######## 不能反解
    hash = hashlib.md5()
    # help(hash.update)
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())   '21232f297a57a5a743894a0e4a801fc3'
    print(hash.digest())      b'!#/)zWxa5xa7Cx89Jx0eJx80x1fxc3'
     
     
    ######## sha1 ########
     
    hash = hashlib.sha1()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
     
    # ######## sha256 ########
     
    hash = hashlib.sha256()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
     
     
    # ######## sha384 ########
     
    hash = hashlib.sha384()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
     
    # ######## sha512 ########
     
    hash = hashlib.sha512()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())

    以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

    1 import hashlib
    2  
    3 # ######## md5 ########
    4  
    5 hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))
    6 hash.update(bytes('admin',encoding="utf-8"))
    7 print(hash.hexdigest())

    python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密

    1 import hmac
    2  
    3 h = hmac.new(bytes('898oaFs09f',encoding="utf-8"))
    4 h.update(bytes('admin',encoding="utf-8"))
    5 print(h.hexdigest())

    7、request模块

    Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作

    安装:pip3 install requests

    # 1、无参数实例
     
    import requests
     
    ret = requests.get('https://github.com/timeline.json')
     
    print(ret.url)
    print(ret.text)
     
     
     
    # 2、有参数实例
     
    import requests
     
    payload = {'key1': 'value1', 'key2': 'value2'}
    ret = requests.get("http://httpbin.org/get", params=payload)
     
    print(ret.url)
    print(ret.text)
    GET请求
    # 1、基本POST实例
     
    import requests
     
    payload = {'key1': 'value1', 'key2': 'value2'}
    ret = requests.post("http://httpbin.org/post", data=payload)
     
    print(ret.text)
     
     
    # 2、发送请求头和数据实例
     
    import requests
    import json
     
    url = 'https://api.github.com/some/endpoint'
    payload = {'some': 'data'}
    headers = {'content-type': 'application/json'}
     
    ret = requests.post(
              url, 
              data=json.dumps(payload),  # json=payload 序列化成字节
              headers=headers)
     
    print(ret.text)
    print(ret.cookies)
    POST请求
    requests.get(url, params=None, **kwargs)
    requests.post(url, data=None, json=None, **kwargs)
    requests.put(url, data=None, **kwargs)
    requests.head(url, **kwargs)
    requests.delete(url, **kwargs)
    requests.patch(url, data=None, **kwargs)
    requests.options(url, **kwargs)
     
    # 以上方法均是在此方法的基础上构建
    requests.request(method, url, **kwargs)
    其他请求
  • 相关阅读:
    设计模式--17、建造者模式
    设计模式--16、原型模式
    面向对象的几大设计原则
    设计模式--15、模板方法模式
    设计模式--14、中介者模式
    设计模式--13、享元模式
    设计模式--12、外观模式
    设计模式--11、命令模式
    消息中间件ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka如何选型?
    Kafka,Mq,Redis作为消息队列有何差异?
  • 原文地址:https://www.cnblogs.com/chenzhuo-/p/6168905.html
Copyright © 2020-2023  润新知