首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >龙卷风的AsyncHTTPClient子类

龙卷风的AsyncHTTPClient子类
EN

Stack Overflow用户
提问于 2018-01-11 15:56:25
回答 1查看 1K关注 0票数 1

(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继承不建议使用它/不是使用它的有效方法:

代码语言:javascript
复制
    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属性的默认值。例如:

代码语言:javascript
复制
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类?

目前没有错误,但在实际获取之后,我没有收到响应。

代码语言:javascript
复制
import sys
from tornado import ioloop, gen, httpclient

类下SimpleAsyncHTTPClient(httpclient.AsyncHTTPClient):

代码语言:javascript
复制
#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():

代码语言:javascript
复制
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')
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-12 18:20:03

既然你已经用更多的细节更新了你的问题,而且它已经变得和原来的完全不同了,我想补充另一个答案。

:AsyncHTTPClient背后的魔力

请考虑以下代码:

代码语言:javascript
复制
http_client = AsyncHTTPClient()
print(http_client.__class__)

# Output:
<class 'tornado.simple_httpclient.SimpleAsyncHTTPClient'>

如您所见,http_clientSimpleAsyncHTTPClient的实例,而不是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,并根据您的需要对它进行修改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48211102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档