更新时间:2022-10-18 22:40:28
Python 为任何给定的 import
搜索几个不同的文件,包括具有该名称的目录并包含 __init__.py
,纯原生 Python 模块的 .so
文件和 .pyc
文件,即使删除了 .py
也可以使用.
运行 strace -o trace_output.txt python
以查看其工作原理.import md5
的部分示例:
stat("/usr/lib/python2.7/md5", 0x7fff81ff16d0) = -1 ENOENT (没有那个文件或目录)open("/usr/lib/python2.7/md5.x86_64-linux-gnu.so", O_RDONLY) = -1 ENOENT (没有那个文件或目录)open("/usr/lib/python2.7/md5.so", O_RDONLY) = -1 ENOENT (没有那个文件或目录)open("/usr/lib/python2.7/md5module.so", O_RDONLY) = -1 ENOENT(没有那个文件或目录)打开(/usr/lib/python2.7/md5.py",O_RDONLY)= 3
在我的设置中,它实际上是在搜索:
~/.local/lib/python2.7/
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
/usr/lib/python2.7/
在每个目录中,调用stat
查找目录然后查找.so
文件,然后.py
的模式.
有关编写纯原生 Python 模块的更多信息,请参见此处:https://docs.python.org/2/extending/index.html
I am running an interactive Python shell and trying to see the path from which a module is being imported using the 'inspect' module. The modules I am trying to import have Python wrappers around C++ APIs using SWIG.
The following snippet shows my steps :
>>> import os
>>> import inspect
>>>
>>> import db
>>> inspect.getfile(db)
'mypath1/lib/db/db.pyc'
>>>
>>> import dart
>>> inspect.getfile(dart)
'mypath2/lib/dart.so'
>>>
My PYTHONPATH
contains both mypath1/lib/db
and mypath2/lib
.
I was under the impression that in order to be able to load modules, the interpreter needs access to a .py
file which then calls imp.load_module
to load the required shared library (.so
file). This is what I see in case of the db
module which has a db.py
file under mypath1/lib/db
. However, dart
does not have a .py
file under mypath2/lib
.
Is it possible to import a module without the .py file as is happening in the case of the dart
module ?
Python searches for several different files for any given import
including a directory by that name and containing an __init__.py
, an .so
file for pure-native Python modules and .pyc
files which can be used even if the .py
is removed.
Run strace -o trace_output.txt python
to see how this works. Partial example for import md5
:
stat("/usr/lib/python2.7/md5", 0x7fff81ff16d0) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5.x86_64-linux-gnu.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5module.so", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.7/md5.py", O_RDONLY) = 3
On my setup, it actually searches:
~/.local/lib/python2.7/
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
/usr/lib/python2.7/
Within each directory, the pattern of calling stat
to find a directory then looking for .so
files, then .py
is followed.
For more info on writing a purely native python module, see here: https://docs.python.org/2/extending/index.html