getChild" 在 Twisted 中是如何工作的
Twisted网络的文档说,getChild这个方法必须这样实现:
class Hello(Resource):
isLeaf = True
def getChild(self, name, request):
if name == '':
return self
return Resource.getChild(self, name, request)$
根据我的理解,这里有一个递归调用getChild方法,但谁负责从名字中去掉路径的部分呢?是哪个类里的哪个方法呢?
谢谢!
2 个回答
你可以通过使用 inspect 模块来获取调用 getChild(self, name, request) 的调用者。
import inspect
...
class Hello(Resource):
#isLeaf = True # This has to be left out, to ensure, getChild is called!
def getChild(self, name, request):
print inspect.stack()[2][1]
return self
现在你会在标准输出中看到以下内容:
2012-09-17 11:16:24+0200 [HTTPChannel,0,127.0.0.1] getChildForRequest
如果你查看 API 文档中关于 web/resource/Resource 的部分,并查看 Resource 的源代码,你会发现有一个方法叫做 "getChildForRequest"(在第 172 行),并且会看到一个弃用警告,内容是“…使用模块级别的 getChildForRequest。”这意味着你需要查看模块级别的内容,找到那个 函数(在第 58 行)。
接下来,这个模块级别的函数会通过检查 "isLeaf" 来处理路径元素,并移动前后路径元素。如果我们的资源有 "isLeaf",那么就会返回这个资源;否则,如果 request.postpath 存在且 "isLeaf" 为假,路径会被重新排列,然后会调用 resource.getChildWithDefault,这个方法会寻找一个始终可用的资源(这个资源是通过 putChild 添加的,或者简单地存在于 self.children 字典中)。如果找不到,它会调用 "getChild",这个方法应该返回一个动态资源,否则就会得到 getChild 的默认返回值,即:NoResource("没有这样的子资源") 在第 152 行。
祝好,
Laidback
比如,网址 /foo/bar/baz 通常会是:
Resource.getChild('foo').getChild('bar').getChild('baz')
但是,如果 'bar' 返回的资源设置了 isLeaf 为 true,那么就不会再对它进行 getChild 的调用了。