上述两部分的例子都是在同一模块(也就是同一个py文件)下进行的,因此不需要导入模块。实际情形下不同的处理函数可能被放置在不同的目录模块下。涉及模块足够多时,通过import语句进行导入会是一种灾难。针对该类问题,python提供了import方法,根据方法参数,动态地导入模块。
1 同一目录下的模块动态导入
示例如下: 考虑如下的场景:根据用户输入的url不同,调用不同的视图函数,渲染不同的web页面。这是web开发中最常见的功能了。 涉及到的目录文件组字结构如下图:
account.py
def login():
print("欢迎进入用户登录页面")
def personal():
print("欢迎进入个人中心页面")
common.py
def home():
print('欢迎进入首页')
goods.py
def display():
print('欢迎进入商品展示页面')
def gooddetail():
print('欢迎进入商品详情页面')
visit.py
def run(inp):
modules, func = inp.split('/')
obj = __import__(modules)
if hasattr(obj, func):
func = getattr(obj, func)
func()
else:
print('url不存在')
if __name__ == '__main__':
run('account/login')
print('这是分界线')
run('goods/gooddetail')
result:
欢迎进入用户登录页面
这是分界线
欢迎进入商品详情页面
这里,我们没有使用import语句来导入模块,用户的输入则被规范为"模块名/方法名"格式的字符串,类似于url。然后将模块名、方法名分离, 使用import来加载模块名, 使用hasattr方法判断加载的模块中有无方法名。在有方法名的前提下使用getattr获取方法
2 不同目录下的模块动态导入
对1中的文件进行目录结构调整如下:
此时visit.py文件的内容如下:
def run(inp):
*modules, func = inp.split("/")
obj = __import__(".".join(modules), fromlist=True)
if hasattr(obj, func):
func = getattr(obj, func)
func()
else:
print("url不存在")
if __name__ == "__main__":
run("user/account/login")
print("这是分界线")
run("product/goods/gooddetail")
result:
欢迎进入用户登录页面
这是分界线
欢迎进入商品详情页面