(python 3.6.4和龙卷风4.5.3)
当使用: http_client = tornado.httpclient.AsyncHTTPClient()时,异步http请求获取很好。
但是,试图定义和使用AsyncHTTPClient的子类使我在运行程序时陷入某种类型的死锁(与其子类功能良好的同步HTTPClient类相反)。
*请纠正我:如果龙卷风的AsynchHTTPClient类遵循/继承可配置接口/抽象类,那么如何能够从它构建对象?(与Java中的规则相同)。是某种东西在几个内置的实现中为它选择了一个默认实现吗?
“可配置子类必须定义类方法configurable_base和configurable_default,并使用实例方法初始化而不是init。”--在继承的情况下,默认的ctor会调用super.init吗?这就是问题的原因吗?
从文档中可以看出,从AsyncHTTPClient继承不建议使用它/不是使用它的有效方法:
http_client = AsyncHTTPClient()
http_client.fetch("http://www.google.com/", handle_response)这个类的构造函数在几个方面是神奇的:它实际上创建了一个特定于实现的子类的实例,并且实例被重用为一种伪单例(每个.IOLoop一个)。关键字参数force_instance=True可用于抑制这种单例行为。除非使用force_instance=True,否则不应将任何参数传递给AsyncHTTPClient构造函数。实现子类及其构造函数的参数可以使用静态方法configure() All AsyncHTTPClient实现来设置,该方法支持defaults关键字参数,该参数可用于设置HTTPRequest属性的默认值。例如:
AsyncHTTPClient.configure(
None, defaults=dict(user_agent="MyUserAgent"))
# or with force_instance:
client = AsyncHTTPClient(force_instance=True,
defaults=dict(user_agent="MyUserAgent"))补充问题:
1)缓冲响应是否是一种选择?
3)我应该什么时候使用tornado.web.RequestHandler类?
目前没有错误,但在实际获取之后,我没有收到响应。
import sys
from tornado import ioloop, gen, httpclient类下SimpleAsyncHTTPClient(httpclient.AsyncHTTPClient):
#had to add this one (abstract function empty implementation? )
# I think that's the troublemaker
def fetch_impl(self, request, callback):
pass
@gen.coroutine
def get(self, url):
method = 'GET'
print('send Async GET request ')
res = yield self._fetch(url, method)
print('after _fetch ...')
return res
@gen.coroutine
def _fetch(self, url, method):
print('send Asynchronous request ...')
res = yield self.fetch(url, method=method)
print('got a response')
return res在全球范围:
@gen.coroutine
def ioloop_task():
yield gen.sleep(3)
url = 'http://google.com'
http_client = SimpleAsyncHTTPClient()
res = yield http_client.get(url)
res_code = res.code
res_body = res.body
print('return code: {}, body: {}....'.format(res_code, res_body[:60]))
print('do other stuff ....')
yield gen.sleep(2)
print(' task completed')发布于 2018-01-12 18:20:03
既然你已经用更多的细节更新了你的问题,而且它已经变得和原来的完全不同了,我想补充另一个答案。
:AsyncHTTPClient背后的魔力
请考虑以下代码:
http_client = AsyncHTTPClient()
print(http_client.__class__)
# Output:
<class 'tornado.simple_httpclient.SimpleAsyncHTTPClient'>如您所见,http_client是SimpleAsyncHTTPClient的实例,而不是AsyncHTTPClient的实例。这是怎么回事?
如果您查看AsyncHTTPClient的源代码,您将看到它正在继承tornado.utils.Configurable类。
Configurable类中最重要的代码是负责所有魔术的__new__方法。如果查看它的源代码,您会发现它将创建由classmethod configurable_default返回的任何类的实例。
现在,看看AsyncHTTPClient.configurable_default的源代码。它正在返回SimpleAsyncHTTPClient类,这就是为什么我们在上面创建的对象(http_client)是SimpleAsyncHTTPClient的实例,而不是AsyncHTTPClient的实例。
最后,没错,您需要在子类中创建fetch_impl方法。因为AsyncHTTPClient将调用self.fetch_impl方法。您可以在源代码中的这一行中看到这一点。
尽管fetch_impl还没有在AsyncHTTPClient类中实现,但它已经在SimpleAsyncHTTPClient中实现了。你可以找到它,这里。
如何成功地子类AsyncHTTPClient**?**
我首先看一下SimpleAsyncHTTPClient,并根据您的需要对它进行修改。
https://stackoverflow.com/questions/48211102
复制相似问题