我正在寻找requests
模块的来源,并注意到this code:
class Response(object):
"""The :class:`Response <Response>` object, which contains a
server's response to an HTTP request.
"""
def __init__(self):
super(Response, self).__init__()
... more init method...
我对super()
的理解表明这个电话根本不会做任何事情。我发现quite有一些questions关于superclass calling,但所有这些都来自其他类的子类,而不是object
本身。 python docs也没有提到这种结构。
我觉得这可能只是一个错误,如果你git blame
向commit that introduced that line提交了文件,你会发现在作者身份时,Response
是一个BaseResponse
的子类。该行只是一个类重构的延续,还是这个super()调用做了什么呢?
答案 0 :(得分:4)
如果 Response 成为多重继承树的一部分,则此代码实际上可能会执行某些操作。 &#34; MRO&#34;中的下一课程列表可能是 object 之外的其他内容!在这种情况下,对 super 的调用可能非常必要。
例如,
class NewerClass(A, Response):
def __init__(self):
... do stuff ...
super(NewerClass, self).__init__()
从该类定义中,如果不知道 A 的层次结构是什么,则无法确定super(Response, self).__init__()
调用的下一个类将是什么。它可能是 object ,也可能是 A 的基类。
我认为一个问题是名称 super 会导致混淆。它不像Smalltalk的 super 变量那样,除非你只使用单继承,并且它不会返回&#34;超类&#34;宾语。相反,它正在做的是找出&#34; next&#34;根据MRO命令使用的类。
关于这个主题的经典文章是: Python's Super Considered Super和Python's Super Considered Harmful。
答案 1 :(得分:2)
如Corley Brigman's comment所述,这是不必要的,但无害。
对于某些背景知识,在Kenneth的sprint期间,在Requests 1.0上添加了BaseResponse
类。 1.0代码更改引入了transport adapters,这使得为某些HTTP端点(或实际上non-HTTP endpoints)定义特定行为成为可能。传输适配器接口的一个重要部分是HTTPAdapter.build_response()
方法,它从HTTPAdapter.send()
获取返回的原始响应,并从中构建一个请求Response
对象。
很明显,Kenneth看到了为Response
提供某种形式的抽象基类的潜在效用,这将允许传输适配器将Response
的行为返回到标准HTTP {{} 1}}对象。出于这个原因,使用子类中的大部分逻辑将重构转换为ABC似乎是有意义的。
后来在重构中,由于不必要的复杂性,这再次被拉出来。现实情况是,想要定义专门的Response
对象的人可以简单地将Response
子类化,而不是让ABC不做任何事情。这使得主线用例(vanilla Requests)在代码中更加清晰,并且几乎没有任何实用程序。
当Response
课程被拔出时,这一行被忽略了,但由于它没有引起任何问题,因此从未需要删除它。
答案 2 :(得分:0)
darinbob是正确的。 在谈论单一继承时,这是不必要的,但是在多重继承中,情况有所不同:
class WithSuper:
def __init__(self):
print('With super')
super().__init__()
class NoSuper:
def __init__(self):
print('No super')
class TestOne(WithSuper, NoSuper):
def __init__(self):
print('Test 1')
super().__init__()
class TestTwo(NoSuper, WithSuper):
def __init__(self):
print('Test 2')
super().__init__()
one = TestOne()
print(TestOne.__mro__)
print('\n' * 2)
two = TestTwo()
print(TestTwo.__mro__)
使用python3运行上面的代码,您会看到区别。
Test 1
With super
No super
(<class '__main__.TestOne'>, <class '__main__.WithSuper'>, <class '__main__.NoSuper'>, <class 'object'>)
Test 2
No super
(<class '__main__.TestTwo'>, <class '__main__.NoSuper'>, <class '__main__.WithSuper'>, <class 'object'>)