Open holdenweb opened 10 years ago
It's great to come here and see the explanation. Thanks for taking the time to post the details!
Happy it's been helpful. The reports were anonymous, so I couldn't respond directly, and the O'Reilly Errata page appears to contain no functionality to action a reported error.
In introducing-decorators.ipynb we apply a class decorator,
barking()
, to two instances, the first of a class with one applicable method, the second of a subclass of that class with two further applicable methods. This succeeds with the first class (the one with only one method) but fails with the second for reasons described below.Although the commentary makes it appear the (very lightweight) testing performed succeeds, closer examination of the output reveals that the two additional methods are actually calling the same original method (
wag()
), and the the original code of the decorator has a bug.This issue is caused by the use of a decorator-local variable to wrap each non-dunder method. Since the same variable is used to wrap each method, and since all methods are handled in a single call to the decorator, the wrapped functions must necessarily all be the same.
This explains why both
d3.wag()
andd3.sniff()
print "a dog_3 is happy" - thewag()
method is the last to be processed by the decorator, and is thus the function called by all decorated methods.Note also that this example demonstrates that only locally-defined methods appear in the class's
__dict__
- the inheritedshout()
method is not wrapped a second time.Please comment and reassign to me for further discussion.