python模块以及包管理

一、模块的导入方式

1、 import方式导入(绝对导入):在后续代码中调用此模块中的类,函数,属性等都是通过:模块名.函数名、模块名.类名、模块名.属性名的方式调用。

import datetime
import time

print("import方式导入:")
print(datetime.datetime.now())
print(time.time())

结果:

import方式导入:
2019-07-09 09:22:58.838245
1562635378.8382452

2、 form...import 方式导入(相对导入):在后续代码中调用此模块中的类,函数,属性等都是通过直接写类名,函数名,属性名。

from datetime import datetime
from time import *

print("form...import方式导入:")
print(datetime.now())
print(time())

结果:

form...import方式导入:
2019-07-09 09:23:23.161034
1562635403.1610339

二、模块的调用

从上例可以知道,在python中能直接调用系统模块,同理,也可以调用自己创建的模块,尤其在自动化测试中,调用执行测试用例时,用得比较多,一般分为同级目录调用和跨目录模块调用。

1、同级目录模块调用

在test_case目录下,创建了test_a.py以及test_b.py文件,它两是同一目录下的文件。


test_a.py文件:

print('this is test_a')

test_b.py文件:

import test_a

print('this is test_b')

执行test_b.py能正常执行

this is test_a
this is test_b

2、跨目录模块调用

在test_case目录下,创建了test_aaa文件夹,并在其下创建了test_a.py以及test_ccc文件夹,在test_ccc文件下创建了test_c.py文件,现在test_a.py和test_c.py它两是不在同一目录下。

test_a.py文件:

import test_c

print('this is test_a')

test_c.py文件:

print('this is test_c')

执行test_a.py文件时,提示错误:不能找到模块

import test_c
ModuleNotFoundError: No module named 'test_c'

在之前同一级目录下,都能运行,不同目录下就出现问题了。这是为什么呢?要理解它,需要知道执行import语句时,到底发生了什么?总结如下:

  • 第一步,创建一个新的module对象;
  • 第二步,把这个module对象插入到sys.module中;
  • 第三步,找到module程序所在位置,转载module的代码。这里需要注意的是程序查找的顺序方法,首先,是找当前路径(以及当前目录指定的sys.path),然后是PythonPATH,再然后是python的安装路径。如果当前路径存在或PythonPATH中存在与标准module同样名称的模块时,则会执行当前路径存在或PythonPATH中存在的模块,所以在给文件名取名称时需要注意;
  • 第四步,执行新的module中对应的代码。

了解原理后,就明白了,在引入在不同目录下的模块时,import不能找到执行的模块,那么需要指定相应的路径才能找到并执行。如下:

import sys
sys.path.append(r'E:\python\unittest_test\test_case\test_aaa\test_ccc')
import test_c

print('this is test_a')

结果:已经能找到并执行程序

this is test_c
this is test_a

三、包管理

包的定义:一个包(package)就是放在一个文件夹里的模块集合。包的名字就是文件夹的名字。

现在考虑实际工作中的使用场景,在执行测试用例时,众多的测试用例可能分布在不同目录层级下的文件中,也就是包中国。此时,需要用到python中的dicover函数,它会自动查找到我们想要的测试用例脚本文件,而不用我们手动去加入每个测试用例脚本文件名称。比如:

if __name__ == '__main__':
    #构造测试集
    suite = unittest.TestSuite()
    suite.addTest('test_a')#手动加入每个测试用例脚本文件名称
    suite.addTest('test_b')#手动加入每个测试用例脚本文件名称
    suite.addTest('test_c')#手动加入每个测试用例脚本文件名称
    #执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)

当测试用例成百上千时,手动的效率可想而知是如何低下,于是轮到dicover函数出场:

import unittest
unittest.defaultTestLoader.discover(start_dir=,pattern='test*.py',top_level_dir=None)

discover(start_dir=,pattern='test*.py',top_level_dir=None)

  • start_dir:要测试的模块名或者测试用例目录;
  • pattern:表示用例文件名的匹配原则。比如:pattern='test.py',这里匹配的是test开头的.py类型的文件,星号“”表示任意多个字符;
  • top_level_dir:测试模块的顶层目录。如果没有,默认为None。

现在用dicover函数方法去查找不同目录下的测试用例脚本文件,比如:执行test_one.py文件,找到并执行test_a.py、test_b.py和test_c.py文件。

执行test_one.py文件:

import unittest

test_dir = r'E:\python\unittest_test\test_case'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(discover)

结果:没有找到,也没有执行任何的测试用例

----------------------------------------------------------------------
Ran 0 tests in 0.000s

OK

这是为什么?因为我们在执行程序的时候要告诉python,我们的测试用例放在哪些包中,那怎么告诉python呢?其实很简单,也就是把一个名为__ init__.py的文件(通常是文件内容为空)放在文件夹中。比如:

现在我们再次执行test_one.py文件,看能否找到并执行test_a.py、test_b.py和test_c.py文件。

import unittest

test_dir = r'E:\python\unittest_test\test_case'
discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(discover)

结果:已经能成功找到!

this is test_a
this is test_c
this is test_b

这里需要注意,unittest框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:09,AZ,a~z。所以你会看到以上的执行结果,因为它查找到的文件夹名称的顺序是先test_aaa,然后是test_bbb。所以先执行test_a.py,再test_c.py,最后test_b.py。

四、使用模块或者引入模块的时候需要注意哪些?

1、使用模块的时候需要注意:

模块名要遵循python的命名规范,也就是尽量使用小写命名,首字母保持小写,尽量不要用下划线(除非多个单词,且数量不多的情况),
不要使用中文或者特殊字符。

模块名不要和系统模块名冲突,最好先检查系统是否已经存在该模块,检查的方法是在python的交互环境中执行import XXX,
若成功,则说明存在此模块。可以通过import导入数据,另外,需要注意变量的作用域。

自己创建模块名称时,要注意命名,不能和python自带的模块名称冲突。

2、引入模块的时候需要注意:

import导入几个模块时,要用逗号进行分开。

模块名字太长可以取别名,比如:import XX as xx等

from import,是从模块名引入方法名

你可能感兴趣的:(python模块以及包管理)