getChild" 在 Twisted 中是如何工作的

2 投票
2 回答
2678 浏览
提问于 2025-04-17 12:57

Twisted网络的文档说,getChild这个方法必须这样实现:

class Hello(Resource):
    isLeaf = True
    def getChild(self, name, request):
        if name == '':
            return self
        return Resource.getChild(self, name, request)$

根据我的理解,这里有一个递归调用getChild方法,但谁负责从名字中去掉路径的部分呢?是哪个类里的哪个方法呢?

谢谢!

2 个回答

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

2

比如,网址 /foo/bar/baz 通常会是:

Resource.getChild('foo').getChild('bar').getChild('baz')

但是,如果 'bar' 返回的资源设置了 isLeaf 为 true,那么就不会再对它进行 getChild 的调用了。

撰写回答