• python基础之模块(一)


    概述

    模块,用一砣代码实现了某个功能的代码集合。一个功能可能由 N 个函数来组成,这些函数写到一个py文件中,那么这个Py文件就是传说中的模块.

    模块可将代码归类,让你的代码看着条理清晰,当然还需要你在提前设计程序时的设计思路清晰,更多的调用,慢慢练吧,骚年!

    模块使用时的特点:

    1. 先导入,后使用
    2. 模块可为目录,也可为py文件

    模块分为三类:

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

    自定义模块

    自定义模块顾名思义就是自己编写的对某功能实现的一些函数集合.

    模块的导入

    模块导入的方式比较多:

    import index  #执行py与index在同一目录
    from index import func1   #执行py与index在同一目录,func1为index.py中的某个函数
    

    又比如,有某个目录:

    |____1.py
    |____2.py
    |______pycache__
    | |____geno.cpython-35.pyc
    |____db
    |____digui.py
    |____geno.py
    |____iter_test.py
    |____lib
    | |______pycache__
    | | |____commands.cpython-35.pyc
    | |____commands.py
    

    1.py想导入lib/commands.py文件中的东西,commands是一个模块,我们可以这么做:

    from lib import commands  #导入
    commands.func1	#调用func1函数
    	#也可以这么用
    from lib.commands import * 
    func1   #直接调用
    

    那么问题来了,不同目录之间怎么调用呢?

    .
    |______init__.py
    | |____a
    | | |____22.py
    | | |______init__.py
    | | |______pycache__
    | | | |______init__.cpython-35.pyc
    | | | |____test.cpython-35.pyc
    | | |____test.py
    | |____b
    | | |____1.py
    

    b/1.py 想调用a/22.py 模块,这就需要添加环境变量来调用了

    import sys
    sys.path.append('..')
    

    但这么搞是不是有点太low了,来个比较高档点吧:

    import sys,os
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    

    为毛这么搞可以?来解释下:

    • file 获取当前文件以及所在的位置,但有可能得到的是相对路径
    • os.path.abspath() 获取文件的绝对路径
    • os.path.dirname() 获取文件的上级目录

    这里需要插播一下python自动创建的全局变量:

    • file 获取当前文件以及所在的位置,但有可能得到的是相对路径
    • name 如果模块被导入,那么__name__的名字就为模块的名字,如果模块是被直接执行,__name__的值为’main
    • main 仅仅是用来检测该文件代码是否是主程序文件,也即非模块。通常可以用来测试模块比如你可以通过检测来执行一些测试用例,但当文件作为模块导入其他程序中时,检测__main__会为False,即里面的代码不会执行
    • doc 获取文件的注释
    • cached 字节码的路径
    • package 一般使用方式:print(xxx.package),显示xxx模块的文件路径

    内置模块

    sys模块

    来看一个比较好玩的进度条吧,装逼器:

    import sys,time
    def view_bar(num,totle):
        rate=num/totle
        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(101):
            time.sleep(0.1)
            view_bar(i,100)
    

    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       #错误相关
    

    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所指向的文件或者目录的最后修改时间
    os.getlogin()            #获取当前登录用户
    

    重点说下os.path.join()的用法:
    一般是在拼接路径的时候用的。举个例子

    os.path.join(“home”, "me", "mywork")
    在Linux系统上会返回
    “home/me/mywork"
    在Windows系统上会返回
    "homememywork"
    好处是可以根据系统自动选择正确的路径分隔符"/"或""
    

    之前博客中有写一篇判断文件是否存在的模块,链接在这:
    点我点我点我

    hashlib

    用于加密相关的操作,替代了MD5和SHA,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
    看下例子:

    import hashlib
    obj=hashlib.md5(bytes('asdfasdf',encoding='utf8'))  #1
    obj.update(bytes('123',encoding='utf8'))
    res=obj.hexdigest()
    print(res)
    

    1位置有一个'hashlib.md5(bytes('asdfasdf',encoding='utf8'))',干啥用的呢?因为如果碰到撞库攻击的时候,对方会用的密码字典去匹配你的密码,所以我们在前面加上自己的字段,这样生成的md5值肯定和对方的不一样了!

    之前博客中有一篇说了下一个密码加密的东西,链接:
    点我点我点我

    random模块

    随机模块,比较简单,不多做说明了.
    之前博客中有一篇随机生成验证码的模块,链接在这:
    点我点我点我

    序列化模块

    Python中序列化数据的模块有两个:

    1. json 用于【字符串】和 【python基本数据类型】 间进行转换
    2. pickle 用于【字符串】和 【python基本数据类型】 间进行转换

    其实无非是load/dump/loads/dumps的应用

    json 和 pickle 区别

    1. json 更适合夸语言操作,字符串,基本数据类型操作

    2. pickle 适合所有类型的序列化 python 操作,pickle 仅适用于 python,2和3可能不兼容

    json

    通过 json.loads 反序列化时,一定要注意双引号,要与其他语言格式相匹配了

    之前博客写过一片json的使用,链接:
    点我点我

    pickle

    大体类似,上个例子吧,需要注意的一点就是二进制文件的读写模式:

    import pickle
    li=[1,2,3,4,5,'cc']
    ####pickle.dump(li,open('db','wb'))
    r=pickle.dumps(li)
    print(r)
    res=pickle.loads(r)
    print(res)
    

    out:

    b'x80x03]qx00(Kx01Kx02Kx03Kx04Kx05Xx02x00x00x00ccqx01e.'
    [1, 2, 3, 4, 5, 'cc']
    

    requests模块

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

    安装很简单: pip3 install requests

    配合json可以玩个有意思的天气查询:

    import json,requests
    
    response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=北京')
    response.encoding='utf-8'
    
    dic=json.loads(response.text) #text 指 requests生成的内容
    print(dic)
    

    out:

    {'desc': 'OK', 'data': {'wendu': '20', 'forecast': [{'fengxiang': '无持续风向', 'date': '14日星期二', 'low': '低温 18℃', 'high': '高温 24℃', 'fengli': '微风级', 'type': '雷阵雨'}, {'fengxiang': '无持续风向', 'date': '15日星期三', 'low': '低温 17℃', 'high': '高温 30℃', 'fengli': '微风级', 'type': '多云'}, {'fengxiang': '无持续风向', 'date': '16日星期四', 'low': '低温 20℃', 'high': '高温 33℃', 'fengli': '微风级', 'type': '多云'}, {'fengxiang': '无持续风向', 'date': '17日星期五', 'low': '低温 22℃', 'high': '高温 33℃', 'fengli': '微风级', 'type': '多云'}, {'fengxiang': '无持续风向', 'date': '18日星期六', 'low': '低温 21℃', 'high': '高温 31℃', 'fengli': '微风级', 'type': '多云'}], 'yesterday': {'fx': '无持续风向', 'date': '13日星期一', 'low': '低温 18℃', 'high': '高温 22℃', 'fl': '微风', 'type': '雷阵雨'}, 'city': '北京', 'ganmao': '各项气象条件适宜,无明显降温过程,发生感冒机率较低。', 'aqi': '45'}, 'status': 1000}
    

    time模块

    时间相关的操作,有time,datetime两个模块.

    python中的时间表示,有三种方式:

    1. 1970年1月1日之后的秒,即:time.time()
    2. 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
    3. 结构化时间 是一个元组数据,元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
    import time
    import datetime
     
    print(time.time()) #返回当前系统时间戳
    print(time.ctime()) #输出Tue Jan 26 18:23:48 2016 ,当前系统时间
    print(time.ctime(time.time()-86640)) #将时间戳转为字符串格式
    print(time.gmtime(time.time()-86640)) #将时间戳转换成struct_time格式
    print(time.localtime(time.time()-86640)) #将时间戳转换成struct_time格式,但返回本地时间
    print(time.mktime(time.localtime())) #与time.localtime()功能相反,将struct_time格式转回成时间戳格式
    time.sleep(4) #常用,用来暂停
    print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将struct_time格式转成指定的字符串格式
    print(time.strptime("2016-01-28","%Y-%m-%d") ) #将字符串格式转换struct_time格式
     
    ################################
     
    print(datetime.date.today()) #输出格式 2016-01-26
    print(datetime.date.fromtimestamp(time.time()-864400) ) #2016-01-16 将时间戳转成日期格式
    current_time = datetime.datetime.now() #
    print(current_time) #输出2016-01-26 19:04:30.335935
    print(current_time.timetuple()) #返回struct_time格式
    
    ###############################################
     
    """datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])"""
    
    print(current_time.replace(2014,9,12)) #输出2014-09-12 19:06:24.074900,返回当前时间,但指定的值将被替换
    ############################################
    str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #将字符串转换成日期格式
    new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比现在加10天
    new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比现在减10天
    new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比现在减10小时
    new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比现在+120s
    

    具体时间的表示方式:

    %Y  Year with century as a decimal number.
    %m  Month as a decimal number [01,12].
    %d  Day of the month as a decimal number [01,31].
    %H  Hour (24-hour clock) as a decimal number [00,23].
    %M  Minute as a decimal number [00,59].
    %S  Second as a decimal number [00,61].
    %z  Time zone offset from UTC.
    %a  Locale's abbreviated weekday name.
    %A  Locale's full weekday name.
    %b  Locale's abbreviated month name.
    %B  Locale's full month name.
    %c  Locale's appropriate date and time representation.
    %I  Hour (12-hour clock) as a decimal number [01,12].
    %p  Locale's equivalent of either AM or PM.
    
    

    看起来复杂吧,来张图吧,应该就清楚了:

    logging模块

    logging用于记录日志且线程安全的模块.

    日志level的分类:

    CRITICAL = 50
    FATAL = CRITICAL
    ERROR = 40
    WARNING = 30
    WARN = WARNING
    INFO = 20
    DEBUG = 10
    NOTSET = 0
    

    但文件日志记录

    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')
    

    需要注意一点:只有【当前写等级】大于【日志等级】时,日志文件才被记录

    format格式中的一些说明:

    属性 格式化 描述
    args 将参数的元组合并进消息产生消息,或者将字典中对应的值合并为消息
    asctime %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    created %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
    exec_info 异常信息
    filename %(filename)s 调用日志输出函数的模块的文件名
    funcName %(funcName)s 调用日志输出函数的函数名
    levelname %(levelname)s 文本形式的日志级别
    levelno %(levelno)s 数字形式的日志级别
    module %(module)s 调用日志输出函数的模块名
    msecs %(msecs)d 创建日志时的毫秒时间
    message %(message)s 用户输出的消息
    msg 传入的格式化字符串
    name %(name)s logger的名字
    pathname %(pathname)s 调用文件的路径
    process %(process)d 调用日志系统的进程ID
    processNmae %(processNmae) 进程名字
    thread %(thread)d 线程
    threadName %(threadName)s 线程名称

    那么多文件的写入日志需要怎么搞呢?

    日志如果要模块化时,需要有4个知识点:

    • logger 创建一个在应用程序中用到的接口
    • handler 处理器,将logger产生的日志,发送给对应的文件
    • filter 过滤器,用来将符合条件的日志过滤出来
    • formatter 输出前格式化日志,形成你想要的格式的日志
    import logging
     
    ######## create logger
    logger = logging.getLogger('TEST-LOG')
    logger.setLevel(logging.DEBUG)
     
     
    ######## create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
     
    ######## create file handler and set level to warning
    fh = logging.FileHandler("access.log")
    fh.setLevel(logging.WARNING)
    
    ######## create formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
     
    ######## add formatter to ch and fh
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)
     
    ######## add ch and fh to logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    

    调用方式:

    logger.debug('debug message')
    logger.info('info message')
    logger.warn('warn message')
    logger.error('error message')
    logger.critical('critical message')
    

    解释下上面的代码:

    1. 创建一个logger接口
    2. 创建显示终端或文件,并设置日志级别
    3. 创建日志格式标准
    4. 格式标准添加至显示终端
    5. 将终端的handler添加至logger

    之前博客写过一篇日志处理的模块,链接:
    点我点我点我

  • 相关阅读:
    oracle闪回查询
    带搜索框的jQuery下拉框插件
    Eclipse、Tomcat、Spring3等使用过程的一些配置、错误等的总结记录
    局域网不能访问本机IIS网站的解决方法
    在同一台电脑部署多个Tomcat服务
    Tomcat重启脚本
    IE8下面parseInt('08')、parseInt('09')会转成0
    [转]Examining Open vSwitch Traffic Patterns
    [转]Ubuntu Precise
    [转] iptables
  • 原文地址:https://www.cnblogs.com/ccorz/p/5584183.html
Copyright © 2020-2023  润新知