zoukankan      html  css  js  c++  java
  • Python学习笔记

    模块与包

    一个模块就是一个包含了Python定义和声明的文件,文件名就是模块名加上.py的后缀,导入一个py文件,解释器解释该py文件,导入一个包,解释器解释该包下的 __init__.py 文件,所以如果我们要创建一个包文件,那么该文件下必须要有__init__.py文件。

    从目录级别来组织模块的,本质上也是被导入的,目录下有 __init__ 文件的都可以理解为包,在import时,其实导入的就是包下的 __init__.py 文件。

    • 无论是import形式,还是from...import形似,凡是在导入语句中(而不是使用时)遇到带点的,就是在导入包
    • 包是目录级的(文件夹),文件夹是用来组织py文件的。(包的本质就是一个包含 __init__.py 文件的目录)
    • import导入文件时,产生的名称空间来源于文件,import包,产生的命名空间同样来源于文件,既包下面的__init__.py,导入包的本质就是导入该文件

    包的import *

    这个* 其实读取的就是 __init__ 文件里面的所有函数,所以一般不要用*
    通过在父包内的__init__文件中利用相对路径进行导入子包的模块或者方法,来达到通过(父包.方法)来调用,屏蔽了不同子包路径过长的问题

    模块

    要想使用模块需要先行倒入,那么根据导入方式的不同主要有两种方式:import 和 from。

    import导入

    导入操作:
      1)import导入模块就会执行要导入的模块的所有代码
      2)产生新的名称空间
      3)拿到一个模块名,指向模块中的代码
    语法:

    import module as alias  # 导入时并定义别名
    import module,module1,module2  # 一次导入多个模块(不建议)
    

    调用方式:使用包名.函数名来执行导入的函数

    import time
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    
    # 导入time模块
    # 使用 time.strftime()来调用strftime()函数
    

    注意:使用import方式会导入包中的所有函数。

    from导入      

    导入操作:
      1)会执行要导入的模块的所有代码,调用时只通过func就可以调用
      2)如果func和本文件中存在同名func,那么就会覆盖
    语法:

    from module import func  # 调用时可以直接使用func,而不必使用module.func来调用
    from module import * # 导入所有函数
    

    PS:在被导入模块的__init__.py文件中定义__all__ = ['module','module1'],这样在导入其时,用*,只能导入 __all__ 定义的模块

    调用方式:直接使用函数名进行调用。 

    from time import strftime
    print(strftime('%Y-%m-%d %H:%M:%S'))

    PS:func来自哪个文件,那么func内部调用的变量,以其所在文件中的环境变量为准

    模块中的特殊关键字及路径

    模块文件中有一些Python提供的特殊关键字,例如
    __file__ :打印当前文件的文件名
    __name__ :显示当前模块是否被导入,显示:__main__ 表示没有被导入,显示:模块名, 表示被此模块被导入。
    PS:如果我们写的Python文件中的某个函数或者类会被其他人调用,使用if __name__ == '__main__' ,后面写主逻辑,这样在别的地方导入,就不会执行下面的代码段,而直接运行文件时,就会执行。

    模块路径      

    顾名思义,导入模块是需要先找到该模块,和在linux中执行命令是相同的,在Python中导入模块的搜索顺序:

    1. 先从内存中寻找
    2. 然后在内置模块中寻找
    3. 然后在sys.path中查找

    关于sys.path,类似于shell中的PATH,其是list类型,每个元素为路径的字符串形式,列表的第一个路径默认为当前路径,使用sys.path.append('dirpath'),就可以把路径加入到sys.path中

    Python内置模块 

    Python中内置了很多模块,可以提供很多实用的功能,下面将会列举部分模块。

    datetime模块

    提供时间功能的模块其实不止datetime,Python内置的还有一个time模块,time模块可以完成格式化输出,但是用起来没有datetime模块方便,但在下面场景下会用到time模块

    import time
    for i in range(1,10):
        print(i)
        time.sleep(1)     # 类似于Linux中的sleep命令。

    获取当前日期和时间

    datetime.now() 格式化输出一个datetime.datetime对象,打印则显示当前时间

    from datetime import datetime
    print(type(datetime.now()))
    print(datetime.now())

    注意到datetime是模块,datetime模块还包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类,如果仅导入import datetime,则必须引用全名datetime.datetime.now()

    获取指定的日期与时间

    通过是datetime对象实例化的时候,传入指定的时间参数,来获取指定的日期与时间的时间格式字符。

    from datetime import  datetime
    
    timer = datetime(2017,11,9,11,20)
    print(timer)
    

    注意:时间日期如果是个位数,不能手动补0,比如9可以,09就不行。

    获取时间戳

    在计算机中,时间实际上是用数字表示的。我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time(元时间),记为0(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp(时间戳)。

    • 所以针对于元时间来说:timestamp = 0 = 1970-1-1 00:00:00 UTC+0:00
    • 对应的北京时间是:timestamp = 0 = 1970-1-1 08:00:00 UTC+8:00(因为北京属于东八区)

    可见timestamp的值与时区毫无关系,因为timestamp一旦确定,其UTC时间就确定了,转换到任意时区的时间也是完全确定的,这就是为什么计算机存储的当前时间是以timestamp表示的,因为全球各地的计算机在任意时刻的timestamp都是完全相同的(假定时间已校准)。

    from datetime import datetime
    
    print(datetime.now().timestamp())
    
    # 注意 timestamp(),方法可以作用在datetime.datetime对象上。 (datetime(2017,11,9,11,50)因为返回的是datetime.datetime对象,所以也可以使用timestamp()来转换)
    

    时间戳转换为格式化时间

    要把timestamp转换为datetime,使用datetime提供的fromtimestamp()方法:

    from datetime import datetime
    t = datetime.now().timestamp()
    print(t)
    t2 = datetime.fromtimestamp(t)
    print(t2) 

    注意到timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。上述转换是在timestamp和本地时间做转换。如果我们计算机本地时间为 UTC +8,那么获得的时间就是基于本地UTC时间的。

    获取前几个小时或后几天

    获取前几个小时或后几天,其实是对日期和时间进行加减,得到新的datetime。加减可以直接用+-运算符,不过需要导入timedelta这个类:

    from datetime import  datetime,timedelta
    
    now = datetime.now()
    
    timer = now - timedelta(hours=10)
    
    print(timer)
    
    # timedelta 默认为天,其他参数还有 days,hours,minutes等。
    # 传递的参数可以为负数
    

    datetime对象转换为字符串时间

    如果已经有了datetime对象,要把它格式化为一个特定的字符串显示给用户,就需要转换为str,转换方法是通过strftime()实现的,同样需要一个日期和时间的格式化字符串:

    from datetime import  datetime
    
    str_time = datetime.now().strftime('%Y-%M-%d %H:%M:%S')
    
    print(str_time)
    

    字符串时间转换为datetime对象

    很多时候,用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过datetime.strptime()实现,需要一个日期和时间的格式化字符串:‘

    from datetime import datetime
    
    str_time = '2017-11-09 17:15:48'
    
    date_time = datetime.strptime(str_time,'%Y-%m-%d %H:%M:%S')
    print(date_time)
    

    logging模块

    logging模块用于日志的打印记录等,是一个健壮的Python程序所必须具有的模块。

    logging模块支持的日志级别主要有五种:DEBUG,INFO,WARNING,ERROR,CRITICAL。优先级为:CRITICAL > ERROR > WARNING > INFO > DEBUG 。 默认的级别为WARNING。Python只会打印比当前级别高的日志,比如我同时刷出了INFO和ERROR级别的日志,如果我的日志级别设置的为WAIRNING,那么只会打印ERROR的日志。

    基本使用

    引入logging模块,通过logging.级别来输出日志信息

    import logging
    
    logging.debug('debug level message')
    logging.info('info level message')
    logging.warning('warning level message')
    logging.error('error level message')
    logging.critical('crtical level message')
    

    注意:由于默认级别为WARNING,所以上面的例子只会打印WARNING、ERROR、CRITICAL输出的信息

    定义日志格式并输出到文件

    logging提供了基础的日志模版,可以定义日志的输出格式,以及输出位置

    import logging
    
    
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        filename='log.log',
                        filemode='w')
    
    logging.debug('debug level message')
    logging.info('info level message')
    logging.warning('warning level message')
    logging.error('error level message')
    logging.critical('crtical level message')
    

    basicConfig支持的参数含义为:

    • level:为日志级别,可选参数有logging.DEBUG,logging.INFO,logging.WARNING,logging.ERROR,logging.CRITICAL,分别对应logging的五种日志级别。
    • filename: 表示日志文件的名称及路径。
    • filemode: 表示日志文件的打开模式,默认不指定的情况下为a,可以改为w。
    • datefmt: 对时间进行格式定制,和时间的格式化字符是相同的。
    • format: 对日志格式进行定义。
     1 %(name)s  # Logger的名字
     2 %(levelno)s  # 数字形式的日志级别
     3 %(levelname)s # 文本形式的日志级别
     4 %(pathname)s # 调用日志输出函数的模块的完整路径名,可能没有
     5 %(filename)s # 调用日志输出函数的模块的文件名
     6 %(module)s # 调用日志输出函数的模块名
     7 %(funcName)s # 调用日志输出函数的函数名
     8 %(lineno)d # 调用日志输出函数的语句所在的代码行
     9 %(created)f # 当前时间,用UNIX标准的表示时间的浮 点数表示
    10 %(relativeCreated)d # 输出日志信息时的,自Logger创建以 来的毫秒数
    11 %(asctime)s # 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    12 %(thread)d # 线程ID。可能没有
    13 %(threadName)s # 线程名。可能没有
    14 %(process)d # 进程ID。可能没有
    15 %(message)s # 用户输出的消息
    format支持的日志格式

    当然logging还有更多灵活的模块:logger,handler,filter,formatter。参考:http://www.jb51.net/article/88449.htm 

    多模块利用logging记录日志

    我们可以把logging写到一个模块中,然后在需要记录的地方,导入模块,记录信息即可。

    # writelog模块:
    import logging
    
    logging.basicConfig(level=logging.WARNING,
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        filename='log.log',
                        filemode='a')
    
    
    
    
    # 需要记录日志的py文件
    import writelog
    
    writelog.logging.debug('debug level message')
    writelog.logging.info('info level message')
    writelog.logging.warning('warning level message')
    writelog.logging.error('error level message')
    writelog.logging.critical('crtical level message')
    

    OS模块 

    OS模块简单的来说它是一个Python的系统编程的操作模块,可以处理文件和目录这些我们日常手动需要做的操作,和所在的操作系统版本无关。

    查看OS模块的帮助文档

    >>> import os  # 导入os模块
    >>> help(os)   # 查看os模块帮助文档,里面详细的模块相关函数和使用方法
    

    常用功能介绍 

    os模块中提供了特别多的和系统相关的操作功能,这里列举一些常用功能 

    os.getcwd()   # 获取当前路径
    os.chdir()  # 切换当前目录,当路径中存在的时候,由于是转意的意思,那么就需要对进行转意,那么路径就是c:\User,或者在目录前面加r,表示后面的字符串不进行解释
    os.curdir()  # 获取当前目录名
    os.pardir()  # 获取上级目录名
    os.mkdir('dir')  # 创建目录,注意只能创建一级目录
    os.makedirs('dir_path')  # 创建多级目录
    os.rmdir('dir')  # 删除一个目录
    os.removedir('dir_path')  # 删除多级目录(目录为空的话)
    os.listdir('dir')  # 显示目录下的所有文件,默认为当前目录,返回的结果为list
    os.remove('file')  # 删除一个文件
    os.rename('old_name','new_name')  # 修改文件名称
    os.stat('file/dir')  # 获取文件/目录的stat信息
    os.sep  # 返回当前操作系统的路径分隔符
    # Windows下:\ , Linux下:/
    os.linesep  # 返回当前操作系统的换行符
    # Windows下:
      ,Linux下:
    
    os.pathsep  # 返回当前操作系统环境变量分隔符
    # Windows下:;   ,   Linux下: :
    os.name  # 返回当前系统的类型
    # nt 表示Windows,  posix表示Linux
    os.system('Commmand')  # 执行命令
    os.environ  # 获取系统环境变量,使用字典存储
    os.path.abspath('dir/file')  # 获取dir/file的绝对路径
    os.path.split('path')  # 把路径分割为目录和文件名组成的元组格式,不管path是否存在
    os.dirname('path')  # 获取文件的父目录名称,不管path是否存在
    os.basename('path')  # 获取文件的名称,不管path是否存在
    os.path.exists('path')  # 判断path是否存在,return bool
    os.path.isabs('path')  # 判断path是否是从根开始,return bool
    # Linux下:从/开始    Windows下从C,D,E盘开始
    os.path.isfile('path')  # 判断path是否是一个文件
    os.path.isdir('path')  # 判断path是否是一个目录
    os.path.join('path1','path2')  # 把path1和path2进行组合
    os.path.getatime('path')  # 获取文件的atime时间,返回时间戳
    os.path.getmtime('path')  # 获取文件的mtime时间,返回时间戳
    os.path.getsize('name')  # 获取文件的大小
    

    commands模块

    commands模块专门用于调用Linux shell命令,并返回状态和结果,和os的popen功能类似,该模块一共有三个函数:getoutput,getstatus,getstatusoutput

    commands.getoutput('Linux shell command')   # 执行Linux shell命令,并获取命令执行的结果
    commands.getstatus('filename')    # 传递filename,执行 'ls -ld  filename' 的命令。
    commands.getstatusoutput('Linux shell command')   # 执行Linux shell命令,返回的是一个元组.。(命令返回code,结果)
    

    实例:

    >>> import commands
    >>> commands.getoutput('who')
    'DahlHin  console  Nov  9 09:38 
    DahlHin  ttys000  Nov 10 10:30 '
    >>> commands.getstatus('.pip')
    'drwxr-xr-x  3 DahlHin  staff  96 10 21 21:44 .pip'
    >>> commands.getstatusoutput('asasas')
    (32512, 'sh: asasas: command not found')
    >>> 
    

    注意:commands模块在Python 3.x中已经被subprocess替代!

    sys模块

    sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。 

    常用函数:

    sys.path # 列出当前Python环境变量,也就是导入时模块的搜索路径
    sys.argv # 类似于shell脚本的$1 $2 ,用于传递命令行参数,使用列表进行传递
    sys.stdout.write(‘#’) # 在屏幕上输出,但是不换行,配合for循环,比较适合用来做进度条等
    sys.stdout.flush() # 配合sys.stdout.write使用,把每次输出的信息,强制刷新到屏幕上,达到动态的效果
    
    1 import sys,time
    2 for i in range(20):
    3     sys.stdout.write('=')
    4     sys.stdout.flush()
    5     time.sleep(1)
    进度条的动态效果

    注意:我们可以把自己写的一些模块加到Python环境变量中去,由于sys.path是list类型,所以只需要append('path'),就可以完成添加。

     1 sys.modules.keys() # 返回所有已经导入的模块列表
     2 sys.exc_info()  # 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
     3 sys.exit(n)  # 退出程序,正常退出时exit(0)
     4 sys.hexversion  # 获取Python解释程序的版本值,16进制格式如:0x020403F0
     5 sys.version  # 获取Python解释程序的版本信息
     6 sys.maxint  # 最大的Int值
     7 sys.maxunicode  # 最大的Unicode值
     8 sys.modules  # 返回系统导入的模块字段,key是模块名,value是模块
     9 sys.platform # 返回操作系统平台名称
    10 sys.stdout  # 标准输出
    11 sys.stdin  # 标准输入
    12 sys.stderr  # 错误输出
    13 sys.exc_clear()  # 用来清除当前线程所出现的当前的或最近的错误信息
    14 sys.exec_prefix  # 返回平台独立的python文件安装的位置
    15 sys.byteorder  # 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
    16 sys.copyright  # 记录python版权相关的东西
    17 sys.api_version  # 解释器的C的API版本
    其他的sys模块函数

    json&pickle模块

    json和pickle模块是用来做序列化的,为什么要序列化?序列化可以持久保存状态,还可以跨平台数据交互。

    如何序列化?可以使用json或者pickle模块

    1. json(跨平台) 支持字典(dict)、列表(list)、字符串(str)、整型浮点型(int/float)、bool(True,False),null(None)。
    2. pickle(纯Python),可以序列化存储python所有的对象,甚至是一个函数,但是只能和Python程序进行交互,其他凭他不支持。

    eval不能识别非Python语法的数据类型,所以很多时候要用json

    json

    json支持跨平台的序列化存储以及反序列化读取。

    • 序列化:dump,dumps
    • 反序列化:load,loads
    1 # json.dumps 表示序列化,会返回一个序列化后的对象。
    2 
    3 import json
    4 
    5 a = [1,2,3,4]
    6 
    7 b = json.dumps(a)
    8 
    9 print(type(b))
    json.dumps
     1 # json.dump 表示序列化存储到文件中去
     2 
     3 import json
     4 
     5 a = [1,2,3,4,5]
     6 
     7 with open('log.log','w') as f:
     8     json.dump(a,f)
     9 
    10 
    11 # dump 需要两个参数,持久化的存储的对象,第二个是一个可写的文件描述符。
    json.dump
     1 # json.loads 从json字符串反序列化为对象
     2 import json
     3 
     4 a =  '[1, 2, 3, 4]'
     5 
     6 print(type(a))
     7 
     8 b = json.loads(a)
     9 
    10 print(type(b))
    11 
    12 print(b)
    json.loads
    1 # json.load 从文件中反序列化为对象
    2 import json
    3 
    4 with open('hello.txt','r') as f:
    5     b = json.load(f)
    6 
    7 print(b)
    json.load

    pickle

    pickle仅python支持,在序列化到文件中的时候没需要用b模式打开才可以。

    • 序列化:dump,dumps
    • 反序列化:load,loads
     1 # pickle.dumps 把对象序列化为bytes格式数据
     2 import pickle
     3 
     4 a = {
     5     'name':'daxin',
     6     'age':18,
     7     'job':'Linux'
     8 }
     9 
    10 b = pickle.dumps(a)
    11 print(b)
    12 print(type(b))
    pickle.dumps
     1 # pickle.dump 序列化到文件中
     2 import pickle
     3 
     4 a = {
     5     'name':'daxin',
     6     'age':18,
     7     'job':'Linux'
     8 }
     9 
    10 with open('hello.txt','wb') as f:
    11     pickle.dump(a,f)
    pickle.dump
    1 # pickle.loads 把bytes对象反序列化
    2 import pickle
    3 
    4 b = b'x80x03}qx00(Xx04x00x00x00nameqx01Xx05x00x00x00daxinqx02Xx03x00x00x00ageqx03Kx12Xx03x00x00x00jobqx04Xx05x00x00x00Linuxqx05u.'
    5 
    6 a = pickle.loads(b)
    7 
    8 print(a)
    pickle.loads
    1 # pickle.load 从文件中反序列化
    2 import pickle
    3 
    4 with open('hello.txt','rb') as f:
    5     a = pickle.load(f)
    6 
    7 print(a)
    pickle.load

    注意:

      json序列化后的对象类型为str,pickle序列化后的对象类型为bytes,所以pickle序列化/反序列化时对文件的操作需要用b模式。

    备份一个好用的json转换网站:https://www.json.cn/

    random模块

    顾名思义,用来产生随机数的模块,它有 如下几个常用的方法

    random.randint(a,b)         # 在a,b之间随机选出一个数(包含a,b本身)
    random.randrange(a,b,step)  # 这里和range的使用方法是相同的
    random.choice(iterable)     # 在一个可迭代对象中随机选择
    random.shuffle(seq)         # 原地对序列进行洗牌(随机打乱)
    

      

  • 相关阅读:
    封装logging模块,创建日志器
    excel的读写封装,利用openpyxl
    利用yaml封装配置文件模块
    自动生成小学四则运算项目(更新)
    基于cmmi的软件工程及实训指导 第一章 读后感
    第一次数据库学习
    第一个爬虫和测试
    预测球队成绩
    第一个网页
    科学计算与可视化
  • 原文地址:https://www.cnblogs.com/dachenzi/p/7808198.html
Copyright © 2011-2022 走看看