This has been bugging me for a while and appears hard to google.
In the following code can anyone explain the pragmatic difference between FirstChild
and SecondChild
. It's clear from experiments that both "work" and arguably SecondChild
is marginally more efficient. But is there something that I'm missing about the way these two behave? Are they different and how are they different?
import collections
class Parent:
def send_message(self, message: str):
pass
class FirstChild(Parent):
def __init__(self):
self.message_queue = collections.deque()
def send_message(self, message: str):
self.message_queue.append(message)
class SecondChild(Parent):
def __init__(self):
self.message_queue = collections.deque()
self.send_message = self.message_queue.append
FirstChild
creates a descriptor in the class called send_message
. When you do instance.send_message
, the interpreter first searches the instance __dict__
for the name, then the class. When it's found in the class, the function is bound to the instance to create a method object that doesn't accept self
. It happens every time you do the lookup, and it looks something like
method = type(instance).send_message.__get__(type(instance), instance)
SecondChild
assigns a bound method as the attribute send_message
in the instance . It cuts out the lookup in its own class object, as well as the lookup in the deque
class object, and binding. That is probably why it appears marginally more efficient.
A major practical difference between these approaches is that send_message
in SecondChild
is not overridable. Since functions are non data descriptors (they have a __get__
method but not __set__
(and yes, functions have a class type and methods, like any other object)), the instance attribute send_message
in SecondChild
will always trump any class-level function. This means that a child of SecondChild
that calls the parent __init__
method will hide any implementation of send_message
it creates.
You will likely find the official descriptor guide to be quite informative: https://docs.python.org/3/howto/descriptor.html
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.