tornado中一些通用的函数和类


本篇记录tornado源代码阅读过程中一些有意思的函数和类等,偏向于python编程技巧语法等。

ObjectDict


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class ObjectDict(dict):
"""Makes a dictionary behave like an object, with attribute-style access.
"""
def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
self[name] = value
od = ObjectDict()
od.a = 1
od['a'] # 1
od.a # 1

import_object


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def import_object(name):
"""Imports an object by name.
import_object('x') is equivalent to 'import x'.
import_object('x.y.z') is equivalent to 'from x.y import z'.
>>> import tornado.escape
>>> import_object('tornado.escape') is tornado.escape
True
>>> import_object('tornado.escape.utf8') is tornado.escape.utf8
True
>>> import_object('tornado') is tornado
True
>>> import_object('tornado.missing_module')
Traceback (most recent call last):
...
ImportError: No module named missing_module
"""
if name.count('.') == 0:
return __import__(name, None, None)
parts = name.split('.')
obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0)
try:
return getattr(obj, parts[-1])
except AttributeError:
raise ImportError("No module named %s" % parts[-1])

importlib.import_module更加方便,import_object可以直接导入模块或者属性,而前者只能导入模块。另外注意两个函数都是将导入的对象返回,而不是将其暴露在当前域名中, 和import有差距。

1
2
3
4
5
6
7
8
9
import_object('os')
os #NameError
path_exists = import_object('os.path.exists')
# from os.path import exists as path_exists
####################
mypath = importlib.import_module('.path', 'os')
# from os import path as mypath

###