本节内容

Python全栈开发之路 【第六篇】:Python基础之常用模块
模块分类:
    好处:
    标准库:
        help("modules") 查看所有python自带模块列表
    第三方开源模块:
    自定义模块:

模块调用: import module
         from os import rmdir
         from module.xx.xx import xx as rename
         from module.xx import *  (不推荐)

    注意: 模块一旦被调用,就相当于执行了另为一个py文件里的代码。

自定义模块:
         查找模块路径依据:当前目录范围、sys.path ---> 只在当前程序里有效
         site-packages: 所有的标准库,包括第三方 和 自带模块。
                        依次去查找module

开源模块安装、使用:
         https://pypi.python.org/pypi 是python的开元模块库。
         pip install PyTrion
         怎么去配置国内的豆瓣源。

包(Package)及跨模块导入:
         包: 一个文件夹管理多个模块文件,这个文件夹就成为包。
         crm  proj  manage.py 都在同一级别下
         从当前路径下寻找,想在manage.py里导入views.py ---> from crm import views

         python2:
             包就是文件夹,但该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。
             __int__.py用于标识当前文件夹是一个包。
         python3:
             在python3里,即使目录下没__int__.py文件也能创建成功,
             猜应该是解释器优化所致,但创建包还是要记得加上这个文件.
    跨模块的导入:
         为什么crm包里的views.py想导入proj包里的settings.py
            ---> sit-packages 列表打印的第一个值是''''代表着总入口程序manage.py所在的路径
            而不是执行views.py 的路径。只有入口的程序的路径会加入到sit-packages里,
            而里面间接的调用不管多少层和views.py 没关系。
            只要manage.py的路径在sie-packages里,只能是from proj import setting。

跨模块导入2:
    问题一:
         把views.py作为入口文件,在views.py里导入proj文件里的settings.py
            ---> import os,sys
                 # sys.path.append("……/my_proj/")
                 # print(dir())
                 # print(__file__)  ---> 在pycharm里打印的是绝对路径,但在命令行里打印相对路径
                 # print(os.path.abspath(__file__)) ---> 就是真正的获取 绝对路径
                 # os.path.dirname() 的作用是 在绝对路径的基础上 返到上一层。
                 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
                 sys.path.append(BASE_DIR)
                 from proj import settings
    "出手就是专业的"
    程序在哪执行,当前路径就是那个。要想导入其他模块,就要找到那个模块的路径。

相对导入:
    问题一:
        在入口manages.py里导入在crm文件夹里的views.py, 在views.py里导入models
            --->在views.py里:
                 import models # 错误,原因: 因为当前路径是manages.py的所在路径,没有models.py,
                                           并且sit-packages里也没有。不要认为views与models同级别就可以!
                 from crm import models  # 正确写法
                 from . import models  # 正确写法, . 代表相对导入

                 from ..proj import settings
                 -> SystemError: Parent module '' not loaded, cannot perform relative import
                 -> 或 ValueError: attempted relative import beyond top-level package
                 这两个错误的原因归根结底是一样的:在涉及到相对导入时,package所对应的文件夹必须正确的被python解释器视作package,
                 而不是普通文件夹。否则由于不被视作package,无法利用package之间的嵌套关系实现python中包的相对导入。
    文件夹被python解释器视作package需要满足两个条件:
        1、文件夹中必须有__init__.py文件,该文件可以为空,但必须存在该文件。
        2、不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口)。

time模块详解:
    time.time(): 当前时间戳, 从1970.2.1 8:00年到现在
    time.localtime(): 本地时间 (是操作系统的时间)
    time.gmtime(): 将一个时间戳转换为UTC时区(0时区)的struct_time。
    time.mktime(): 将一个struct_time转化为时间戳。
    time.sleep(): 推迟执行时间
    time.asctime(): 形式:'Sun Oct 1 12:04:38 2017'
    time.ctime():
    time.strftime('%Y-%m-%d %H:%M:%S %A', 时间对象):
    time.strptime():

datetime模块详解:
    datetime.date: 表示日期的类。常用的属性有year, month, day;
    datetime.time: 表示时间的类。常用的属性有hour, minute, second, microsecond;
    datetime.datetime.now(): 返回当前的datetime日期类型
    datetime.date.fromtimestamp(time.time()): 把一个时间戳转为datetime日期类型
    datetime.datetime: 表示日期时间。
    datetime.timedelta: 表示时间间隔,即两个时间点之间的长度。

    时间运算:
        >>> datetime.datetime.now()
        datetime.datetime(2018, 5, 8, 15, 55, 8, 864325)
        >>> datetime.datetime.now() + datetime.timedelta(4) #当前时间 +4天
        datetime.datetime(2018, 5, 12, 15, 55, 33, 643242)
        >>> datetime.datetime.now() + datetime.timedelta(hours=4) #当前时间+4小时
        datetime.datetime(2018, 5, 8, 19, 55, 53, 93034)

    时间替换:
        >>> d = datetime.datetime.now()
        >>> d.replace(year=2999,month=11,day=30)
        datetime.date(2999, 11, 30)

random模块:
    random.randint(1,100): 1-100之间的随机数,包含100
    random.randrange(1,100): 1-100之间的随机数,不包含100
    random.choice('assxds$#%ds'): 返回一个给定数据集合中的随机字符
    random.sample('abcdefghi',3): 从多个字符中选取特定数量的字符['a', 'd', 'b']
    random.random(): 返回一个随机浮点数
    生成随机字符串: 随机验证码
        >>> import string
        >>> ''.join(random.sample(string.ascii_lowercase + string.digits, 6))
        '4fvda1'

        >>> string.digits
        '0123456789'
        >>> string.ascii_letters
        'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        >>> string.hexdigits
        '0123456789abcdefABCDEF'
        >>> string.octdigits
        '01234567'
        >>> string.ascii_lowercase
        'abcdefghijklmnopqrstuvwxyz'
        >>> string.ascii_uppercase
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
        >>>string.punctuation
        '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
    洗牌:
        >>> a
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        >>> random.shuffle(a)
        >>> a
        [3, 0, 7, 2, 1, 6, 5, 8, 9, 4]

os模块:
    得到当前工作目录,即当前Python解释器 脚本工作的目录路径: os.getcwd()
    返回指定目录下的所有文件和目录名:os.listdir()
    函数用来删除一个文件:os.remove()
    删除多个目录:os.removedirs(r“c:\python”)
    检验给出的路径是否是一个文件:os.path.isfile()
    检验给出的路径是否是一个目录:os.path.isdir()
    判断是否是绝对路径:os.path.isabs()
    检验给出的路径是否真地存:os.path.exists()
    返回一个路径的目录名和文件名:os.path.split()     e.g os.path.split('/home/swaroop/byte/code/poem.txt') 结果:('/home/swaroop/byte/code', 'poem.txt')
    分离扩展名:os.path.splitext()       e.g  os.path.splitext('/usr/local/test.py')    结果:('/usr/local/test', '.py')
    获取路径名:os.path.dirname()
    获得绝对路径: os.path.abspath()
    获取文件名:os.path.basename()
    运行shell命令: os.system()
    读取操作系统环境变量HOME的值:os.getenv("HOME")
    返回操作系统所有的环境变量: os.environ
    设置系统环境变量,仅程序运行时有效:os.environ.setdefault('HOME','/home/alex')
    给出当前平台使用的行终止符:os.linesep    Windows使用'\r\n',Linux and MAC使用'\n'
    指示你正在使用的平台:os.name       对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'
    重命名:os.rename(old, new)
    创建多级目录:os.makedirs(r“c:\python\test”)
    创建单个目录:os.mkdir(“test”)
    获取文件属性:os.stat(file)
    修改文件权限与时间戳:os.chmod(file)
    获取文件大小:os.path.getsize(filename)
    结合目录名与文件名:os.path.join(dir,filename)
    改变工作目录到dirname: os.chdir(dirname)
    获取当前终端的大小: os.get_terminal_size()
    杀死进程: os.kill(10884,signal.SIGKILL)

sys模块:

shutil模块:
    高级的 文件、文件夹、压缩包 处理模块.
    shutil.copyfileobj(fsrc, fdst[, length]):将文件内容拷贝到另一个文件中.
    shutil.copyfile(src, dst): 拷贝文件.
    shutil.copymode(src, dst): 仅拷贝权限。内容、组、用户均不变.
    shutil.copystat(src, dst): 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
    shutil.copy(src, dst): 拷贝文件和权限.
    shutil.copy2(src, dst): 拷贝文件和状态信息.
    shutil.ignore_patterns(*patterns)
    shutil.copytree(src, dst, symlinks=False, ignore=None): 递归的去拷贝文件夹
    shutil.rmtree(path[, ignore_errors[, onerror]]): 递归的去删除文件
    shutil.move(src, dst): 递归的去移动文件,它类似mv命令,其实就是重命名。
    shutil.make_archive(base_name, format,...): 创建压缩包并返回文件路径,例如:zip、tar
                                                创建压缩包并返回文件路径,例如:zip、tar
    base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,

序列化模块: json & pickle
    序列化是指把内存里的数据类型转变成字符串,
    以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes

    json模块:
        import json
    ①  d = json.dumps(data)  # 把data变成字符串
        f = open("test.json", 'w', encoding='utf-8')
        f.write(d)
        f.close()

    ②  f = open("test.json", "w")
        json.dump(data, f)  # 转成字符串, 并写入文件里
        或 json.dump(data,open("test.json", "w"))

    ③  d = json.dumps(data)  # 仅把data变成字符串.(现在状态仅存在内存里)
        d2 = json.loads(d)  # 从序列化中读出来

    ④  f = open("test.json", "r")
        json.load(f)

    只是把数据类型转换成字符串存到内存里的意义?
        json.dumps()   json.loads()
      1、把你的内存数据 通过网络 共享给远程其他人.
      2、定义了不同语言的之间的交互规则(跨平台、体积小)

    注意: dumps只能进行一次, loads多次会出错!
         json序列化的数据类型 只能支持int\str\list\tuple\dict

pickle模块:
    import pickle
    与 json 模块用法相同, dumps、dump、loads、load

    d = {'name': 'hyp', 'age': 22}
    pk = open("data.pkl", "wb")
    # print(pickle.dumps(d))  # 结果: b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00hypq\x02X\x03\x00\x00\x00ageq\x03K\x16u.'
    pickle.dump(d, pk)

    f = open("data.pkl", "rb")
    d = pickle.load(f)
    print(d)

    注意: 优点:专为python设计,支持python所有的数据类型
         缺点: 缺点:只能在python中使用,存储数据占空间大

序列化shelve模块:
    import shelve
        shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,
        可以持久化任何pickle可支持的python数据格式
    可以修改,但只能是以给key重新赋值的方式改。
    可以添加,删除

xml处理模块:  <>节点
    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,
    但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,
    大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

    import xml.etree.ElementTree as ET
    tree = ET.parse("xml test")  # open
    root = tree.getroot()  # 相当于 f.seek(0)
    print(root.tag)  # 打印标签: data

    # 遍历xml文档
    for child in root:  # 循环每一个<country>
        print(child.tag, child.attrib)  # child.tag -> country, child.attrib ->字典结构的数据
        for i in child:  # 循环每一个country下的结构
            print(i.tag, i.text)

    # 只遍历year 节点
    for node in root.iter('year'):
        print(node.tag, node.text)

    # 修改和删除xml文档内容
    for node in root.iter('year'):
    new_year = int(node.text) + 1
    node.text = str(new_year)
    node.set("updated", "yes")  # 存储属性,存到country的后面
    tree.write("xml test")

    #删除node
    for country in root.findall('country'):  # 查找所有的country节点
       rank = int(country.find('rank').text)  # 找到所有rank的值
       if rank > 50:
         root.remove(country)  # 删掉rank>50的country
    tree.write('output.xml')

    # 自己创建xml文档
    import xml.etree.ElementTree as ET

    # 根(root)是namelist
    root = ET.Element("namelist")
    # 创建子节点name 和 对应的属性attrib
    name = ET.SubElement(root, "name", attrib={"enrolled":"yes"})
    # 在name节点下放的参数age,sex,
    age = ET.SubElement(name, "age", attrib={"checked":"no"})
    sex = ET.SubElement(name, "sex")
    sex.text = 'male'  # 给sex赋值

    # 第二个节点: name2
    name2 = ET.SubElement(root, "name", attrib={"enrolled":"no"})
    age = ET.SubElement(name2, "age")
    age.text = '19'  # 给age赋值

    et = ET.ElementTree(root)  # 生成文档对象
    # xml_declaration ---> 版本号声明
    et.write("build_out.xml", encoding="utf-8", xml_declaration=True)

    ET.dump(root) #打印生成的格式

configparser模块:
    此模块用于生成和修改常见配置文档
    [DEFAULT]里默认存储每一个节点里都要有的默认值

    解析配置文件:
        >>> import configparser # 导入模块
        >>> config = configparser.ConfigParser()  # 实例化(生成对象)
        >>> config.sections()  # 调用sections方法
        []

        >>> config.read('config.ini')  # 读配置文件(注意文件路径)
        ['config.ini']

        >>> config.sections()  # 调用sections方法(默认不会读取default)
        ['bitbucket.org', 'topsecret.server.com']

        # 会默认打印DEFAULT下的
        for k, v in conf["bitbucket.org"].items():
            print(k, v)

        >>> 'bitbucket.org' in config  # 判断元素是否在sections列表内
        True

        >>> 'bytebong.com' in config
        False

        >>> config['bitbucket.org']['User']  # 通过字典的形式取值
        'hg'

        >>> config['DEFAULT']['Compression']  #
        'yes'

        >>> topsecret = config['topsecret.server.com']
        >>> topsecret['ForwardX11']
        'no'

        >>> topsecret['Port']
        '50022'

        >>> for key in config['bitbucket.org']: print(key)  # for循环 bitbucket.org 字典的key
        ...
        user
        compressionlevel
        serveraliveinterval
        compression
        forwardx11
        >>> config['bitbucket.org']['ForwardX11']
        'yes'


    其它增删改查语法:

hashlib加密模块:

subprocess模块:
    run()
    call()
    Popen()

logging模块:
    logging的日志可以分为:
    debug(), info(), warning(), error() and critical()5个级别.
    调试      记录    潜在问题    出问题        严重问题

    StreamHandler、FileHandler设置的日志级别要 高于 全局设置的日志级别,
    否则不起作用!  (全局的日志级别默认是 warning)

re模块:


软件开发目录规范:
模块笔记

相关文章: