Python的gtk
模块为了导入一个奇怪的魔法
名为gdk
的模块。任何地方都没有实际的gdk
模块。该
gtk/__init__.py
模块的开头如下所示:
# load the required modules:
import gobject as _gobject
ver = getattr(_gobject, 'pygobject_version', ())
if ver < (2, 11, 1):
raise ImportError(
"PyGTK requires PyGObject 2.11.1 or higher, but %s was found" % (ver,))
if 'gtk._gtk' in sys.modules:
_gtk = sys.modules['gtk._gtk']
else:
from gtk import _gtk
import gdk
显然gdk
,像Athena一样,完全由...构成
_gtk.so
模块中包含的gtk
共享库。这就是全部
很好,但我试图解决的问题是
使用weechat,加载使用gtk
的Python脚本
第一次,但后来失败了这样的追溯:
python: loading script "/home/username/.weechat/python/lnotify.py"
python: stdout/stderr: Traceback (most recent call last):
python: stdout/stderr: File "/home/username/.weechat/python/lnotify.py", line 20, in <module>
python: stdout/stderr: import weechat, string, pynotify
python: stdout/stderr: File "/usr/lib64/python2.7/site-packages/gtk-2.0/pynotify/__init__.py", line 19, in <module>
python: stdout/stderr: import gtk
python: stdout/stderr: File "/usr/lib64/python2.7/site-packages/gtk-2.0/gtk/__init__.py", line 42, in <module>
python: stdout/stderr: import gdk
python: stdout/stderr: ImportError: No module named gdk
python: unable to parse file "/home/username/.weechat/python/lnotify.py"
所以,正在发生的事情突然发生在gtk
模块上
无法在共享库中找到gdk
模块。我&#39;米
甚至不确定从哪里开始进一步诊断,因为我不是
完全确定什么可能导致这种符号解决问题。
你以前见过这样的事吗?
答案 0 :(得分:1)
问题源于这样一个事实:每个进程只加载一个C扩展模块,而WeeChat在该单个进程上下文中使用多个解释器实例,每个脚本一个。这个does not play well具有扩展模块for a number of reasons。
在这种特殊情况下,模块初始化仅在首次导入扩展模块gtk._gtk
时运行一次,正如您所指出的那样,gtk.gdk
出现在哪里。从那时起,每次import gtk
的尝试都会发现_gtk
已经被加载,因此在新的解释器上下文中复制了它的模块字典的浅表副本。这将使您可以访问gtk._gtk
,但不会再次调用扩展初始化函数,这就是后续解释器将丢失gtk.gdk
的原因。
您可以在没有WeeChat的情况下重现此行为,也可以通过导入gtk
,删除sys.modules
中的引用并再次导入gtk
来使用子解释器来重现此行为:
import sys
import gtk
for mod in sys.modules.keys():
if mod.startswith('gtk'):
sys.modules.pop(mod)
import gtk
# throws "ImportError: No module named gdk"
没有简单的方法可以解决这个问题。你可以试试
fork()
为在WeeChat中执行的每个脚本提供真正的隔离(但在Windows上做什么?)并以额外开销为代价避免此问题。