【发布时间】:2013-01-11 09:15:45
【问题描述】:
我正在尝试制作一个 Python 库来使用来自 Objective-C 的 Ubutu One API。这是我的源代码: https://github.com/JoseExposito/U1-Finder-Plugin/blob/master/U1FinderLib/U1FinderLib.py
我需要对 API 进行多次调用,因此我需要让我的反应器运行一次,而不是运行它并停止它,就像 Ubuntu One 文档的示例中一样: https://one.ubuntu.com/developer/files/store_files/syncdaemontool
因为不可能运行两次反应器...而且我需要在线程中执行 reactor.run() 因为我无法阻止使用该库的应用程序!
有可能吗?我无法在线程中运行反应器并同步调用 Ubuntu One API。
编辑:
我正在使用这个简单的源代码来测试这个想法:
#!/usr/bin/env python
import objc
import thread
import os
import time
from twisted.internet import reactor, defer
from ubuntuone.platform.tools import (SyncDaemonTool, is_already_running)
from threading import Thread
NSObject = objc.lookUpClass('NSObject')
##
# Variable to get the result of the calls to the Sync Daemon.
# The result is a JSON string stored in returned_value[0].
returned_value = ['']
##
# Objective-C facade to the methods of the U1FinderLib.
class U1FinderLib(NSObject):
def init(self):
self = super(U1FinderLib, self).init()
self.sync_daemon_tool = SyncDaemonTool(None)
Thread(target=reactor.run, args=(False,)).start()
return self
@objc.typedSelector('@@:')
def volumeList(self):
print "Begin volumeList"
reactor.callLater(0, run_command, "volume_list", [], self.sync_daemon_tool)
print "End volumeList"
return returned_value[0]
##
# Auxiliar functions to call to the sync daemon.
@defer.inlineCallbacks
def run_command(action, params, sync_daemon_tool):
print "run_command"
running = yield is_already_running()
print "After is_already_running"
try:
if not running:
returned_value[0] = '{ type:"error" reason:"Sync Daemon is not running" }'
else:
print "Before run_action"
yield run_action(action, params, sync_daemon_tool)
print "After run_action"
except Exception, e:
returned_value[0] = '{ type:"error" reason:"Exception: %s" }' % e
@defer.inlineCallbacks
def run_action(action, params, sync_daemon_tool):
if action == "volume_list":
d = sync_daemon_tool.get_folders()
returned_value[0] = yield d.addCallback(lambda r: volume_list(r))
# Volume List
def volume_list(folders):
volumes_json = '{ type:"volume_list" volumes: { \n\t{ volume:"' + os.path.expanduser('~/Ubuntu One') + '" subscribed:"YES" }'
for folder in folders:
volumes_json += ',\n\t{ volume:"' + folder['path'] + '" subscribed:"' + ('YES' if bool(folder['subscribed']) else 'NO') + '" }'
volumes_json += '\n} }'
return volumes_json
if __name__ == '__main__':
py = U1FinderLib.alloc().init()
print py.volumeList()
print "EXIT"
这是程序的输出:
Begin volumeList
End volumeList
EXIT
问题是“run_command”函数从未被调用
【问题讨论】:
-
你总是可以将你的函数注册为deferands,通过reactor触发它们#
-
你能解释一下吗?我是一个 Python 完全菜鸟(事实上这是我在 Python 中的第一个代码)
-
第一次用 Python 编程并直接跳到 Twisted?祝你好运... :)
-
作为 Twisted 的长期开发者和用户,“将你的函数注册为 deferands [原文如此]”或“通过反应器发射它们#”这两个短语对我来说都没有任何意义。我想雅各布可能会和你一起玩。
标签: python cocoa ubuntu twisted