Python 模块和包

模块有什么用呢?何不把所有的 py 代码都放在一个文件中呢?

大量代码在一个文件中,不易于维护,大量的代码会让人眼花缭乱,我们根据功能不同分为多个文件,那么维护的时候就很方便了。

从另一方面,我们会写一些比较有用的代码,我们将其封装为单独的模块,下次使用此功能的时候就不需要重写编写代码,达到复用的效果,我们的程序也不需要每次都从零开始。

封装为单独的模块,还可以解决命名冲突的问题,不同模块中的名字是可以重复的。但是同一模块中名字是不可以重复的。达到复用名字的效果。

1. 使用模块

Python 中的模块指的是一个包含的各种 Python 对象的程序文件。

1.1 模块使用

我们编写一个模块,命名为 my_module.py,在该模块中我们定义一些函数和类,如下代码所示:

# Person类
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def show_person(self):
        print("Name:%s Age:%d"%(self.name,self.age))

# 函数
def my_add(a,b):
    ret = a + b
    return ret

我们在其他 Python 文件中使用时,首先需要导入这些需要的对象,导入方法如下:

  1. import 模块名
  2. import 模块名 as 别名
  3. from 模块名 import 符号
  4. from 模块名 import 符号 as 别名
  5. from 模块名 import *
# 1. import 模块名
import mymodule
print(mymodule.my_add(10, 20))

# 2. import 模块名 as 别名
import mymodule as mm
print(mm.my_add(10, 20))

# 3. from 模块名 import 符号
from mymodule import Person
person = Person('smith', 18)
person.show_person()

# 3. from 模块名 import 符号 as 别名
from mymodule import Person as P
from mymodule import my_add as ma
p = P('obama', 20)
p.show_person()
print(ma(10, 20))

# 4. from 模块名 import *
from mymodule import *
person = Person('smith', 18)
person.show_person()

1.2 main

如果我们的 my_module 模块内容如下:

def my_addd():
    print('a + b = %d' % (a + b))


# 测试代码,或者其他一些代码
my_add(10, 20)

当 my_module 作为模块被 import 到其他文件中时,上面的 my_add 函数调用就会被自动执行。我们可以进行如下改进来避免此问题:

def my_addd():
    print('a + b = %d' % (a + b))


# 测试代码或者其他一些代码,避免被作为模块导入时被执行
if __name__ == '__main__':
    my_addd(10, 20)

所以,if main 的作用就是避免某个 Python 模块被导入时自动执行一些测试代码。

2. 包

为了更好管理模块,将多个模块放到一个文件夹中,这个文件夹就叫做包,但是此文件夹下必须包含__init__.py 文件,该__init__文件可以为空。__init__文件主要用于标识该目录是一个包。我们接下来构建一个名字叫叫做 package 的 Python 包,目录结构如下:

package
|-- __init__.py
|-- my_module1.py
`-- sub_package
    |-- __init__.py
    `-- my_module2.py

2.1 使用包

# 1. import 模块名
import package.my_module1
import package.sub_package.my_module2

package.my_module1.my_function1()
package.sub_package.my_module2.my_function2()


# 2. import 模块名 as 别名
import package.my_module1 as p
import package.sub_package.my_module2 as sp

p.my_function1()
sp.my_function2()

# 3. from 模块名 import 符号
from package.my_module1 import my_function1
from package.sub_package.my_module2 import my_function2
my_function1()
my_function2()

# 4. from 模块名 import *
from package.my_module1 import *
from package.sub_package.my_module2 import *
my_function1()
my_function2()

2.2 __init__.py 文件的作用

init 文件中一般用来编写一些模块的初始化代码或者其他一些用于简化 import 的代码。这一部分我们通过案例描述。目录结构为:

.
|-- main.py
`-- package
    |-- __init__.py
    |-- my_module1.py
    `-- sub_package
        |-- __init__.py
        |-- my_module2.py

package 中 定义 my_function1 函数,sub_package/my_module2 中定义 my_function2 函数。包的目录结构会导致导入包时编写的路径较长,我们可以使用 init 文件来简化这个步骤。

sub_packgae/init.py 文件内容如下:

from package.sub_package.my_module2 import *

执行效果就是将 my_module2 中的 my_funtion2 提到了 sub_package 空间中,如下图所示:

其中 packgae/init.py 文件内容如下:

from package.my_module1 import *
from package.sub_package import *

这两行代码,将 sub_package 中的 my_function2 和 my_module1 中的 my_function1 提升到了 package 空间中,如下图所示:

当我们在 main 中导包时,就可以直接通过顶层包名来导入某个具体符号,如下代码所示:

# 通过包名直接导入模块中定义的符号
from package import my_function2
from package import my_function1

未经允许不得转载:一亩三分地 » Python 模块和包
评论 (1)

6 + 4 =

  1. avatar
    走着走着就丢了07-07 16:25回复

    讲的很基础,很清晰,踩点,孟老师