zoukankan      html  css  js  c++  java
  • 模块

    模块

    模块,就用一砣代码实现了某个功能的代码集合。 

    类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。

    而对于一个复杂的功能来说,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

    例如:os 是系统相关的模块;file是文件操作相关的模块

    模块分为三种:

    • 自定义模块
    • 第三方模块
    • 内置模块

    自定义模块

    自定义模块示例

    导入模块

    Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用。

    如果想要使用模块,则需要导入。导入模块有一下几种方法: 

    import module
    from module.xx.xx import xx
    from module.xx.xx import xx as rename 
    from module.xx.xx import *

    导入模块就是告诉Python解释器去解释哪个.py文件

    • 导入一个py文件,解释器解释该py文件
    • 导入一个包,解释器解释该包下的 __init__.py 文件 【py2.7中】

    * 导入模块的时候是根据 sys.path 路径作为基准进行的

    import sys
    print(sys.path)
    ['/Users/Yao/python road/even', '/Users/Yao/python road', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Users/Yao/python road/venv/lib/python3.6/site-packages', '/Users/Yao/python road/venv/lib/python3.6/site-packages/setuptools-28.8.0-py3.6.egg', '/Users/Yao/python road/venv/lib/python3.6/site-packages/pip-9.0.1-py3.6.egg', '/Applications/PyCharm.app/Contents/helpers/pycharm_matplotlib_backend']
    得到的结果

    如果 sys.path 路径列表之中没有我们想要的路径,可以通过 sys.path.append('路径') 进行添加

    模块的安装

    pip3、源码、Pycharm内置安装三种方式都可以

    下面以 requests 为例

    1.使用 pip3 安装:

    pip3 install requests

    2.windows系统使用源码进行安装:

    下载源码包之后放到相应的盘符

    cd E:源码包名称 然后在cmd中启动 python3 setup.py install

    3.使用Pycharm内置安装

    进入 Project Interpreter 选择 + 

    在搜索栏输入想要安装的模块名,我们这次在这里搜索requests,找到之后选择并进行install安装

    显示Package 'requests' installed successfully,就已经将requests通过Pycharm安装成功了

    内置模块

    一、json/pickle 序列化

     Python中用于序列化的两个模块

    • json     用于【字符串】和 【python基本数据类型】 间进行转换,但仅限基本数据类型,如字典、列表等,更适合跨语言做操作
    • pickle   用于【python特有的类型】 和 【python基本数据类型】间进行转换,适合所有类型(包含复杂类型)做操作,但仅适用于python

    json模块提供了四个功能:dumps、dump、loads、load

    pickle模块提供了四个功能:dumps、dump、loads、load

    * 通过loads去进行反序列化时,内部一定要使用双引号""(涉及到跨平台通用原则),不然会导致报错

    import json
    
    li = '["even","root"]'
    # li = "['even','root']"  这种写法会导致报错
    ret = json.loads(li)
    print(ret,type(ret))
    具体示例
    ['even', 'root'] <class 'list'>
    显示结果

    ①json

     json 中的 dumps:将 python的基本数据类型转换成(序列化成)字符串形式

    import json
    
    dic = {'k1':'v1'}
    print(dic,type(dic))
    
    #将python基本数据类型转换成字符串形式
    result = json.dumps(dic)
    print(result,type(result))
    {'k1': 'v1'} <class 'dict'>
    {"k1": "v1"} <class 'str'>
    显示结果

     json中的 loads:将 python的字符串形式转换成(反序列化成)基本数据类型

    import json
    
    s1 = '{"k1":123}'
    dic = json.loads(s1)
    
    print(dic,type(dic))
    {'k1': 123} <class 'dict'>
    显示结果

    基于天气API获取天气相关的json数据示例:

    这里有一个关于天气信息的网页,为我们提供了全国各个城市的天气信息情况,以字符串的形式展现 http://wthrcdn.etouch.cn/weather_mini?city=重庆

    结合 requests 和 json,我们先用 requests 拿到获取到这个页面的字符串,再将其转换成dict字典形式,这样我们就可以再针对这些python基本数据类型的数据进行一些开发和操作了

    import requests
    import json
    
    response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=重庆')
    response.encoding = 'utf-8'
    
    dic = json.loads(response.text)
    print(type(dic))
    {"data":{"yesterday":{"date":"15日星期五","high":"高温 29℃","fx":"无持续风向","low":"低温 21℃","fl":"<![CDATA[<3级]]>","type":"小雨"},"city":"重庆","aqi":"69","forecast":[{"date":"16日星期六","high":"高温 27℃","fengli":"<![CDATA[<3级]]>","low":"低温 22℃","fengxiang":"无持续风向","type":"小雨"},{"date":"17日星期天","high":"高温 28℃","fengli":"<![CDATA[<3级]]>","low":"低温 23℃","fengxiang":"无持续风向","type":"小雨"},{"date":"18日星期一","high":"高温 28℃","fengli":"<![CDATA[<3级]]>","low":"低温 23℃","fengxiang":"无持续风向","type":"小雨"},{"date":"19日星期二","high":"高温 29℃","fengli":"<![CDATA[<3级]]>","low":"低温 25℃","fengxiang":"无持续风向","type":""},{"date":"20日星期三","high":"高温 28℃","fengli":"<![CDATA[<3级]]>","low":"低温 26℃","fengxiang":"无持续风向","type":""}],"ganmao":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。","wendu":"23"},"status":1000,"desc":"OK"} <class 'dict'>
    显示结果

    dump load 和 dumps loads的是类似的功能,只是将文件操作结合了起来

    详细说明见 https://www.cnblogs.com/wswang/p/5411826.html

     json中的 dump:先序列化,再写到文件里面

    import json
    li = [11,22,33]
    json.dump(li,open('db','w'))

     json中的 load:反序列化,再读文件

    import json
    li = json.load(open('db','r'))
    print(li,type(li))

    二、time模块

    表示时间的三种方式

    在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:

    • 时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
      import time
      
      print(time.time())  #时间戳
    • 格式化的时间字符串(Format String): ‘2013-05-03’
      %y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制小时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称
      %A 本地完整星期名称
      %b 本地简化的月份名称
      %B 本地完整的月份名称
      %c 本地相应的日期表示和时间表示
      %j 年内的一天(001-366%p 本地A.M.或P.M.的等价符
      %U 一年中的星期数(00-53)星期天为星期的开始
      %w 星期(0-6),星期天为星期的开始
      %W 一年中的星期数(00-53)星期一为星期的开始
      %x 本地相应的日期表示
      %X 本地相应的时间表示
      %Z 当前时区的名称
      %% %号本身
      python中时间日期格式化符号
      import time
      
      tm1 = time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
      tm2 = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
      tm3 = time.strftime("%Y-%m-%d %X",time.localtime())
      print(tm1)
      print(tm2)
      print(tm3)
      
      #2018-06-16 05:29:27   格林威治字符串时间     
      #2018-06-16 13:29:27   本地字符串时间  
      #2018-06-16 13:29:27   同上
    • 元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
      索引(Index)属性(Attribute)(Values)
      0 tm_year(年) 比如2011
      1 tm_mon(月) 1 - 12
      2 tm_mday(日) 1 - 31
      3 tm_hour(时) 0 - 23
      4 tm_min(分) 0 - 59
      5 tm_sec(秒) 0 - 60
      6 tm_wday(weekday) 0 - 6(0表示周一)
      7 tm_yday(一年中的第几天) 1 - 366
      8 tm_isdst(是否是夏令时) 默认为0
      import time
      
      print(time.gmtime())    #格林威治struct时间
      print(time.localtime()) #本地struct时间
      time.struct_time(tm_year=2018, tm_mon=6, tm_mday=16, tm_hour=5, tm_min=35, tm_sec=16, tm_wday=5, tm_yday=167, tm_isdst=0)
      time.struct_time(tm_year=2018, tm_mon=6, tm_mday=16, tm_hour=13, tm_min=35, tm_sec=16, tm_wday=5, tm_yday=167, tm_isdst=0)
      显示结果

    那么对于这三种表示时间的方法,我们可以做一个小结:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的。

    * 三种时间表示方法的转换关系:

    #--------------------------按图1转换时间
    # localtime([secs])
    # 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。
    time.localtime()
    time.localtime(1473525444.037215)
    
    # gmtime([secs]) 和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
    
    # mktime(t) : 将一个struct_time转化为时间戳。
    print(time.mktime(time.localtime()))#1473525749.0
    
    
    # strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和
    # time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个
    # 元素越界,ValueError的错误将会被抛出。
    print(time.strftime("%Y-%m-%d %X", time.localtime()))#2016-09-11 00:49:56
    
    # time.strptime(string[, format])
    # 把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
    print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X'))
    #time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6,
    #  tm_wday=3, tm_yday=125, tm_isdst=-1)
    #在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。
    按图1转换时间

    #--------------------------按图2转换时间
    # asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。
    # 如果没有参数,将会将time.localtime()作为参数传入。
    print(time.asctime())#Sun Sep 11 00:43:43 2016
    
    # ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为
    # None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
    print(time.ctime())  # Sun Sep 11 00:46:38 2016
    print(time.ctime(time.time()))  # Sun Sep 11 00:46:38 2016
    按图2转换时间

    其他常用time模块方法:

    import time
    time.sleep(4)
    print('------')
    #线程推迟指定的4s后运行print

    datetime模块的方法:

    datetime显示时间和转换日期
    datetime 时间加减
    import datetime
    
    c_time  = datetime.datetime.now()
    print(c_time.replace(minute=3,hour=2)) #时间替换
    print(c_time.replace(2015,5,3))   #直接替换成年月日
    datetime 时间替换
    import datetime
    
    c_time  = datetime.datetime.now()
    # print(c_time.replace(minute=3,hour=2)) #时间替换
    n = c_time.replace(2015,5,3)   #直接替换成年月日
    print(c_time,type(c_time))
    print(n,type(c_time))
    
    print(c_time > n)
    过去时间和现在时间的比较

    总结:time模块最常用的是用来取时间戳,datetime模块最常用的一般用来取日期

    三、logging模块

    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING

    (日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。

    CRITICAL = 50 #FATAL = CRITICAL
    ERROR = 40
    WARNING = 30 #WARN = WARNING
    INFO = 20
    DEBUG = 10
    NOTSET = 0 #不设置
    日志级别
    import logging
    
    logging.debug('调试debug')
    logging.info('消息info')
    logging.warning('警告warn')
    logging.error('错误error')
    logging.critical('严重critical')
    
    '''
    WARNING:root:警告warn
    ERROR:root:错误error
    CRITICAL:root:严重critical
    '''

    单文件日志:

    import logging
    
    logging.basicConfig(filename='log.log',
                        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S %p',
                        level=10)
    
    logging.debug('debug')
    logging.info('info')
    logging.warning('warning')
    logging.error('error')
    logging.critical('critical')
    logging.log(10, 'log')
    单文件日志示例



    logging库提供了多个组件:Logger、Handler、Filter、Formatter

     Logger:产生日志的对象

     Filter:过滤日志的对象(不常用,略)

     Handler:接收日志然后控制打印到不同的地方 :FileHandler用来打印到文件中,StreamHandler用来打印到终端

     Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

    '''
    critical=50
    error =40
    warning =30
    info = 20
    debug =10
    '''
    
    
    import logging
    
    #1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
    logger=logging.getLogger(__file__)
    
    #2、Filter对象:不常用,略
    
    #3、Handler对象:接收logger传来的日志,然后控制输出
    h1=logging.FileHandler('t1.log') #打印到文件
    h2=logging.FileHandler('t2.log') #打印到文件
    h3=logging.StreamHandler() #打印到终端
    
    #4、Formatter对象:日志格式
    formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S %p',)
    
    formmater2=logging.Formatter('%(asctime)s :  %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S %p',)
    
    formmater3=logging.Formatter('%(name)s %(message)s',)
    
    
    #5、为Handler对象绑定格式
    h1.setFormatter(formmater1)
    h2.setFormatter(formmater2)
    h3.setFormatter(formmater3)
    
    #6、将Handler添加给logger并设置日志级别
    logger.addHandler(h1)
    logger.addHandler(h2)
    logger.addHandler(h3)
    logger.setLevel(10)
    
    #7、测试
    logger.debug('debug')
    logger.info('info')
    logger.warning('warning')
    logger.error('error')
    logger.critical('critical')
    logging提供的组件详解

    四、sys模块 和 os模块

    sys模块是与Python解释器交互的一个接口

    sys.argv           #命令行参数List,第一个元素是程序本身路径
    sys.exit(n)        #退出程序,正常退出时exit(0)
    sys.version        #获取Python解释程序的版本信息
    sys.maxint         #最大的Int值
    sys.path           #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       #返回操作系统平台名称
    sys.stdin          #输入相关
    sys.stdout         #输出相关
    sys.stderror       #错误相关

    利用 sys.stdout.write(r) 实现进度条

    import sys
    import time
    
    
    def view_bar(num, total):
        rate = num / total
        rate_num = int(rate * 100)
        r = '
    %d%%' % (rate_num, )
        sys.stdout.write(r)
        sys.stdout.flush()
    
    
    if __name__ == '__main__':
        for i in range(0, 101):
            time.sleep(0.1)
            view_bar(i, 100)
    百分比进度条
    import sys
    import time
    
    
    def view_bar(num, total):
        rate = num / total
        rate_num = int(rate * 100)
        r = '
    %s>%d%%' % ('='*num,rate_num, )
        sys.stdout.write(r)
        sys.stdout.flush()
    
    
    if __name__ == '__main__':
        for i in range(0, 101):
            time.sleep(0.1)
            view_bar(i, 100)
    百分比进度条图形版

    os模块是与操作系统交互的一个接口

    os.getcwd()                 #获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")         #改变当前脚本工作目录;相当于shell下cd
    os.curdir                   #返回当前目录: ('.')
    os.pardir                   #获取当前目录的父目录字符串名:('..')
    os.makedirs('dir1/dir2')    #可生成多层递归目录
    os.removedirs('dirname1')   #若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')         #生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')         #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')       #列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()                 #删除一个文件
    os.rename("oldname","new")  #重命名文件/目录
    os.stat('path/filename')    #获取文件/目录信息
    os.sep                      #操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep                  #当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    os.pathsep                  #用于分割文件路径的字符串
    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所指向的文件或者目录的最后修改时间

    五、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())
    print(hash.digest())
     
     
    ######## 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再来二次的加密。

    import hashlib
     
    # ######## md5 ########
     
    hash = hashlib.md5(bytes('20150503even',encoding="utf-8"))    #'20150503even'相当于自己的私有key,在这个基础上再进行一次的加密算法 得到更复杂的hash值 避免了被撞库的危险
    hash.update(bytes('admin',encoding="utf-8"))
    print(hash.hexdigest())

    补充:python模块中的特殊变量

    __doc__        #将.py文件的注释封装到__doc__
    __cached__     #.pyc文件相关,指定字节码路径
    __package__    #当前.py文件在包的位置
    
    __file__       #记录当前.py文件运行的目录/路径
    
    
    __name__ #当前.py文件是主文件的时候设置运行
    if __name__ == "__main__": run()

    在os模块中

    os.path.abspath()   #获取绝对路径
    os.path.dirname()   #找到某个文件的上级目录

    涉及到 bin,可执行文件时,往往都要加上这一句

    import sys
    import os
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  • 相关阅读:
    GITHUB个人博客搭建-Pelican 在Windows环境下的安装及配置
    字符串-四则运算
    微信公众平台开发环境配置
    【小程序】使用uni-app搭建小程序环境---弹窗
    【小程序】使用uni-app搭建小程序环境---js变化
    【小程序】使用uni-app搭建小程序环境---组件标签
    【小程序】使用uni-app搭建小程序环境---封装接口
    【小程序】使用uni-app搭建小程序环境之框架
    【小程序】使用uni-app搭建小程序环境调用
    【js】JS Unicode编码和解码(6种方法)
  • 原文地址:https://www.cnblogs.com/evenyao/p/9189871.html
Copyright © 2011-2022 走看看