【python】 解:import导包机制
模块和包
包:存放模块的文件夹,含有init.py文件,定义path属性。
import语句的作用
import语句用于导入其他 python 文件(模块或包),使用该模块定义的类、方法或变量,从而达到代码复用的目的。
导包的两种方式
import 包名/模块名
from 包名/模块名 import 任意变量
import 导入模块时,默认执行了这个模块的代码,若重复多次导入,则只会执行一次。因为第一次导入后,就将模块名加载到内存,存储在sys.modules字典中,后面重复导入只是在加载内存中模块对象的引用,而不会重新执行模块内的语句。
import导包的机制
1:执行import时,会先从sys.modules中查询是否被导入;
2:若已经导入,则直接引用,若没有导入,则依据sys.path按照列表顺序依次到每个目录下去匹配导入的模块;
3:若找到这个模块,则会创建这个模块的命名空间,并将模块中的名字存储到命名空间中。
模块导包顺序
内置标准模块,help('modules')查看;
第三方开源模块,扩展的,通过pip install联网安装的;
自定义模块。
导包示例
1 -- my_proj 2 -- common 3 -- handle_excel.py 4 -- handle_conf.py 5 -- handle_db.py 6 -- test 7 -- test_login.py 8 -- test_register.py 9 -- run.py
同级目录调用:
1 在test_login 中调用 test_register: 2 import test_register 3 from test_register import * 4 from test.test_register import * 5 import sys 6 print(sys.path) 7 ['C:\\Users\\jo\\Desktop\\api\\test', 'C:\\Users\\jo\\Desktop\\api',, ……]
调用兄弟目录的子目录:
1 在test_login 中调用 handle_excel: 2 from common import handle_excel 3 from common.handle_excel import *
as别名的妙用
了解过的同学都知道,as是给模块重命名,即起一个别名,那么什么情况用as,什么情况不需要,应用场景有哪些呢?
场景一:当模块名过长,引用时影响观感,为了提升代码的可读性,我们可以用as进行重命名,例如我们在做UI自动化,需要等待某个条件被触发,需要导入expected_conditions模块使用触发条件的方法,每次用expected_conditions调用方法太长,但起个别名,如EC调用就简洁许多,这时我们可以这样写:
1 from selenium.webdriver.support import expected_conditions as EC
场景二:当导入不同的模块,但完成的是相同的功能,我们也可以用as别名来进行统一操作,不用写两套一样的代码,如在接口自动化我们在进行数据库验证时,不同公司使用数据库不相同,有些mysql,有些orcle,但是操作步骤均一致,若不设置别名,我们需要写两套代码,设置别名后,我们可以兼容不同的数据库,实现方式如下:
tip:重命名后,只支持用重命名变量名去调用,不支持用原模块去调用。
1 class Handle_Mysql: 2 3 def __init__(self, connect_type='mysql'): 4 if connect_type == 'mysql': 5 import pymysql as db 6 from pymysql.cursors import Cursor as Cur 7 self.conn = db.Connection( 8 host='', 9 uesr='', 10 password='', 11 database='', 12 port='', 13 charset='utf-8' 14 ) 15 elif connect_type == 'orcle': 16 import cx_Oracle as db 17 from cx_Oracle.Cursor import Cursor as Cur 18 self.conn = db.connect('username','password','host/orcl') 19 self.cur = Cur(self.conn) 20 21 def get_all(self, sql): 22 """用于返回所有数据,执行sql前后需提交事务,以防数据冲突""" 23 self.conn.commit() 24 # 执行sql加入异常判断,sql执行失败就回滚 25 try: 26 self.cur.execute(sql) 27 except Exception as e: 28 self.conn.rollback() 29 return 'sql执行错误:{}'.format(e) 30 self.conn.commit() 31 return self.cur.fetchall() 32 33 def close(self): 34 self.cur.close() 35 self.conn.close()