事件处理程序中的 Python Kivy PicklingError:无法腌制 <type 'code'>:属性查找 __builtin__.code 失败
Posted
技术标签:
【中文标题】事件处理程序中的 Python Kivy PicklingError:无法腌制 <type \'code\'>:属性查找 __builtin__.code 失败【英文标题】:Python Kivy PicklingError within event handler: Can't pickle <type 'code'>: attribute lookup __builtin__.code failed事件处理程序中的 Python Kivy PicklingError:无法腌制 <type 'code'>:属性查找 __builtin__.code 失败 【发布时间】:2016-03-15 03:25:04 【问题描述】:我是 Kivy 和多处理的新手。
我正在探索同时运行多个 Kivy 应用程序,使用多处理,方式与以下相同:Running multiple Kivy apps at same time that communicate with each other。
现在,我想维护当前运行的应用程序的共享列表,例如 Manager.list()
,但我一开始就卡住了。我有一个这样的测试代码:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from multiprocessing import Process, Manager
class ParentApp(App):
def __init__(self, app_list, **kwargs):
super(ParentApp, self).__init__(**kwargs)
self.app_list = app_list
def build(self):
self.add_self_to_list()
return Label(text = "abc")
# def on_start(self):
# self.add_self_to_list()
def add_self_to_list(self):
self.app_list.append(self)
if __name__ == "__main__":
manager = Manager()
my_list = manager.list()
print "Before:"
print my_list
parent = ParentApp(my_list)
p = Process(target = parent.run)
p.start()
p.join()
print "After:"
print my_list
这会将ParentApp
正确添加到共享的my_list
,但是当我在build
中注释掉self.add_self_to_list()
并取消注释on_start
时,我得到了这个PicklingError:
...
self.app_list.append(self)
File "<string>", line 2, in append
File "C:\Kivy-1.9.0-py2.7-win32-x64\Python27\lib\multiprocessing\managers.py", line 758, in _callmethod
conn.send((self._id, methodname, args, kwds))
PicklingError: Can't pickle <type 'code'>: attribute lookup __builtin__.code failed
我还尝试将add_self_to_list
挂钩到按钮的on_press
回调,但我得到了同样的错误。为什么它适用于 build
方法而不适用于回调?有没有办法解决这个问题?
我在 Windows 7 上运行 Kivy 1.9.0 和 Python 2.7。
(如果您想知道我为什么要这样尝试:每个应用程序都可能调用其他应用程序。如果一个应用程序已经在运行,我不想启动一个新应用程序并用副本污染屏幕同一个窗口。理想情况下,我会抓住应用程序并在前面弹出它的窗口。我还没有尝试过 Kivy 应用程序的 root_window,所以我什至不确定这是否可能。只是查看选项在这里 :) 如果您已经知道这是否可以使用 Kivy 完成,我也想知道,但也许我会发布另一个问题! )
【问题讨论】:
【参考方案1】:我不知道kivy
是否有任何特殊限制,但你不能腌制一个code
对象用于multiprocessing
。但是,multiprocessing
的一个分支(称为multiprocess
)使用可以腌制code
对象的序列化程序(dill
)。所以,multiprocess
应该有机会为你工作。
>>> import multiprocess
>>> CodeType = compile('','','exec')
>>> f = lambda x:CodeType
>>> p = multiprocess.Pool()
>>> p.map(f, range(2))
[<code object <module> at 0x100aeb5b0, file "", line 1>, <code object <module> at 0x100af1130, file "", line 1>]
顺便说一句,我建议不要腌制 GUI 类实例,而是从 GUI 中提取和转储状态。
【讨论】:
注意,我是multiprocess
的作者。
谢谢迈克,我现在才看到你的回答。我会尽快尝试,然后再回来找你。以上是关于事件处理程序中的 Python Kivy PicklingError:无法腌制 <type 'code'>:属性查找 __builtin__.code 失败的主要内容,如果未能解决你的问题,请参考以下文章
Python/Kivy:如何在 ctrl+a 键盘事件上调用函数
使用python / kivy处理小部件放置以解决屏幕旋转的好方法是啥?