PyGTK的问题" gdk"模

时间:2014-03-28 03:12:54

标签: python gtk irc

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;米 甚至不确定从哪里开始进一步诊断,因为我不是 完全确定什么可能导致这种符号解决问题。

你以前见过这样的事吗?

1 个答案:

答案 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"

没有简单的方法可以解决这个问题。你可以试试

  1. 修复PyGTK以使用与(重新)在不同的解释器上下文中加载它的初始化过程
  2. fork()为在WeeChat中执行的每个脚本提供真正的隔离(但在Windows上做什么?)并以额外开销为代价避免此问题。