15.04.2013 Views

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

gc = GC()<br />

>>> gc.foo() # GC C1 P1<br />

called P1-foo()<br />

>>> gc.bar() # GC C1 P1 P2<br />

called P2-bar()<br />

When calling foo(), it looks in the current class (GC) first. If it cannot be found, it goes up to its<br />

immediate parent, C1. The search fails there so it continues up the tree to its parent, P1, which is where<br />

foo() is found.<br />

Likewise for bar(), it searches through GC, C1, and P1 before then finding it in P2. C2.bar() is never found<br />

because of the resolution order used. Now, you may be thinking, "I would prefer to call C2's bar()<br />

because it is closer to me in the inheritance tree, thus more relevant." In this case, you can still use it,<br />

but you have to do it in the typical unbound fashion by invoking its fully qualified name and providing a<br />

valid instance:<br />

>>> C2.bar(gc)<br />

called C2-bar()<br />

New-Style Classes<br />

Now uncomment the (object) next to the class declarations for P1 and P2 and reexecute. The new-style<br />

method resolution gives us something different:<br />

>>> gc = GC()<br />

>>> gc.foo() # GC C1 C2 P1<br />

called P1-foo()<br />

>>> gc.bar() # GC C1 C2<br />

called C2-bar()<br />

Instead of following the tree up each step, it looks at the siblings first, giving it more of a breadth-first<br />

flavor. When looking for foo(), it checks GC, followed by C1 and C2, and then finds it in P1. If P1 did not<br />

have it, it would have gone to P2. The bottom line for foo() is that both classic and new-style classes<br />

would have found it in P1, but they took different paths to get there.<br />

The result for bar() is different, though. It searches GC and C1, and finds it next in C2 and uses it there.<br />

It does not continue up to the grandparents P1 and P2. In this case, the new-style resolution fit into the<br />

scheme better if you did prefer to call the "closest" bar() from GC. And of course, if you still need to call<br />

one higher up, just do it in an unbound manner as before:<br />

>>> P2.bar(gc)<br />

called P2-bar()<br />

New-style classes also have an __mro__ attribute that tells you what the search order is:<br />

>>> GC.__mro__

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!