开发者

Why python super does not accept only instance?

In python 2.x, super accepts the following cases

class super(object)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:

as far as I see, super is a class, wrapping the type and (eventually) the instance to resolve the superclass of a class.

I'm rather puzzled by a couple of things:

  • why there is also no super(instance), with typical usage e.g. super(self).__init__(). Technically, you can obtain the type of an object from the object itself, so the current strategy super(ClassType, self).__init__() is kind of redundant. I assume compatibility issues with old-style classes, or multiple inheritance, but I'd like to hear your point.
  • why,开发者_如何学C on the other hand, python 3 will accept (see Understanding Python super() with __init__() methods) super().__init__() ? I see kind of magic in this, violating the explicit is better than implicit Zen. I would have seen more appropriate self.super().__init__().


super(ClassType, self).__init__() is not redundant in a cooperative multiple inheritance scheme -- ClassType is not necessarily the type of self, but the class from which you want to do the cooperative call to __init__.

In the class hierarchy C inherits B inherits A, in C.__init__ you want to call superclass' init from C's perspective, and you call B.__init__; then in B.__init__ you must pass the class type B to super -- since you want to resolve calling superclasses of B (or rather, the next in the mro after B of the class C).

class A (object):
  def __init__(self):
    pass

class B (A):
  def __init__(self):
    super(B, self).__init__()

class C (B):
  def __init__(self):
    super(C, self).__init__()

if you now instantiate c = C(), you see that the class type is not redundant -- super(self).__init__() inside B.__init__ would not really work! What you do is that you manually specify in which class the method calling super is (an this is solved in Python 3's super by a hidden variable pointing to the method's class).

Two links with examples of super and multiple inheritance:

  • Things to Know About Python Super (1 of 3)
  • Python's Super is nifty, but you can't use it


I can't provide a specific answer, but have you read the PEP's around the super keyword? I did a quick google search and it came up with PEP 367 and PEP 3135.

http://www.python.org/dev/peps/pep-0367/

http://www.python.org/dev/peps/pep-3135/#numbering-note

Unlike any other language I know of, most of the time you can find the answers to Python's quirks in the PEP's along with clear rational and position statements.

Update:

Having read through 3135, related emails in the Python Mailing and the language reference it kind of makes sense why it is the way it is for Python 2 vs Python 3.

http://docs.python.org/library/functions.html?highlight=super#super

I think super was implemented to be explicit/redundant just to be on the safe side and keep the logic involved as simple as possible ( no sugar or deep logic to find the parent ). Since super is a builtin function, it has to infer the correct return from what is provided without adding more complication to how Python objects are structured.

PEP 3135 changes everything because it presented and won an argument for a DRY'er approach to super.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜