Python类、模块、包的区别
类的概念在许多语言中出现,很容易理解。它将数据和操作进行封装,以便将来的复用。
模块
模块,在Python可理解为对应于一个文件。在创建了一个脚本文件后,定义了某些函数和变量。你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量。一般用module_name.fun_name,和module_name.var_name进行使用。这样的语义用法使模块看起来很像类或者名字空间,可将module_name 理解为名字限定符。模块名就是文件名去掉.py后缀。
示例一:简单的class定义
class HelloClass: def __init__(self,name): self._name=name def SayHello(self): print("hello {0}".format(self._name)) S= HelloClass("WORLD!") S.SayHello()
示例二:class的继承
父类:在Day1.py文件中定义FirstTest类
class FirstTest: def __init__(self , name): self._name=name def SayFirst(self): print("Hello {0}".format(self._name)) F = FirstTest("CNBlogs") F.SayFirst()
子类
继承仅需
class Second(FirstTest):
class 子类名(父类名):
from Day1 import FirstTest class Second(FirstTest): def __init__(self,name): FirstTest.__init__(self,name); def Second(self): print("Good -{0}".format(self._name)); r=Second("Jack") r.SayFirst(); r.Second();
运行结果:
模块搜索路径
每个模块都有自己的私有符号表,所有定义在模块里面的函数把它当做全局符号表使用。
模块可以导入其他的模块。通常将import语句放在模块的开头,被导入的模块名字放在导入它的模块的符号表中。
import sys import os print sys.path workpath = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.insert(0, os.path.join(workpath, 'modules')) print sys.path
其他的要点
模块能像包含函数定义一样,可包含一些可执行语句。这些可执行语句通常用来进行模块的初始化工作。这些语句只在模块第一次被导入时被执行。这非常重要,有些人以为这些语句会多次导入多次执行,其实不然。
模块在被导入执行时,python解释器为加快程序的启动速度,会在与模块文件同一目录下生成.pyc文件。我们知道python是解释性的脚本语言,而.pyc是经过编译后的字节码,这一工作会自动完成,而无需程序员手动执行。
包
通常包总是一个目录,可以使用import导入包,或者from + import来导入包中的部分模块。包目录下为首的一个文件便是 __init__.py。然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。
在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,这里就需要运用包的概念了。包对应于文件夹,使用包的方式跟模块也类似,唯一需要注意的是,当文件夹当作包使用时,文件夹需要包含__init__.py文件,主要是为了避免将文件夹名当作普通的字符串。__init__.py的内容可以为空,一般用来进行包的某些初始化工作或者设置__all__值,__all__是在from package-name import *这语句使用的,全部导出定义过的模块。
包是一个有层次的文件目录结构,它定义了由n个模块或n个子包组成的python应用程序执行环境。
通俗一点:包是一个包含__init__.py 文件的目录,该目录下一定得有这个__init__.py文件和其它模块或子包。
常见问题:
-
引入某一特定路径下的模块
- 使用
sys.path.append(yourmodulepath)
- 使用
-
将一个路径加入到python系统路径下,避免每次通过代码指定路径
- 利用系统环境变量
export PYTHONPATH=$PYTHONPATH:yourmodulepath
, - 直接将这个路径链接到类似
/Library/Python/2.7/site-packages
目录下
- 利用系统环境变量
-
好的建议
- 经常使用
if __name__ == '__main__'
,保证你写包既可以import又可以独立运行,用于test。 - 多次import不会多次执行模块,只会执行一次。可以使用
reload
来强制运行模块,但不提倡。
- 经常使用
包(package)
为了组织好模块,将多个模块分为一个包。包是python模块文件所在的目录,且该目录下必须存在__init__.py
文件。常见的包结构如下:
package_a ├── __init__.py ├── module_a1.py └── module_a2.py package_b ├── __init__.py ├── module_b1.py └── module_b2.py main.py
- 如果
main.py
想要引用packagea
中的模块module
a1
,可以使用:
from package_a import module_a1 import package_a.module_a1
- 如果
packagea
中的module
a1
需要引用packageb
,那么默认情况下,python是找不到package
b
。我们可以使用sys.path.append('../')
,可以在packagea
中的__init__.py
添加这句话,然后该包下得所有module都添加*import __init
_
即可。