模块和包

1 模块

1.1 模块致命三问

1.1.1 什么是模块

模块就是一系列功能的集合体
模块分为四种类别:

  • 1、一个py文件就可以是一个模块
  • 2、包:就是一个存放有__init__.py文件的文件夹
  • 3、使用C编写并链接到python解释器的内置模块
  • 4、已被编译为共享库或DLL的C或C++扩展

模块有三种来源

  • 1、python解释器自带的(内置的、标准库)
    1
    2
    3
    4
    import time  # 内置库
    print(time)
    import os # 标准库
    print(os)
  • 2、第三方的库
  • 3、自定义的库

    1.1.2 为何要用模块

  • 1、拿来主义,极大地提升开发效率
  • 2、解决代码冗余问题

    1.1.3 如何用模块

    1.2 import语句

    有如下示范文件#文件名:foo.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    x=1
    def get():
    print(x)
    def change():
    global x
    x=0
    class Foo:
    def func(self):
    print('from the func')
    要想在另外一个py文件中引用foo.py中的功能,需要使用import foo,

首次导入模块会做三件事:

  • 1、执行源文件代码
  • 2、产生一个新的名称空间用于存放源文件执行过程中产生的名字
  • 3、在当前执行文件所在的名称空间中得到一个名字foo,该名字指向新创建的模块名称空间,若要引用模块名称空间中的名字,需要加上该前缀,如下
    1
    2
    3
    4
    5
    import foo #导入模块foo
    a=foo.x #引用模块foo中变量x的值赋值给当前名称空间中的名字a
    foo.get() #调用模块foo的get函数
    foo.change() #调用模块foo中的change函数
    obj=foo.Foo() #使用模块foo的类Foo来实例化,进一步可以执行obj.func()
    加上foo.作为前缀就相当于指名道姓地说明要引用foo名称空间中的名字,所以肯定不会与当前执行文件所在名称空间中的名字相冲突,并且若当前执行文件的名称空间中存在x,执行foo.get()或foo.change()操作的都是源文件中的全局变量x。

    1.3 from import 语句

    from…import…与import语句基本一致,唯一不同的是:使用import foo导入模块后,引用模块中的名字都需要加上foo.作为前缀,而使用from foo import x,get,change,Foo则可以在当前执行文件中直接引用模块foo中的名字,如下
    1
    2
    3
    4
    from foo import x,get,change #将模块foo中的x和get导入到当前名称空间
    a=x #直接使用模块foo中的x赋值给a
    get() #直接执行foo中的get函数
    change() #即便是当前有重名的x,修改的仍然是源文件中的x
    avatar
    无需加前缀的好处是使得我们的代码更加简洁,坏处则是容易与当前名称空间中的名字冲突,如果当前名称空间存在相同的名字,则后定义的名字会覆盖之前定义的名字。

2 一个python文件的两种用途

  • 1、被当做程序运行
  • 2、被当做模块导入
    每个python文件都会内置一个__name__变量#eg: 现在有一个foo.py文件
  • 1、当foo.py被运行时__name__的值为”__main__
  • 2、当foo.py被当做模块导入时,
1
__name__

的值为”foo”

1
2
3
4
5
6
7
#因此我们在文件结尾可以这样写
def xxx():
pass
if __name__ == '__main__':
xxx()
#当py文件被直接运行时,执行xxx()
#当py问价被导入时,则不执行xxx()