热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python模块查找机制探究

先上段上代码:[root@localhost~]#viSocketServer.pyimportSocketServerclassMyTCPHandler(SocketServer.BaseRe

先上段上代码:

[root@localhost ~]# vi SocketServer.py

importSocketServer

classMyTCPHandler(SocketServer.BaseRequestHandler):

   
def handle(self):
       
self.data =self.request.recv(1024).strip()
       
print"{} wrote:".format(self.client_address[0])
       
printself.data
       
self.request.sendall(self.data.upper())

if __name__ =="__main__":
    HOST
, PORT ="localhost",9999
    server
=SocketServer.TCPServer((HOST, PORT),MyTCPHandler)
    server
.serve_forever()

这段程序语法上是正确的,但就是运行时报如下的错:

[root@localhost ~]# python SocketServer.py
Traceback(most recent call last):
 
File"SocketServer.py", line 1,in
   
?importSocketServer
 
File"/root/SocketServer.py", line 3,in
   
classMyTCPHandler(SocketServer.BaseRequestHandler):
AttributeError:'module'object has no attribute 'BaseRequestHandler'

这个问题是一个刚学python不久的新手遇到的,拿着这个报错信息在网上搜也找不到答案,原因是什么呢?我想大家看到上面我贴出代码就知道是啥原因了,因为这个脚本的名字为SocketServer.py,而在这个脚本中import了SocketServer这个模块,python把当前目录下的SocketServer.py当成了SocketServer模块,解决方法很简单,把脚本的文件名改一下就可以了,这个问题解决,接下来看一下python加载模块的机制,用strace来跟一下这个程序

stat("/root",{st_mode=S_IFDIR|0550, st_size=4096,...})=0
stat
("/root",{st_mode=S_IFDIR|0550, st_size=4096,...})=0
stat
("/root/SocketServer",0x7fffc5280bf0)=-1 ENOENT (No such file or directory)
open
("/root/SocketServer.so", O_RDONLY)=-1 ENOENT (No such file or directory)
open
("/root/SocketServermodule.so", O_RDONLY)=-1 ENOENT (No such file or directory)
open
("/root/SocketServer.py", O_RDONLY)=3
fstat
(3,{st_mode=S_IFREG|0644, st_size=449,...})=0
open
("/root/SocketServer.pyc", O_RDONLY)=4
fstat
(4,{st_mode=S_IFREG|0644, st_size=856,...})=0
mmap
(NULL,4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,-1,0)=0x7f9ec67dc000
read
(4,"\3\363\r\n\353\t\36Pc\0\0\0\0\0\0\0\0\3\0\0\0@\0\0\0sf\0\0\0d\0"...,4096)=856
fstat
(4,{st_mode=S_IFREG|0644, st_size=856,...})=0
read
(4,"",4096)                       =0
close
(4)                                =0
munmap
(0x7f9ec67dc000,4096)            =0
close
(3)                                =0

这段是加载模块的地方,我们可以看到python加载模块时,首先是在当前目录下搜索,先stat SocketServer,看SocketServer这个目录是否存在,然后再搜索SocketServer.so,接着搜SocketServermodule.so,最后搜索SocketServer.py和SocketServer.pyc,直到找到,我们发现另外一个现象就是python已经找到了.py文件了,并且打开了,但还是会继续找.pyc文件,这个地方有点奇怪。接着我们跟一下把名字改掉后的脚本:

stat("/tmp",{st_mode=S_IFDIR|S_ISVTX|0777, st_size=12288,...})=0
stat
("/tmp",{st_mode=S_IFDIR|S_ISVTX|0777, st_size=12288,...})=0
stat
("/tmp/SocketServer",0x7fff13219a70)=-1 ENOENT (No such file or directory)
open
("/tmp/SocketServer.so", O_RDONLY)  =-1 ENOENT (No such file or directory)
open
("/tmp/SocketServermodule.so", O_RDONLY)=-1 ENOENT (No such file or directory)
open
("/tmp/SocketServer.py", O_RDONLY)  =-1 ENOENT (No such file or directory)
open
("/tmp/SocketServer.pyc", O_RDONLY)=-1 ENOENT (No such file or directory)
stat
("/usr/lib64/python2.6/SocketServer",0x7fff13219a70)=-1 ENOENT (No such file or directory)
open
("/usr/lib64/python2.6/SocketServer.so", O_RDONLY)=-1 ENOENT (No such file or directory)
open
("/usr/lib64/python2.6/SocketServermodule.so", O_RDONLY)=-1 ENOENT (No such file or directory)
open
("/usr/lib64/python2.6/SocketServer.py", O_RDONLY)=3
fstat
(3,{st_mode=S_IFREG|0644, st_size=21914,...})=0
open
("/usr/lib64/python2.6/SocketServer.pyc", O_RDONLY)=4
fstat
(4,{st_mode=S_IFREG|0644, st_size=21222,...})=0
mmap
(NULL,4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,-1,0)=0x2b268d545000
read
(4,"m\362\r\nz\17\305Lc\0\0\0\0\0\0\0\0\v\0\0\0@\0\0\0s.\2\0\0d\0"...,4096)=4096
close
(4)                                =0
munmap
(0x2b268d545000,4096)            =0

这个看的更加明白了,python会在当前目录下找,然后接着到系统的路径的路径下去找,也就是sys.path

>>>import sys
>>> sys.path
['','/usr/lib64/python26.zip','/usr/lib64/python2.6','/usr/lib64/python2.6/plat-linux2','/usr/lib64/python2.6/lib-tk','/usr/lib64/python2.6/lib-old','/usr/lib64/python2.6/lib-dynload','/usr/lib64/python2.6/site-packages']

我们只要把python模块放在这个sys.path里所在路径下,python就可以找到我们的模块,如果我们python模块不在当前路径下也不在sys.path里怎么办呢?我们有两种方式:

第一种,设置PYTHONPATH:

假如我将模块放在/home/admin/下,在终端下执行如下命令:
$
export PYTHONPATH=$PYTHONPATH:/home/admin/
$ echo $PYTHONPATH
:/home/admin/
>>> sys.path
['','/tmp','/home/admin','/usr/lib64/python26.zip','/usr/lib64/python2.6','/usr/lib64/python2.6/plat-linux2','/usr/lib64/python2.6/lib-tk','/usr/lib64/python2.6/lib-old','/usr/lib64/python2.6/lib-dynload','/usr/lib64/python2.6/site-packages']

第二种,在程序运行时修改sys.path就可以

>>>import sys
>>> sys.path
['','/usr/lib64/python26.zip','/usr/lib64/python2.6','/usr/lib64/python2.6/plat-linux2','/usr/lib64/python2.6/lib-tk','/usr/lib64/python2.6/lib-old','/usr/lib64/python2.6/lib-dynload','/usr/lib64/python2.6/site-packages']
>>> sys.path.append("/home/admin")
>>> sys.path
['','/usr/lib64/python26.zip','/usr/lib64/python2.6','/usr/lib64/python2.6/plat-linux2','/usr/lib64/python2.6/lib-tk','/usr/lib64/python2.6/lib-old','/usr/lib64/python2.6/lib-dynload','/usr/lib64/python2.6/site-packages','/home/admin']

看完了python的模块查找机制后,总感觉这个查找机制不是很高效,如果模块在sys.path这个list最后一个,那么python要把list中所有路径都遍历一遍,假如sys.path的路径很多,遍历一遍还是需要花一些时间。

 
0 Comments
2012/08/05 17:42
Tags: module, python.
 

Before you can run VMware, several modules must be compiled and loaded into the running kernel

在ubuntu 12.04上安装vmware workstation 8.02,

在vmware kernel module updater这个窗口上,编译第二步Virtual Network Device 时出现错误

查看Log,有如下报错:

2012-06-24T14:56:24.833+08:00| vthread-3| I120:Your GCC version:4.6
2012-06-24T14:56:24.839+08:00| vthread-3| I120:Your GCC version:4.6
2012-06-24T14:56:24.855+08:00| vthread-3| I120:Header path /lib/modules/3.2.0-25-generic/build/include for kernel release 3.2.0-25-generic is valid.
2012-06-24T14:56:24.867+08:00| vthread-3| I120:Trying to find a suitable PBM setfor kernel 3.2.0-25-generic.

解决方案:

# cd /usr/lib/vmware/modules; 
# wget http://pavlinux.ru/vmware/8.0.2/source.tar.lzma;
# tar -xf source.tar.lzma;
# vmware-modconfig --console --install-all

vmware

 
3 Comments
2012/06/24 15:30
Tags: vmware.
 
http://jasonwu.me/
推荐阅读
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
author-avatar
纽约纽约MrWaNg
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有