tornado是一个并发框架,在写IO密集型的程序时,非阻塞式请求才能最大程度发挥框架的能力。
AsyncHTTPClient的使用官方给的例子是:
Example usage::
def handle_response(response):
if response.error:
print("Error: %s" % response.error)
else:
print(response.body)
http_client = AsyncHTTPClient()
http_client.fetch("http://www.google.com/", handle_response)
现在有一个疑问:每次请求都需要新建一个AsyncHTTPClient对象吗?
The constructor for this class is magic in several respects: It
actually creates an instance of an implementation-specific
subclass, and instances are reused as a kind of pseudo-singleton
(one per.IOLoop
). The keyword argumentforce_instance=True
can be used to suppress this singleton behavior.
这是该类的一段介绍,可以发现只要构造对象时不使用force_instance的参数,该类会表现出单例类的行为,所以每次新建对象没有问题。
AsyncHTTPClient.configure(None, defaults=dict(user_agent="MyUserAgent"))
# or with force_instance:
client = AsyncHTTPClient(force_instance=True,
defaults=dict(user_agent="MyUserAgent"))
下面是类的构造方法:
@classmethod
def _async_clients(cls):
attr_name = '_async_client_dict_' + cls.__name__
if not hasattr(cls, attr_name):
setattr(cls, attr_name, weakref.WeakKeyDictionary())
return getattr(cls, attr_name)
def __new__(cls, force_instance=False, **kwargs):
io_loop = IOLoop.current()
if force_instance:
instance_cache = None
else:
instance_cache = cls._async_clients()
if instance_cache is not None and io_loop in instance_cache:
return instance_cache[io_loop]
instance = super(AsyncHTTPClient, cls).__new__(cls, **kwargs)
# Make sure the instance knows which cache to remove itself from.
# It can't simply call _async_clients() because we may be in
# __new__(AsyncHTTPClient) but instance.__class__ may be
# SimpleAsyncHTTPClient.
instance._instance_cache = instance_cache
if instance_cache is not None:
instance_cache[instance.io_loop] = instance
return instance