Skip to content

Latest commit

 

History

History
177 lines (136 loc) · 5.37 KB

19-模块和包.md

File metadata and controls

177 lines (136 loc) · 5.37 KB

模块和包

感谢大家一个月以来的支持,这是聪哥python基础教程的最后一篇。聪哥想把这个公众号办下去,后续的更新内容还没有确定,聪哥初步意向是更新一些python编程的小技巧,如果各位还有自己的想法,可以在微信公众号后台留言。

模块是预定义的变量、函数和类的集合。当我们引入模块的时候,就可以直接使用这些变量、函数和类。这样就避免了重复定义,大大提高了代码的复用性。

import语句

假设在文件student.py中有以下代码:

NUMBER = 30
def show():
    print(NUMBER)
class Student():
    def __init__(self, name, gender, chinese, math, english):
        self.name = name
        self.gender = gender
        self.chinese = chinese
        self.math = math
        self.english = english
    def average(self):
        return (self.chinese + self.math + self.english)/3

为了使用模块中的对象,我们需要使用import语句来引入它们。假设student.py就在命令行的工作目录下,则有三种import方式,不同的引用方式对应了对象的不同的使用方式。第一种是引入模块名,借助模块名可以访问模块中所有的对象。

# 引入模块名
>>> import student
# 使用模块中的变量必须要加上模块的名称
>>> student.NUMBER
30
>>> student.show()
20
>>> jack = student.Student('Jack', 'male', 88, 85, 94)
>>> student.Student.average(jack)
89.0

第二种是引入模块中所有对象。

# 引入student模块中所有的对象
# 可以直接使用student中的所有对象
>>> from student import *
>>> NUMBER
30
>>> jack = Student('Jack', 'male', 88, 85, 94)
>>> Student.average(jack)
89.0

第三种是从student模块中引入指定的对象。

>>> from student import Student
# 因为没有引入变量NUMBER,因此提示变量没有定义
>>> NUMBER
NameError: name 'NUMBER' is not defined
# 引入了Student类,就可以直接使用
>>> jack = Student('Jack', 'male', 88, 85, 94)
>>> Student.average(jack)
89.0

这三种方法中,第一种指明了模块名称,在使用模块中的对象时,清楚地知道对象的来源,但是每一次使用都要加上模块名称,相对比较麻烦。第二种引入了模块中所有的对象,然而我们并不一定使用这个对象,由于python的对象名不能重复,这种方法实际上会造成对象名的污染,因而不推荐使用。第三种方法只引入了将要使用的对象,既可以方便使用,也不会造成对象名的污染,因此推荐使用第三种方法。

__name__属性

每一个模块都有__name__属性,当且仅当__name__属性的值是__main__时,表示模块不是被引用,而是自身在运行。

# filename: student.py
class Student():
    def __init__(self, name, gender, chinese, math, english):
        self.name = name
        self.gender = gender
        self.chinese = chinese
        self.math = math
        self.english = english
    def average(self):
        return (self.chinese + self.math + self.english)/3

if __name__ == '__main__':
    jack = Student('Jack', 'male', 88, 85, 94)
	Student.average(jack)

对于上面的文件student.py,主动运行就在命令行中输入命令python student.py,而被引用没有使用这个命令,而使用了import语句。

# 模块自身被运行,__name__属性的值是'__main__'
> python student.py
89.0
# 模块被引用,__name__属性的值不是'__main__',不会自动计算jack同学平均分
> python
>>> from student import Student
>>> jack = Student('Jack', 'male', 88, 85, 94)
>>> Student.average(jack)
89.0

dir()方法

通过dir()方法,我们可以查看模块中所有的对象和属性。

# 用dir()方法查看模块student的对象和属性
>>> import student
>>> dir(student)
['Student', '__builtins__', '__cached__', '__doc__', '__file__', 
 '__loader__', '__name__', '__package__', '__spec__']
# 模块名加属性名就能得到属性值
>>> student.Student
<class 'student.Student'>
>>> student.__name__
'student'

包是模块的集合,它是一个目录,里面有一些文件。用pip命令安装的包都在python根目录下的lib目录中。

下面以xml包为例,简单介绍一下包的构成:

xml/
		__init__.py
		sax/
				__init__.py
				_excetpions.py
				expatreader.py
				handler.py
				saxutils.py
				xmlreader.py
		dom/
				__init__.py
				domreg.py
				...
		etree/
				__init__.py
				cElemtentTree.py
				...
		parser.py

__init__.py中是当前目录下所有文件的一些初始化信息,该文件内容空白也没事,但是目录下一定要有,否则python就不认为这个目录是一个包。

除了__init__.py以外的其它文件,都是各种功能模块。

一个包中可以有多个子目录,比如xml包中就有sax/, dom/等子目录。

从包中引入模块要注意目录,子目录下的文件,在引用时要注意加上子目录名,目录和子目录之间用点隔开。

# 引入parse模块
from xml import parse.py
# 引入handler模块
from xml.sax import handler

总结

  1. 使用import语句,从模块中引入对象
  2. 当文件主动运行时,__name__属性的值是__main__
  3. 使用dir()方法,查看模块中的所有属性和对象
  4. 包是实现某种功能的一些模块的集合