zoukankan      html  css  js  c++  java
  • 包、相对导入和绝对导入、random模块、解压缩

    . 包,也是一种模块
    函数多了,可以分模块文件去管理
    模块多了,可以将模块分类,放在一个个文件夹中,这些文件夹就是包
    为的是使组织机构更加合理清晰

    模块本来就是拿来用的,而包是一些模块的集合,因此它也是被调用的

    文件:
    1.被别人使用
    2.当作脚本自己使用
    执行文件运行时,会将执行文件当前目录加载到sys.path列表中

    import sys
    print(666)
    print(sys.path)
    
    # 666
    # ['C:\Users\Shawn_Huang\Desktop\ATM'
    # 'C:\Users\Shawn_Huang\Desktop\ATM',
    # 'D:\Python36\python36.zip', 'D:\Python36\DLLs',
    # 'D:\Python36\lib', 'D:\Python36', 'D:\Python36\lib\site-packages',
    # 'E:\PyCharm 2018.3.1\helpers\pycharm_matplotlib_backend']
    # 这里列表中的第一个元素就是执行文件当前目录
    
    

    回顾,执行一个模块会发生三件事:

    1.在内存中创建一个以模块名命名的临时名称空间
    2.执行模块代码,将模块里面的代码加载到以模块名命名的临时名称空间
    3.调用模块内的名字必须通过模块名. 的方式调用

    因为包也是模块,是模块的集合体,因此import 一个包名,也会发生三件事:
    1.内存中创建一个以包名命名的名称空间
    2.执行包中的 __init__ 文件,将 __init__ 里面的代码块加载到以包名命名的名称空间
    3.调用包内的名字必须通过包名. 的方式调用
    # 假设有一个包,名为aaa,则在包aaa的 __init__ 文件中创建一个变量x,并给它赋值
    # 在本文件中,可以这样调用:
    # 这里能直接引用aaa,是因为本文件与 aaa 这个包在同一个目录下
    
    import aaa  # 执行 __init__ 文件里的内容
    print(aaa.x)
    
    # 如果 aaa 包里又有另一个 m2.py 文件,怎么办?
    import sys
    print(sys.path)
    # ['C:\Users\Shawn_Huang\Desktop\ATM',
    # 'C:\Users\Shawn_Huang\Desktop\ATM',
    # 'D:\Python36\python36.zip', 'D:\Python36\DLLs',
    # 'D:\Python36\lib', 'D:\Python36', 'D:\Python36\lib\site-packages',
    # 'E:\PyCharm 2018.3.1\helpers\pycharm_matplotlib_backend']
    
    # 这里 aaa 在这个 path 里面,但是 aaa 里面的 m2 不在这个 path 里
    # 因此在 __init__ 里面添加:
    
    from aaa import m2
    
    # 这样的话就可以在本文件里这样:
    import aaa
    print(aaa.m2)  # 这样就会引用 m2 文件里的所有内容
    # <module 'aaa.m2' from 'C:\Users\Shawn_Huang\Desktop\ATM\aaa\m2.py'>
    print(aaa.m2.s1)  # 这里可以被调用
    # 如果 aaa 包里还有很多文件,要想调用它,则可以在 __init__ 里面这样写
    # from aaa import *
    import aaa
    # 如果 aaa 包里还有一个 bbb 包,为了在本文件引用它
    # 应该在 __init__ 文件里加:
    from aaa import bbb
    
    # 引用 包 bbb 里的 __init__ 文件的 s2 变量,可以这样:
    print(aaa.bbb.s2)  # 包bbb的 __init__ 文件内容在这里
    
    # 如果包 bbb 里面又有一个m3.py文件,要引用这个文件的内容,按照以下步骤:
    # 1.在本文件 import aaa
    # 2.在 aaa 包的 __init__ 文件这样写: from aaa import bbb
    # 3.在 bbb 包的 __init__ 文件这样写: from aaa.bbb import m3
    print(aaa.bbb.m3.s3)  # 包 bbb 内的 m3 文件内容在这里
    
    # 上面三步只是为了了解过程,真正程序中可以这样写:—— 直接在本文件中写
    from aaa.bbb import m3
    print(m3.s3)  # 包 bbb 内的 m3 文件内容在这里
    
    # 一定要记住:本文件是执行文件,因此在 sys.path 里面会把它所在的目录添加进去
    # 而 aaa 这个包跟本文件在同一个文件夹内,即同一个目录,因此可以直接引用 aaa 的 __init__ 文件
    
    # 总结
    # 1. from a.b import c  .的左边一定是个包,import后面一定有个具体的名字
    # 2. 包里面的 __init__ 文件想要引用模块必须是from...import...  只有在执行文件里直接写 import,而包是被引用的,不能直接 import
    # 3.from a.b.c.d import e.f.g 错误,import 后面必须只有一个,应该把 .f.g 去掉后才行
    # 相对导入,绝对导入
    # 假设与本文件同目录有个nb.py,内容是这样:
    
    def f1():
        print("111")
    
    def f2():
        print("222")
    
    def f3():
        print("333")
    
    # 在本文件是这样引用的:
    import nb
    
    # 但是,如果随着代码更新,nb模块又增加了一百个函数,放在一个文件肯定不行,要分文件
    # 这时要注意,假如分文件时不能改变调用这个模块的调用方式
    # 这时py文件就应该改为一个包,然后在这个包里创建比如 m1, m2, m3文件,里面放内容
    # 如果只能以下这样调用,怎么改?
    import nb
    nb.f1()  # 111
    nb.f2()  # 222
    nb.f3()  # 333
    nb.f4()  # 444
    nb.f5()  # 555
    nb.f6()  # 666
    
    # 在nb 的 __init__ 里面这样写:—— 这是绝对导入
    from nb.m1 import f1, f2
    from nb.m2 import f3, f4
    from nb.m3 import f5, f6
    
    
    # 但是如果 nb 这里包必须改名,可以直接把 nb 包复制一份,包名重命名为 NB1,
    # 然后在 NB1 的 __init__ 文件里这样写:—— 相对导入
    from .m1 import f1, f2
    from .m2 import f3, f4
    from .m3 import f5, f6
    绝对导入与相对导入总结

    绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
    优点: 执行文件与被导入的模块中都可以使用
    缺点: 所有导入都是以sys.path为起始点,导入麻烦

    相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入符号:
    .代表当前所在文件的文件夹
    ..代表上一级文件夹
    ...代表上一级的上一级文件夹
    优点: 导入更加简单
    缺点: 只能在导入包中的模块时才能使用


    # 二. random 模块 随机模块
    
    import random
    
    print(random.random()) 
    # 大于0小于1之间的随机一个小数
    
    print(random.uniform(1, 3))  
    # 1-3之间的所有小数中的随机一个
    
    print(random.randint(1, 5))  
    # 1-5之间的整数,包括1和5
    
    print(random.randrange(1, 10, 2))  
    # 10以内的奇数的随机一个
    
    print(random.choice(["alex", "wusir", "日天"]))  
    # 多选一, choice()里面必须是容器类数据类型
    
    print(random.sample(["alex", "wusir", "日天", "太白"], 2))  
    # 多选多
    
    l1 = [1, 2, 3, 4, 5]
    random.shuffle(l1)
    print(l1)  # 对原列表打乱顺序
    # 生成随机验证码
    # 5个字符(包含0-9的数字,a-z的小写字母)
    # 思路:验证码肯定是字符串形式
    # 0-9 random.randrange(10)
    # a-z 利用小写字母对应的ascii来写 [chr[i] for i in range(97, 123)]
    # 二选一个字符
    # print(random.randrange(10))
    # print([chr(i) for i in range(97, 123)])
    
    def get_code():
        code = ""
        for i in range(5):
            num = str(random.randrange(10))
            s = chr(random.randint(97, 122))
            # 下面加个大写字母
            s1 = chr(random.randint(65, 90))
            single_s = random.choice([num, s, s1])
            code += single_s
        return code
    
    print(get_code())
    # shutil模块
    # 高级的 文件、文件夹、压缩包 处理模块
    
    # shutil.copyfileobj(fsrc, fdst[, length])
    # 将文件内容拷贝到另一个文件中:
    
    import shutil
    
    shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
    
    
    # shutil.copyfile(src, dst)
    # 拷贝文件
    shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
    
    # shutil.copymode(src, dst)
    # 仅拷贝权限。内容、组、用户均不变
    shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
    
    # shutil.ignore_patterns(*patterns)
    shutil.copytree(src, dst, symlinks=False, ignore=None)
    # 递归的去拷贝文件夹
    
    # import shutil
    
    shutil.copytree('folder1', 'folder2',
                    ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    
    #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
    # 打包与压缩
    
    import shutil
    import time
    import tarfile
    
    # 同一个文件夹下,直接写 "NB1_bak%s", 不在同一个文件夹写清路径
    # 然后如果压缩至同一个文件夹下,"gztar" 后面不用写 root_dir="路径",反之则反
    shutil.make_archive("NB1_bak%s" % time.strftime("%Y-%m-%d"), "gztar",)
    
    # 解压
    t = tarfile.open("NB1_bak2019-01-10.tar.gz", "r")
    t.extractall("这是新创的文件夹名字")
    t.close()
  • 相关阅读:
    Shared Memory in Windows NT
    Layered Memory Management in Win32
    软件项目管理的75条建议
    Load pdbs when you need it
    Stray pointer 野指针
    About the Rebase and Bind operation in the production of software
    About "Serious Error: No RTTI Data"
    Realizing 4 GB of Address Space[MSDN]
    [bbk4397] 第1集 第一章 AMS介绍
    [bbk3204] 第67集 Chapter 17Monitoring and Detecting Lock Contention(00)
  • 原文地址:https://www.cnblogs.com/shawnhuang/p/10249945.html
Copyright © 2011-2022 走看看