python模块搜索路径
① 解决python开发中模块冲突的具体方法
假如有两个同名的模块,那么只能导入它们中的一个——默认情况下,Python总是会选择在模块搜索路径sys.path中最左边的那一项。如果你偏爱的模块和顶层脚本在同一目录下,那就不成问题;由于顶层脚本的主目录总是模块搜索路径中的第一项,因此它的内容总是会首先被自动定位。然而对于跨目录的导入,模块搜索路径的线性本质意味着同名的文件会产生冲突。
要修复这一冲突,要么避免同名文件。如果你需要同时访问两个同名的文件,那么就要把两个源文件分族陵饥别放入子目录中,这样包导入目录名称将使得模块引用唯一。只要外围的包目录名称是唯一的,你就能访问兆返同名模块中的任意一个,或是全部的两个。注意,如果你不小心为自己的模块使用了一个名称,而它碰巧和你需要使用的标准库模块的名称相同,那么也汪拿会出现这一问题。这是因为程序主目录(或是模块路径中靠前的另一个目录)下的本地模块会隐藏和替换标准库模块。要修复这种覆盖,要么避免使用和你需要的另一模块相同的名称,要么把模块放到一个包目录下然后使用Python 3.X的包相对导入模型(包相对导入在2.X版本中是一个可选的功能)。在包相对导入模型下,普通导入会跳过包目录,因此你可以获取标准库版本,但在必要时特殊的点号开头导入语句仍然可以选取同名模块的本地版本。
② 如何设置python模块的默认搜索路径
Python的模块搜索路径PYTHONPATH类似Java的CLASSPATHx0dx0a由以下路径组合而成,通过更改以下4者其中之一都可以改变Python模块的默认搜索路径:x0dx0a1.当前工作目录x0dx0a2.操作系统的PYTHONPATH环境变量x0dx0a3.Python安装目录lib/site-packages中或PYTHONPATH中的.pth文件定义的路径x0dx0a如:find~/my_lib-typed-print>~/python2.6/site-packages/my_lib.pthx0dx0a4.运行时对sys.path的改变,如:x0dx0ax0dx0a向后增加:x0dx0asys.path.append(path)x0dx0apath不要以/或\结尾。x0dx0a向前增加:x0dx0asys.path.insert(0,path)
③ python 基础教程
运算
a = 21
b = 10
c = 0
c = a + b
print "1 - c 的值为:", c
c = a - b
print "2 - c 的值为:", c
c = a * b
print "3 - c 的值为:", c
c = a / b
print "4 - c 的值为:", c
c = a % b
print "5 - c 的值为:", c
a = 2
b = 3
c = a**b
print "6 - c 的值为:", c
a = 10
b = 5
c = a//b
print "7 - c 的值为:", c
python比较
a = 21
b = 10
c = 0
if ( a == b ):
print "1 - a 等于 b"
else:
print "1 - a 不等于 b"
if ( a != b ):
print "2 - a 不等于 b"
else:
print "2 - a 等于 b"
if ( a <> b ):
print "3 - a 不等于 b"
else:
print "3 - a 等于 b"
if ( a < b ):
print "4 - a 小于 b"
else:
print "4 - a 大于等于 b"
if ( a > b ):
print "5 - a 大于 b"
else:
print "5 - a 小于等于 b"
a = 5
b = 20
if ( a <= b ):
print "6 - a 小于等于 b"
else:
print "6 - a 大于 b"
if ( b >= a ):
print "7 - b 大于等于 a"
else:
print "7 - b 小于 a"
赋值
a = 21
b = 10
c = 0
c = a + b
print "1 - c 的值为:", c
c += a
print "2 - c 的值为:", c
c *= a
print "3 - c 的值为:", c
c /= a
print "4 - c 的值为:", c
c = 2
c %= a
print "5 - c 的值为:", c
c **= a
print "6 - c 的值为:", c
c //= a
print "7 - c 的值为:", c
逻辑运算符:
a = 10
b = 20
if ( a and b ):
print "1 - 变量 a 和 b 都为 true"
else:
print "1 - 变量 a 和 b 有一个不为 true"
if ( a or b ):
print "2 - 变量 a 和 b 都为 true,或其中一个变量为 true"
else:
print "2 - 变量 a 和 b 都不为 true"
a = 0
if ( a and b ):
print "3 - 变量 a 和 b 都为 true"
else:
print "3 - 变量 a 和 b 有一个不为 true"
if ( a or b ):
print "4 - 变量 a 和 b 都为 true,或其中一个变量为 true"
else:
print "4 - 变量 a 和 b 都不为 true"
if not( a and b ):
print "5 - 变量 a 和 b 都为 false,或其中一个变量为 false"
else:
print "5 - 变量 a 和 b 都为 true"
in,not in
a = 10
b = 20
list = [1, 2, 3, 4, 5 ];
if ( a in list ):
print "1 - 变量 a 在给定的列表中 list 中"
else:
print "1 - 变量 a 不在给定的列表中 list 中"
if ( b not in list ):
print "2 - 变量 b 不在给定的列表中 list 中"
else:
print "2 - 变量 b 在给定的列表中 list 中"
a = 2
if ( a in list ):
print "3 - 变量 a 在给定的列表中 list 中"
else:
print "3 - 变量 a 不在给定的列表中 list 中"
条件
flag = False
name = 'luren'
if name == 'python': # 判断变量否为'python'
flag = True # 条件成立时设置标志为真
print 'welcome boss' # 并输出欢迎信息
else:
print name
num = 5
if num == 3: # 判断num的值
print 'boss'
elif num == 2:
print 'user'
elif num == 1:
print 'worker'
elif num < 0: # 值小于零时输出
print 'error'
else:
print 'roadman' # 条件均不成立时输出
循环语句:
count = 0
while (count < 9):
print 'The count is:', count
count = count + 1
print "Good bye!"
i = 1
while i < 10:
i += 1
if i%2 > 0: # 非双数时跳过输出
continue
print i # 输出双数2、4、6、8、10
i = 1
while 1: # 循环条件为1必定成立
print i # 输出1~10
i += 1
if i > 10: # 当i大于10时跳出循环
break
for letter in 'Python': # 第一个实例
print '当前字母 :', letter
fruits = ['banana', 'apple', 'mango']
for fruit in fruits: # 第二个实例
print '当前水果 :', fruit
print "Good bye!"
获取用户输入:raw_input
var = 1
while var == 1 : # 该条件永远为true,循环将无限执行下去
num = raw_input("Enter a number :")
print "You entered: ", num
print "Good bye!"
range,len
fruits = ['banana', 'apple', 'mango']
for index in range(len(fruits)):
print '当前水果 :', fruits[index]
print "Good bye!"
python数学函数:
abs,cell,cmp,exp,fabs,floor,log,log10,max,min,mod,pow,round,sqrt
randrange
访问字符串的值
var1 = 'Hello World!'
var2 = "Python Runoob"
print "var1[0]: ", var1[0]
print "var2[1:5]: ", var2[1:5]
转义字符
格式化输出
print "My name is %s and weight is %d kg!" % ('Zara', 21)
字符串函数:
添加元素
list = [] ## 空列表
list.append('Google') ## 使用 append() 添加元素
list.append('Runoob')
print list
删除元素
list1 = ['physics', 'chemistry', 1997, 2000]
print list1
del list1[2]
print "After deleting value at index 2 : "
print list1
列表操作
列表方法
删除字典
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};
del dict['Name']; # 删除键是'Name'的条目
dict.clear(); # 清空词典所有条目
del dict ; # 删除词典
print "dict['Age']: ", dict['Age'];
print "dict['School']: ", dict['School'];
字典的函数:
当前时间戳:
import time
time.time()
格式化日期输出
import time
print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
a = "Sat Mar 28 22:24:24 2016"
print time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y"))
获取某个月日历:calendar
import calendar
cal = calendar.month(2016, 1)
print "以下输出2016年1月份的日历:"
print cal
当前日期和时间
import datetime
i = datetime.datetime.now()
print ("当前的日期和时间是 %s" % i)
print ("ISO格式的日期和时间是 %s" % i.isoformat() )
print ("当前的年份是 %s" %i.year)
print ("当前的月份是 %s" %i.month)
print ("当前的日期是 %s" %i.day)
print ("dd/mm/yyyy 格式是 %s/%s/%s" % (i.day, i.month, i.year) )
print ("当前小时是 %s" %i.hour)
print ("当前分钟是 %s" %i.minute)
print ("当前秒是 %s" %i.second)
不定长参数:*
lambda:匿名函数
def....
python模块搜索路径
获取用户输入
str = raw_input("请输入:")
print "你输入的内容是: ", str
input可以接收表达式
open参数
write要自己添加换行符
读取10个字符
重命名:os.rename
os.remove
os.mkdir os.chdir
os.getcwd
os.rmdir
open参数
file的方法
异常:
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
print "Error: 没有找到文件或读取文件失败"
else:
print "内容写入文件成功"
fh.close()
try:
fh = open("testfile", "w")
fh.write("这是一个测试文件,用于测试异常!!")
finally:
print "Error: 没有找到文件或读取文件失败"
用户自定义异常:
os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:
| 序号 | 方法及描述 |
| 1 |
os.access(path, mode)
检验权限模式 |
| 2 |
os.chdir(path)
改变当前工作目录 |
| 3 |
os.chflags(path, flags)
设置路径的标记为数字标记。 |
| 4 |
os.chmod(path, mode)
更改权限 |
| 5 |
os.chown(path, uid, gid)
更改文件所有者 |
| 6 |
os.chroot(path)
改变当前进程的根目录 |
| 7 |
os.close(fd)
关闭文件描述符 fd |
| 8 |
os.closerange(fd_low, fd_high)
关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 |
| 9 |
os.p(fd)
复制文件描述符 fd |
| 10 |
os.p2(fd, fd2)
将一个文件描述符 fd 复制到另一个 fd2 |
| 11 |
os.fchdir(fd)
通过文件描述符改变当前工作目录 |
| 12 |
os.fchmod(fd, mode)
改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 |
| 13 |
os.fchown(fd, uid, gid)
修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 |
| 14 |
os.fdatasync(fd)
强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 |
| 15 |
os.fdopen(fd[, mode[, bufsize]])
通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
| 16 |
os.fpathconf(fd, name)
返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 |
| 17 |
os.fstat(fd)
返回文件描述符fd的状态,像stat()。 |
| 18 |
os.fstatvfs(fd)
返回包含文件描述符fd的文件的文件系统的信息,像 statvfs() |
| 19 |
os.fsync(fd)
强制将文件描述符为fd的文件写入硬盘。 |
| 20 |
os.ftruncate(fd, length)
裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 |
| 21 |
os.getcwd()
返回当前工作目录 |
| 22 |
os.getcw()
返回一个当前工作目录的Unicode对象 |
| 23 |
os.isatty(fd)
如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 |
| 24 |
os.lchflags(path, flags)
设置路径的标记为数字标记,类似 chflags(),但是没有软链接 |
| 25 |
os.lchmod(path, mode)
修改连接文件权限 |
| 26 |
os.lchown(path, uid, gid)
更改文件所有者,类似 chown,但是不追踪链接。 |
| 27 |
os.link(src, dst)
创建硬链接,名为参数 dst,指向参数 src |
| 28 |
os.listdir(path)
返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
| 29 |
os.lseek(fd, pos, how)
设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 |
| 30 |
os.lstat(path)
像stat(),但是没有软链接 |
| 31 |
os.major(device)
从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 |
| 32 |
os.makedev(major, minor)
以major和minor设备号组成一个原始设备号 |
| 33 |
os.makedirs(path[, mode])
递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 |
| 34 |
os.minor(device)
从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 |
| 35 |
os.mkdir(path[, mode])
以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 |
| 36 |
os.mkfifo(path[, mode])
创建命名管道,mode 为数字,默认为 0666 (八进制) |
| 37 |
os.mknod(filename[, mode=0600, device])
创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。
|
| 38 |
os.open(file, flags[, mode])
打开一个文件,并且设置需要的打开选项,mode参数是可选的 |
| 39 |
os.openpty()
打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 |
| 40 |
os.pathconf(path, name)
返回相关文件的系统配置信息。 |
| 41 |
os.pipe()
创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 |
| 42 |
os.popen(command[, mode[, bufsize]])
从一个 command 打开一个管道 |
| 43 |
os.read(fd, n)
从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 |
| 44 |
os.readlink(path)
返回软链接所指向的文件 |
| 45 |
os.remove(path)
删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 |
| 46 |
os.removedirs(path)
递归删除目录。 |
| 47 |
os.rename(src, dst)
重命名文件或目录,从 src 到 dst |
| 48 |
os.renames(old, new)
递归地对目录进行更名,也可以对文件进行更名。 |
| 49 |
os.rmdir(path)
删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 |
| 50 |
os.stat(path)
获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 |
| 51 |
os.stat_float_times([newvalue])
决定stat_result是否以float对象显示时间戳
|
| 52 |
os.statvfs(path)
获取指定路径的文件系统统计信息 |
| 53 |
os.symlink(src, dst)
创建一个软链接 |
| 54 |
os.tcgetpgrp(fd)
返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 |
| 55 |
os.tcsetpgrp(fd, pg)
设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 |
| 56 |
os.tempnam([dir[, prefix]])
返回唯一的路径名用于创建临时文件。 |
| 57 |
os.tmpfile()
返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。 |
| 58 |
os.tmpnam()
为创建一个临时文件返回一个唯一的路径 |
| 59 |
os.ttyname(fd)
返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 |
| 60 |
os.unlink(path)
删除文件路径 |
| 61 |
os.utime(path, times)
返回指定的path文件的访问和修改的时间。 |
| 62 |
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
输出在文件夹中的文件名通过在树中游走,向上或者向下。 |
| 63 |
os.write(fd, str)
写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |
④ MAC python环境变量问题
MAC升级到Big Sur新版本后,python 导入耐搏包时报错,明明这个包已经安装过了。
最开始以为是升级后因为权限什么的导致python环境出了问题,于是花了时间重装了anaconda,结果重装完还是一样有问题......
更新了flask版本,也在环境变量~/.zshrc和~/.bash_profile里面添加了anaconda安装路径,还是有问题
又折腾了好久,才发现是python模块搜索路径有问题,打印出来发现根本没有包含python的安装路径
于是在~/.zshrc里面添加了PYTHONPATH,可以啦!!!
额,然后发现只是念携在默认python环境下才可以昌高祥.......一旦进入虚拟环境,又出现同样的问题,已经安装的包无法导入。赶时间,只能先临时修改环境变量(即一旦重启终端就会失效,需要重新设置),后续有机会再看看怎么修改到配置文件里面。
⑤ python sys.path 从哪里
将路径“永久"添加到sys.path?
sys.path是python的搜索模块的路径集,是一个list
复制代码 代码如下:
['', 'C:\\WINDOWS\\system32\\python26.zip', 'C:\\Python26\\DLLs', 'C:\\Python26\ \lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26 ', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32' , 'C:\\Python26\\lib\\site-packages\\win32\\lib', 'C:\\Python26\\lib\\site-packa ges\\Pythonwin']
可以在python 环境下使用sys.path.append(path)添加相关的路径,但在退出python环境后自己添加的路径就会自动消失!
在python脚本中修改
复制代码 代码如下:
import sys
sys.path.append('c:\\mypythonlib')
为解决这个问题,可以有以下方法:
1. 将自己做的py文件放到 site_packages 目录下:
下面命令显示了 site-packages 目录:
复制代码 代码如下:
python -c "from distutils.sysconfig import get_python_lib; print get_python_lib() "
但是这样做会导致一个问题,即各类模块都放到此文件夹的话,会导致乱的问题,这一点是显而易见的。
注意,也不创建子文件夹,再将自己的模块放到子文件夹解决问题,这会导致使用import 语句时错误。
2. 使用pth文件,在 site-packages 文件中创建 .pth文件,将模块的路径写进去,一行一个路径,以下是一个示例,pth文件也可以使用注释:
# .pth file for the my project(这行是注释)
E:\DjangoWord
E:\DjangoWord\mysite
E:\DjangoWord\mysite\polls
这个不失为一个好的方法,但存在管理上的问题,而且不能在不同的python版本中共享。
3. 使用PYTHONPATH环境变量,在这个环境变量中输入相关的路径,不同的路径之间用逗号(英文的!)分开,如果PYTHONPATH 变量还不存在,可以创建它!
路径会自动加入到sys.path中,而且可以在不同的python版本中共享,应该是一样较为方便的方法。
⑥ python获取当前路径
来自: https://www.cnblogs.com/wind-wang/p/5822192.html
import os,sys
使用sys.path[0]、sys.argv[0]、os.getcwd()、os.path.abspath( file )、os.path.realpath( file )
sys.path是Python会去寻找模块的搜索路径列表,sys.path[0]和sys.argv[0]是一回事因为Python会自动把sys.argv[0]加入sys.path。
如果你在C: est目录下执行python getpathgetpath.py,那么os.getcwd()会输出“C: est”,sys.path[0]会输出“C: estgetpath”。
如果你用py2exe模块把Python脚本编译为可执行文件,那么sys.path[0]的输出还会变化:
如果把依赖库用默认的方式打包为zip文件,那么sys.path[0]会输出“C: estgetpathlibarary.zip”;
如果在setup.py里面指定zipfile=None参数,依赖库就会被打包到exe文件里面,那么sys.path[0]会输出“C: estgetpathgetpath.exe”。
os.getcwd() “D:”,取的是起始执行目录
sys.path[0]或sys.argv[0] “D:python_test”,取的是被初始执行的脚本的所在目录
os.path.split(os.path.realpath( file ))[0] “D:python_test”,取的是 file 所在文件test_path.py的所在目录
正确获取当前的路径:
⑦ python import 路径问题 新手
以下为纯手打,下面给几个demos:
说明:
moles所在的目录在python里叫package, 下面是一个名为 IsDir的package(实际上就是一个目录), package下面有4个moles(A, B, C, D)和一个__init__.py文件,目录结构如下:
IsDir/
A.pyB.pyC.pyD.py__init__.py
大体来讲,有两种方法可以调用某目录下(包括递归目录)的moles.
一. __init__.py为空时
1.1以下为调用moleA的代码:
#!/usr/bin/envpython
fromIsDirimportA
A.say()
输出:
ThisismoleA!
1.2 如果想调用moleA,B,C,D呢?
方法1.
#!/usr/bin/envpython
fromIsDirimportA
fromIsDirimportB
fromIsDirimportC
fromIsDirimportD
A.say()
B.say()
C.say()
D.say()
方法2.
#!/usr/bin/envpython
importIsDir.A
importIsDir.B
importIsDir.C
importIsDir.D
fromIsDirimport*
A.say()
B.say()
C.say()
D.say()
错误示例1:
#!/usr/bin/envpython
importIsDir.A
A.say()
错误示例2:
#!/usr/bin/envpython
fromIsDirimport*
A.say()
错误的原因:
IsDir/目录下__init__.py为空时,直接importIsDir.A或者fromIsDirimport*是无效的.
从官方文档里可以看到,__init__.py 里没有__all__=[mole1,mole2,...]时,
fromIsDirimport* 只能保证IsDir被imported, 所以此时IsDir里的moles是无法被imported,
此时只有如我上面所写的代码所示才能正确执行,否则是错误的。官方解释为:importIsDir.A并无任何意义,只有接着执行fromIsDirimport*后,importIsDir.A语句里的moleA才会被定义,所以完整的调用因改为: 1. import IsDir.A 2. from IsDir import *。
二. __init__.py用all=[...]指定该package下可以被imported进去的mole
__init__.py里写入如下内容:
%catIsDir/__init__.py
__all__=["A","B"]
然后使用之:
#!/usr/bin/envpython
fromIsDirimport*
A.say()
B.say()
结果:
%pythontest.py
ThisismoleA!
ThisismoleB!
错误实例:
#!/usr/bin/envpython
fromIsDirimport*
C.say()
以上示例之所以错误,是因为C并没有在__all__=["A","B"]里制定,由此可见,packageIsDir下面的__init__.py里,__all__=[...]具有隔离moles的作用。
补充:
mole A, B, C,D里我分别只定义了一个method, 例如,以下为mole A的code:
%catIsDir/A.py
defsay():
print"ThisismoleA!"
后记:
谢谢这位同学,回答你的问题感觉很有收获,顺便又把python温习了一遍。回头把这些总结贴到我的blog上以上为手写,望采纳,共勉。
=============================================================
老子写了这么多居然采用了另一个简陋的答案,mlgb的,枉我熬夜给你答题。这种白痴楼主就不配在这里问问题。
⑧ 添加python的import搜索目录
如果我们要添加自己的搜索目录,有两种方法:
一是直接修改sys.path,添加要搜索的目录:
第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块猜丛搜索路径中。设置方式与设置唯锋Path环境变量类似。注意只需要添穗山樱加你自己的搜索路径,Python自己本身的搜索路径不受影响。
⑨ python 模块的路径搜索方法
导入一个叫 spam 的模块时,解释器先在当前目录中搜索名为 spam.py 的文件。如果没有找到的话,接着会到 sys.path 变量中给出的目录列表中查找。 sys.path 变量的初始值来自如下:
输入脚本的目录(当前目录)。
环境变量 PYTHONPATH 表示的目录列表中搜索
(这和 shell 变量 PATH 具有一样的语法,即一系列目录名的列表)。
Python 默认安装路径中搜索。
Note
在支持符号链接的文件系统中,输入的脚本所在的目录是符号链接指向的目录。 换句话说也就是包含符号链接的目录不会被加到目录搜索路径中。
实际上,解释器由 sys.path 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录), PYTHONPATH 和安装目录。这样就允许 Python 程序了解如何修改或替换模块搜索目录。需要注意的是由于这些目录中包含有搜索路径中运行的脚本,所以这些脚本不应该和标准模块重名,否则在导入模块时 Python 会尝试把这些脚本当作模块来加载。这通常会引发错误。