模块
包与目录
按目录来组织模块的方法,称为包(Package),__init__.py
文件用来区分包和文件。目录的设计要规范化,增加可读性。一个简单的组织目录的例子如下:
1.bin/:存放项目的一些可执行文件,也可以取script/之类的名字。
2.foo/:存放项目的源代码,(1)源代码中所有的模块、包都放在下面,而不是在顶层目录 (2)测试子目录tests/存放测试代码。
3.docs/:存放一些文档。
4.setup.py/:安装、部署、打包的脚本。
5.requirements.txt:需要的第三方库
6.README:项目说明文件
- README需要说明的内容
1.软件的基本功能
2.运行代码的安装环境
3.简要的使用说明
4.代码目录结构详细说明
5.常见问题
模块的测试
在写一个模块时,时常需要对它进行测试,如果单纯地写在模块定义的类或函数下,如下:
# foo.py
def f():
print('Hello!')
f() # 测试
那么在import时,就会出现如下的问题:
# bin.py
import foo
foo.f()
# Hello!
# Hello!
我们的本意是调用foo模块的f()函数,但是在import时执行了foo.py中测试的部分,所以会输出两个Hello!,要解决这个问题,把foo.py做如下修改就可以:
# foo.py
def f():
print('Hello!')
if __name__ == '__main__':
f()
这样既能完成测试,在import的时候又不会调用测试的内容。
为什么是会这样,我们可以吧 __name__
输出看看,修改foo.py:
# foo.py
def f():
print('Hello!')
print(__name__)
if __name__ == '__main__':
f()
在运行foo.py的时候,print(__name__)
会输出 __main__
,而运行bin.py的时候import foo
中的 print(__name__)
会输出 foo
。
BASEDIR
看下面的代码
# logger.py
def logging():
print('logging...')
在bin.py中调用的时候,PyCharm没有问题,在命令行中会出错
# bin.py
from module import logger
logger.logging()
这样的原因是PyCharm帮我们做了一件事情,把sys.path输出我们可以看到:
import sys
print(sys.path)
# ['D:\\Python\\Project\\ATM\\bin', 'D:\\Python\\Project\\ATM', 'D:\\Python\\Python36\\python36.zip', 'D:\\Python\\Python36\\DLLs', 'D:\\Python\\Python36\\lib', 'D:\\Python\\Python36', 'D:\\Python\\Python36\\lib\\site-packages', 'D:\\Python\\PyCharm\\helpers\\pycharm_matplotlib_backend']
这个路径 'D:\\Python\\Project\\ATM'
,是PyCharm放进去的,所以bin.py能找到module这个模块,而在命令行中没有这个路径,所以自然找不到module模块。
要解决这个问题,可以手动添加这个路径,先用os.path.abspath(__file__)
把__file__
由相对路径转为绝对路径,再调用两次os.path.dirname()
方法,找到上面两层的路径,最后添加到path。修改bin.py如下:
# bin.py
import sys
import os
BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASEDIR)
from module import logger
logger.logging()
这样在命令行下也不会出错。