我知道这通常是用twistd完成的,但是我想用iPython来测试扭曲代码上的'live'代码。
How to start twisted's reactor from ipython基本上问了同样的事情,但第一个解决方案不再适用于当前的ipython / twisted,而第二个解决方案也无法使用(线程会引发多个错误)。
https://gist.github.com/kived/8721434有一个名为TPython的东西,它声称可以做到这一点,但运行它似乎工作,除了客户端永远不会连接到服务器(运行相同的客户端在python shell中工作)。
我有使用Conch Manhole,还是有办法让iPython玩得很好(可能是_threadedselect)。
供参考,我要求使用ipython 5.0.0,python 2.7.12,twisted 16.4.1
答案 0 :(得分:1)
在实时解释器中运行异步代码通常很麻烦。最好只在后台运行异步脚本,并在单独的解释器中执行iPython内容。您可以使用文件或TCP进行相互通信。如果这超过你的头脑,那是因为它并不总是很简单,最好避免可能的麻烦。
但是,您会很高兴知道在非异步应用程序中使用Twisted有一个名为crochet
的强大项目。它确实是我最喜欢的模块之一,我感到震惊的是它没有被广泛使用(你可以改变它; D虽然)。 crochet
模块有一个run_in_reactor
装饰器,它在由crochet
本身管理的单独线程中运行Twisted反应器。这是一个快速类示例,它执行对Star Wars RESTFul API的请求,然后将JSON响应存储在列表中。
from __future__ import print_function
import json
from twisted.internet import defer, task
from twisted.web.client import getPage
from crochet import run_in_reactor, setup as setup_crochet
setup_crochet()
class StarWarsPeople(object):
people_id = [_id for _id in range(1, 89)]
people = []
@run_in_reactor
def requestPeople(self):
"""
Request Star Wars JSON data from the SWAPI site.
This occurs in a Twisted reactor in a separate thread.
"""
for _id in self.people_id:
url = 'http://swapi.co/api/people/{0}'.format(_id).encode('utf-8')
d = getPage(url)
d.addCallback(self.appendJSON)
def appendJSON(self, response):
"""
A callback which will take the response from the getPage() request,
convert it to JSON, then append it to self.people, which can be
accessed outside of the crochet thread.
"""
response_json = json.loads(response.decode('utf-8'))
#print(response_json) # uncomment if you want to see output
self.people.append(response_json)
将其保存在文件中(例如:swapi.py
),打开iPython,导入新创建的模块,然后像这样运行快速测试:
from swapi import StarWarsPeople
testing = StarWarsPeople()
testing.requestPeople()
from time import sleep
for x in range(5):
print(len(testing.people))
sleep(2)
正如您所看到的,它在后台运行,并且主线程中仍然可以发生内容。您可以像往常一样继续使用iPython解释器。你甚至可以在后台运行一个沙井来进行一些很酷的黑客攻击!
答案 1 :(得分:0)
虽然这不能回答我认为的问题,但它确实回答了我发布的问题。嵌入ipython的工作原理是您可以在反应堆运行时访问业务对象。
from twisted.internet import reactor
from twisted.internet.endpoints import serverFromString
from myfactory import MyFactory
class MyClass(object):
def __init__(self, **kwargs):
super(MyClass, self).__init__(**kwargs)
server = serverFromString(reactor, 'tcp:12345')
server.list(MyFactory(self))
def interact():
import IPython
IPython.embed()
reactor.callInThread(interact)
if __name__ == "__main__":
myclass = MyClass()
reactor.run()
使用python myclass.py
或类似内容调用上述内容。