""" 今日内容: 1、导入模块的细节 2、包的概念及使用 3、包的相对导入 """ """ 1、导入模块的细节 -- 在进行模块的导入时,进行的都是绝对路径的导入, -- 这是由于在执行文件过程中,会将执行文件所在的目录加入到sys.path(环境变量)中,虽然看起来在文件中只是import 模块名,但是系统会直接到sys.path中的绝对路径下寻找 -- 在pycharm执行文件时,系统不仅会将执行文件所在的目录添加进sys.path(环境变量)中,同时pycharm窗口中最大的那个文件夹也会自动加入到sys.path中 -- 但是在命令行中执行文件时,系统只会将执行文件当前所在的文件夹加入到sys.path(环境变量)中 -- 1、跨文件导入模块 -- 1、文件与被导入模块在一个目录下:由于文件在执行过程中,会将自己文件所在的目录加入到环境变量中(sys.path),所以同文件下可以直接进行导入 -- 2、执行文件与被导入模块不在同一个目录下,但是两者所在的目录处于同一个文件夹下,在pycharm中由于会默认将pycharm中最大的窗口加入到环境变量中,所以进行导入时不会报错 举例: 想要在 H:py8-studypracticeday17今日内容.py 文件中调用 H:py8-studypracticeday04while循环练习.py文件,且在pycharm中根目录为 practice 进行的操作为: -- from day04 import while循环练习 -- 3、如果执行文件与被导入模块不在同一个文件夹下,那么进行导入时会报错,此时需要在执行文件中使用sys.path.append()将模块的绝对路径添加进环境变量中 -- 【注】:需要注意的是,系统会主动将sys.path中绝对路径加入到导入的模块前方,所以只需要将路指明径剩下的部分就可以,如果路径名与sys.path中有重叠的部分也会报错 # 举例: 想要将 r'C:UsersAndyDesktopacb.py' 作为模块导入到执行文件中,此时,在执行文件中的操作是: -- import sys -- sys.path.append(r'C:UsersAndyDesktop') -- import acb -- 【需要注意的事】:在实际代码及模块的编写过程中,一般不需要自己手动添加sys.path中的路径 -- 因为我觉得在实际开发中如果想要调用模块会将模块与被执行文件放进相同的目录下或者放在同一个项目下,或者使用相对导入,这样会提高代码的可移植性,不容易报错。 -- 【重点】:在进行模块的导入时,需要遵循一定的规则,这个规则就是: -- 1、使用 import 导入模块时,最多只能导入到文件一级,因为 . 前面必须是文件夹名称 -- 2、使用from...import...进行导入时,也必须遵循 . 前面必须是文件夹名称的规则 -- 2、模块执行的两种方式 -- 1、作为自执行文件:直接执行文件自身 -- 2、作为模块进行执行:将文件作为模块进行导入执行 -- 【注】:需要注意的是,由于代码需要测试,我们经常会在模块中进行测试执行,但是又不想在导入模块时使文件中测试执行代码运行,此时就需要一个值来区分是本文件执行还是导入执行 -- 这个值就是__name__ -- 在本文件执行时,__name__ == "__main__" -- 在非本文件执行时,__name__ == "模块名" """ """ 2、包的概念及使用 -- 什么是包? -- 包就是一系列具有相似功能的模块的集合体,为了管理方便,会用文件夹来管理这一系列模块,这个文件夹就是包,文件夹名就是包名 -- 包与普通文件夹的区别? -- 在创建包时,会在包的根目录下创建一个__init__.py文件,这个__init__.py文件的名称空间就是这个包的名称空间 -- 在导入包时只需要导入包名就可以,将想要外界访问的功能添加进__init__.py的名称空间中就可以,可以直接通过 包名.的方法进行执行 -- 导入包时完成的三件事: -- 1、在导入包时,会首先进行编译,将__init__.py文件编译成.pyc文件 -- 2、执行__init__文件中的内容,将其中的变量放入__init__模块的全局名称空间中,在使用 包名. 语法时会直接访问__init__的全局名称空间 -- 3、在执行文产生一个与包名同名的变量,可以直接通过 包名. 语法访问包中的量 -- 【注】:在py3中会自动创建__init__文件,直接导入包名不会报错,但是在py2中不会自动创建,如果直接导入包名会报错。 -- 如果想要访问包中的变量或模块有两种办法: -- 1、直接通过绝对路径进入包中访问想要访问的变量或模块(此种方法不需要在包中设置__init__文件,因为次访问不会访问包的名称空间) -- 2、使用 包名. 的语法访问包中的变量及模块(此方法需要设置__init__文件,因为此方法是通过 包名. 的语法直接访问包中的变量及模块名,首先需要在包的名称空间中产生这些名字) -- 采用 包名. 语法访问包中变量或模块时需要注意的问题(包的管理): -- 1、 在执行文件中直接导入包名时,需要在__init__文件中设置好想要被外界访问变量 -- 设置方法为采用相对路径的方式 -- 由于在导入包名时会进入包中执行包中的文件,所以此时根目录就相当于是这个包,在__init__文件中只需要使用from . import 模块名 就可以将模块名添加进包的名称空间中 -- 实例:from .l111 import m111 就可以直接将 m111这个模块名直接放入包的全局名称空间中。 -- 2、在包中,可以使用 .来表示当前文件夹 | 使用 .. 来表示当前文件夹的上一级文件夹 --【需要注意的是:】 -- 在包中使用 .. 语法访问上一级目录时,是不能出包的,如果出包会报错 -- ValueError: attempted relative import beyond top-level package -- 在包中的文件是不能自执行的,因为包中的模块可能会包含有 from . import 模块名的语法,此时如果自执行文件会报错,因为 .前面肯定会增加一个路径 -- 如果是自执行会把 __main__作为路径加入到.前面,导致报错 """