(python 3.6.4和tornado 4.5.3)
使用时: http客户端=tornado.httpclient.AsyncHTTPClient() 异步http请求获取工作正常。在
但是试图定义和使用AsyncHTTPClient的子类让我在运行程序时陷入了某种死锁(与同步HTTPClient类相反,它的一个子类运行良好)
*请纠正我:如果Tornado的AsynchHTTPClient类依附于/继承自可配置接口/抽象类,那么如何从中构建对象?(与Java中的规则相同?)。是不是有什么东西在几个内置的实现中选择了一个默认的实现?在
可配置子类必须定义可配置的基类和可配置的默认类方法,并使用实例方法initialize而不是init-在继承的情况下,默认的构造函数会调用super。init?这就是问题的原因吗?在
从文档中可以看出,不建议使用从AsyncHTTPClient继承/不是使用它的有效方法:
http_client = AsyncHTTPClient()
http_client.fetch("http://www.google.com/", handle_response)
这个类的构造函数在几个方面很神奇:它
实际创建特定于实现的实例
子类和实例作为一种伪单例重用
(每个.IOLoop
一个)。关键字参数force_instance=True
可用于抑制此单例行为。除非
force_instance=True
被使用,不应将任何参数传递给
AsyncHTTPClient
构造函数。实现子类为
以及其构造函数的参数可以用
方法configure()
所有AsyncHTTPClient
实现都支持defaults
关键字参数,可用于为设置默认值
HTTPRequest
属性。例如:
其他问题:
1)缓冲响应是否是一种选择?在
3)我什么时候该上课tornado.web请求处理程序? 在
目前没有错误,但在实际获取之后我没有收到响应。在
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
在全球:
在@通用协同程序在
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')
但为什么呢?您可以使用
AsyncHTTPClient
。在如果你这样做是为了学习,这里有一个概念的概要:
yield
和await
用于暂停协同程序。但它们不一样。然而,在Tornado中,当yield
关键字在一个gen.coroutine
修饰函数中时,它们都会执行相同的操作—即在将来(或awaitable)完成之前挂起一个协程。return
用于从函数返回某些内容,我相信您已经知道了。何时使用
yield
,何时使用await
?在如果使用的Python版本早于3.5,请使用
@gen.coroutine ... yield
语法。对于3.5+,应该使用async def ... await
语法。另外,Tornado不久将推出drop support for older Python版本,因此最好遵守新语法。在所以我要指出,把这两者混合起来似乎不是个好主意。通过将},从而摆脱旧的语法。在
@gen.coroutine
替换为async
,并用await
替换{关于您的代码的一些注释:
让我们看看
_fetch
和get
方法。他们两个都不还钱。在为了详细说明,在},因为{}没有返回任何内容。
res = await self._fetch(url, method)
的get
方法中,res
将是{同样的情况也发生在
ioloop_task
的res = http_client.get(url)
。res
将是None
,因为get
没有返回任何内容。在要解决这个问题,只需从
_fetch
和get
方法返回res
对象。在另外,您不需要
_fetch
方法。您可以在get
方法中执行这些操作:实际上,您甚至不需要
^{pr2}$async ... await
语法。这同样有效:为什么第二个代码示例可以很好地工作,我把它作为练习留给您去弄清楚。在
既然你用更多的细节更新了你的问题,而且它与原来的大不相同,我想再加一个答案。在
AsyncHTTPClient背后的魔力
考虑以下代码:
如您所见,}。那么,这是怎么回事?在
http_client
是SimpleAsyncHTTPClient
的实例,而不是{如果您查看^{} 的源代码,您将看到它继承了
tornado.utils.Configurable
类。在Configurable
类中最重要的一段代码是__new__
方法,它负责所有的魔术。如果您查看它的source code,您会发现它将为类方法configurable_default
返回的任何类创建一个实例。在现在,看看^{} 的源代码。它返回}的实例。在
SimpleAsyncHTTPClient
类,这就是为什么我们上面创建的对象(http_client
)是SimpleAsyncHTTPClient
的实例,而不是{最后,是的,您是对的,您需要在子类中创建
fetch_impl
方法。因为AsyncHTTPClient
将调用self.fetch_impl
方法。您可以在this line in source code中看到这一点。在虽然,
fetch_impl
没有在AsyncHTTPClient
类中实现,但它已经在SimpleAsyncHTTPClient
中实现。你可以找到它here。在如何成功子类
AsyncHTTPClient
?{我需要先看看你的西装。在
相关问题 更多 >
编程相关推荐