27 python反射机制( 二 )

删除指定对象中的指定方法,特别提示:只是在本次运行程序的内存中将该方法删除,并没有影响到文件的内容
__import__模块反射接着上面网站的例子,现在一个后台文件已经不能满足我的需求,这个时候需要根据职能划分后台文件,现在我又新增了一个??user.py这个用户类的文件,也需要导入到首页以备调用 。
但是,上面网站的例子,我已经写死了只能指定commons模块的方法任意调用,现在新增了user模块,那此时我又要使用if判断?答:不用,使用Python自带的函数__import__
由于模块的导入也需要使用Python反射的特性,所以模块名也要加入到url中,所以现在url请求变成了类似于??commons/visit??的形式
# user.pydef add_user():print('添加用户')def del_user():print('删除用户')# commons.pydef login():print("这是一个登陆页面!")def logout():print("这是一个退出页面!")def home():print("这是网站主页面!")# visit.pydef run():inp = input("请输入您想访问页面的url:").strip()# modules代表导入的模块,func代表导入模块里面的方法modules, func = inp.split('/')obj_module = __import__(modules)if hasattr(obj_module, func):getattr(obj_module, func)()else:print("404")if __name__ == '__main__':run()最后执行run函数,结果如下:
请输入您想访问页面的url:user/add_user添加用户请输入您想访问页面的url:user/del_user删除用户现在我们就能体会到__import__的作用了,就是把字符串当做模块去导入 。
但是如果我的网站结构变成下面的
|- visit.py|- commons.py|- user.py|- lib|- __init__.py|- connectdb.py现在我想在??visit???页面中调用??lib???包下??connectdb??模块中的方法,还是用之前的方式调用可以吗?
# connectdb.pydef conn():print("已连接mysql")# visit.pydef run():inp = input("请输入您想访问页面的url:").strip()# modules代表导入的模块,func代表导入模块里面的方法modules, func = inp.split('/')obj_module = __import__('lib.' + modules)if hasattr(obj_module, func):getattr(obj_module, func)()else:print("404")if __name__ == '__main__':run()运行run命令,结果如下:
请输入您想访问页面的url:connectdb/conn404结果显示找不到,为了测试调用lib下的模块,我抛弃了对所有同级目录模块的支持,所以我们需要查看__import__源码
def __import__(name, globals=None, locals=None, fromlist=(), level=0): # real signature unknown; restored from __doc__"""__import__(name, globals=None, locals=None, fromlist=(), level=0) -> moduleImport a module. Because this function is meant for use by the Pythoninterpreter and not for general use, it is better to useimportlib.import_module() to programmatically import a module.The globals argument is only used to determine the context;they are not modified.The locals argument is unused.The fromlistshould be a list of names to emulate ``from name import ...'', or anempty list to emulate ``import name''.When importing a module from a package, note that __import__('A.B', ...)returns package A when fromlist is empty, but its submodule B whenfromlist is not empty.The level argument is used to determine whether toperform absolute or relative imports: 0 is absolute, while a positive numberis the number of parent directories to search relative to the current module."""pass??__import__???函数中有一个??fromlist??参数,源码解释说,如果在一个包中导入一个模块,这个参数如果为空,则return这个包对象,如果这个参数不为空,则返回包下面指定的模块对象,所以我们上面是返回了包对象,所以会返回404的结果,现在修改如下:

经验总结扩展阅读