动态地改变Python搜索路径
感谢:Robin Parmar
任务
模块必须处于Python搜索路径中才能被导入,但你不想设置个永久性的大路径,因为那样可能会影响性能,所以,你希望能够动态地改变这个路径。
解决方案
只需简单地在Python的sys.path中加入一个"目录",不过要小心重复的情况:
1. def AddSysPath(new_path):
2. """ AddSysPath(new_path):给Python的sys.path增加一个"目录"
3. 如果此目录不存在或者已经在sys.path中了,则不操作
4. 返回1表示成功,-1表示new_path不存在,0表示已经在sys.path中了
5. already on sys.path.
6. """
7. import sys, os
8. # 避免加入一个不存在的目录
9. if not os.path.exists(new_path): return -1
10. # 将路径标准化。 Windows是大小写不敏感的,所以若确定在
11. # Windows下,将其转成小写
12. new_path = os.path.abspath(new_path)
13. sys.platform
14. new_pathnew_path
15. # 检查当前所有的路径
16. for x in sys.path:
17. x = os.path.abspath(x)
18. sys.platform
19. xx
20. if new_path in (x, x + os.sep):
21. return 0
22. sys.path.append(new_path)
23. # 如果想让new_path在sys.path处于最前
24. # 使用:sys.path.insert(0, new_path)
25. return 1
26. if _ _name_ _
27. # 测试,显示用法
28. import sys
29. print 'Before:'
30. for x in sys.path: print x
31. sys.platform
32. print AddSysPath('c:\\Temp')
33. print AddSysPath('c:\\temp')
34. else:
35. print AddSysPath('/usr/lib/my_modules')
36. print 'After:'
37. for x in sys.path: print x
讨论
模块要处于Python搜索路径中的目录里才能被导入,但我们不喜欢维护一个永久性的大目录,因为其他所有的Python脚本和应用程序导入模块的时候性能都会被拖累。本节代码动态地在该路径中添加了一个"目录",当然前提是此目录存在而且此前不在sys.path中。
sys.path是个列表,所以在末尾添加目录是很容易的,用sys.path.append就行了。当这个append执行完之后,新目录即时起效,以后的每次import操作都可能会检查这个目录。如同解决方案所示,可以选择用sys.path.insert(0,…,这样新添加的目录会优先于其他目录被import检查。
即使sys.path中存在重复,或者一个不存在的目录被不小心添加进来,也没什么大不了,Python的import语句非常聪明,它会自己应付这类问题。但是,如果每次import时都发生这种错误(比如,重复的不成功搜索,操作系统提示的需要进一步处理的错误),我们会被迫付出一点小小的性能代价。为了避免这种无谓的开销,本节代码在向sys.path添加内容时非常谨慎,绝不加入不存在的目录或者重复的目录。程序向sys.path添加的目录只会在此程序的生命周期之内有效,其他所有的对sys.path的动态操作也是如此。
本文出自:http://book.51cto.com/art/201005/198555.htm