super()
предназначен для использования как в методах класса, так и в обычных методах. В classmethod
нет экземпляра, у вас есть доступ только к классу, поэтому второй аргумент super()
принимает либо экземпляр, либо класс. По крайней мере, это описано в документации для super()
:
Если вторым аргументом является объект, isinstance(obj, type)
должно быть истинным. Если второй аргумент является типом, issubclass(type2, type)
должно быть истинным (, это полезно для методов класса ).
Мой жирный акцент.
Теперь Основная задача, которую super()
должен выполнить, - это поиск атрибутов в списке классов Порядка разрешения методов (MRO) по заданной отправной точке. Отправной точкой является первый аргумент, но MRO должен быть взят из второго аргумента; если вы используете super()
в классе Foo
, вы не можете знать в это время, если Foo
мог быть разделен на подклассы, что может изменить MRO второго аргумента. Таким образом, для этой цели super()
отслеживает две части информации:
- Класс, который вы хотите использовать в качестве отправной точки для поиска (первый аргумент)
- Класс из которого берется MRO (тип второго аргумента, если он является экземпляром, или просто второй аргумент, если это класс).
Существует также третья часть информации, экземпляр или класс, к которому привязаны атрибуты, когда вы выполняете поиск атрибутов. Это просто второй аргумент, либо экземпляр, либо класс. Вывод repr()
отражает только первые два значения , в значительной степени потому, что они «скрыты» в этом super()
, без аргументов, получает свои аргументы из контекста и поэтому вы не можете, так же просто посмотрите, что является отправной точкой, или каков источник MRO, но вы можете намного легче увидеть первый аргумент метода (так self
или cls
).
Если вы хотите различать guish между вашими двумя super()
экземплярами, вы можете вместо этого взглянуть на атрибут __self__
, который представляет 3-й фрагмент информации:
>>> sup = super(B, b)
>>> sup.__self__
<__main__.B object at 0x108b4c520>
>>> sup2 = super(B, B)
>>> sup2.__self__
<class '__main__.B'>
Другой две части информации, которые вы видите в выводе repr()
, это атрибуты __thisclass__
и __self_class__
соответственно:
>>> sup.__thisclass__, sup.__self_class__
(<class '__main__.B'>, <class '__main__.B'>)
Это легче заметить, когда вы используете другой класс в качестве первого аргумента :
>>> sup_a = super(A, b)
>>> sup_a
<super: <class 'A'>, <B object>>
>>> sup_a.__thisclass__, sup_a.__self_class__
(<class '__main__.A'>, <class '__main__.B'>)