目录
概念
我们可以把类放在文件中形成一个模块
但是如果我们想 一个文件中只放入一个单独的类,这样的话
原先的模块中的类就要分出去,但是他们之间的访问如何处理呢?
Java中的包映射到物理磁盘就是目录结构,但是访问上却有限制。
Python中的包使用与操作系统类似的目录,使得同一目录下的文件在一起使用时候就像单独的模块
这个和Java的控制是很类似的,同一个包下可以访问
创建包
1.先创建一个目录,文件夹的名字就是包的名字
2.在这个目录下面创建一个 __init__.py文件 (空文件即可)
注意了这个文件的名称和类中初始化方法 __init__的方法名是一样的
这个文件提示python这是个包目录,不是一个仅包含文件的目录
3.__init__文件包含了控制包的用法代码
当导入包的时候,目录中的每个文件并没有立即导入,相反,__init__.py文件首先被计算,它指定了要使用的文件以及使用它们 的方式
4.将我们要放在包下面的类做成 [类名].py 文件放入到这个包目录下面
5.编辑 __init__.py 文件
如果我们想在导入包之后使用这些类,那么就必须在
__init__.py文件中放入我们想要导入的东西这个和导入模块的形式是一样的
在该文件中我们可以使用 from 类名 import 需要的属性
6.导入包 比如 import 包名
7.使用 包名.注册的属性 就可以访问了
小结:
到这里你应该可以看出这个包的意图了吧
包就如同一个中间的 约束空间
我们先将要导入的东西放入到 __init__.py中
这样相当于给这个中间约束空间注册了东西
然后再外部我们使用 包名.属性 进行访问,就相当屏蔽了底层的 类的信息了
同时这样做也可以防范 名字冲突的问题,使用包进行这个限制
__init__.py文件
该文件是包被导入的时候使用的
我们可以在里面注册这个要导出的属性
当然,它本身也是一个py文件,因此可以和其他普通的py文件一样写东西
例如我们看看python安装目录下的Lib下的包 collections 包
实践
先建立一个文件夹MyPack
里面建立一个 __init__.py文件用于包信息登记
然后包的下面我们建立两个模块文件classInfo.py , study.py
sudy.py中的模块将会使用 classInfo.py文件中的模块
下面是 MyPack 目录下面的内容
然后我们在dos下导入该包
我们的包的物理路径是 D:\Apl\python_work\basic
包下面的文件的物理路径是 D:\Apl\python_work\basic\MyPack
现在我们从 D:\Apl\python_work\basic 打开dos进入python交互环境
第一次导入的时候发现会有错误的,记住上节说的模块的搜寻
之所以会有错误,是因为搜寻包的时候不会进入到该包的子目录下面进行模块的搜索的
所以要解决这个问题,需要将模块的文件路径加入到 sys.path中
然后我们重新导入一次,成功导入
查看该包下面的属性,发现是有我们的两个模块的
现在我们想使用这个两个模块进行类对象的创建
注意这个 类的访问: 包名.模块名.类名
包名.模块名.类名 来进行对象的创建
可以看见这种 import 模块名 导入的方式只是将模块的东西加载进来
如果需要访问需要 用模块.对象的方式进行访问
这样就体现了 from 模块 导入 对象 这种方式的优点
代码片段:
classInfo.py
class ClassInfo:
def __init__(self,name):
self.name = name
def getClassName(self):
return self.name
study.py
class Study:
def __init__(self,name,no):
self.name=name
self.no = no
self.classList=[]
def getName(self):
return self.name
def setName(self,name):
self.name=name
def setNo(self,no):
self.no=no
def getNo(self,no):
return self.no
def choose(self,classInfo):
self.classList.append(classInfo)
def display(self):
print('No:%s,name : %s chooseInfo %s' % (self.no,self.name,self.classList))
__init__.py
import classInfo
import study