How does a method of a subclass become a method of the base class?
Jen Kris
jenkris at tutanota.com
Sun Mar 26 16:36:18 EDT 2023
Based on your explanations, I went through the call chain and now I understand better how it works, but I have a follow-up question at the end.
This code comes from the DeltaBlue benchmark in the Python benchmark suite.
1
The call chain starts in a non-class program with the following call:
EqualityConstraint(prev, v, Strength.REQUIRED)
2
EqualityConstraint is a subclass of BinaryConstraint, so first it calls the __init__ method of BinaryConstraint:
def __init__(self, v1, v2, strength):
super(BinaryConstraint, self).__init__(strength)
self.v1 = v1
self.v2 = v2
self.direction = Direction.NONE
self.add_constraint()
3
At the final line shown above it calls add_constraint in the Constraint class, the base class of BinaryConstraint:
def add_constraint(self):
global planner
self.add_to_graph()
planner.incremental_add(self)
4
At planner.incremental_add it calls incremental_add in the Planner class because planner is a global instance of the Planner class:
def incremental_add(self, constraint):
mark = self.new_mark()
overridden = constraint.satisfy(mark)
At the final line it calls "satisfy" in the Constraint class, and that line calls choose_method in the BinaryConstraint class. Just as Peter Holzer said, it requires a call to "satisfy."
My only remaining question is, did it select the choose_method in the BinaryConstraint class instead of the choose_method in the UrnaryConstraint class because of "super(BinaryConstraint, self).__init__(strength)" in step 2 above?
Thanks for helping me clarify that.
Jen
Mar 26, 2023, 18:55 by hjp-python at hjp.at:
> On 2023-03-26 19:43:44 +0200, Jen Kris via Python-list wrote:
>
>> The base class:
>>
>>
>> class Constraint(object):
>>
> [...]
>
>> def satisfy(self, mark):
>> global planner
>> self.choose_method(mark)
>>
>> The subclass:
>>
>> class UrnaryConstraint(Constraint):
>>
> [...]
>
>> def choose_method(self, mark):
>> if self.my_output.mark != mark and \
>> Strength.stronger(self.strength, self.my_output.walk_strength):
>> self.satisfied = True
>> else:
>> self.satisfied = False
>>
>> The base class Constraint doesn’t have a "choose_method" class method,
>> but it’s called as self.choose_method(mark) on the final line of
>> Constraint shown above.
>>
>> My question is: what makes "choose_method" a method of the base
>> class,
>>
>
> Nothing. choose_method isn't a method of the base class.
>
>> called as self.choose_method instead of
>> UrnaryConstraint.choose_method? Is it super(UrnaryConstraint,
>> self).__init__(strength) or just the fact that Constraint is its base
>> class?
>>
>
> This works only if satisfy() is called on a subclass of Constraint which
> actually implements this method.
>
> If you do something like
>
> x = UrnaryConstraint()
> x.satisfy(whatever)
>
> Then x is a member of class UrnaryConstraint and will have a
> choose_method() method which can be called.
>
>
>> Also, this program also has a class BinaryConstraint that is also a
>> subclass of Constraint and it also has a choose_method class method
>> that is similar but not identical:
>>
> ...
>
>> When called from Constraint, it uses the one at UrnaryConstraint. How
>> does it know which one to use?
>>
>
> By inspecting self. If you call x.satisfy() on an object of class
> UrnaryConstraint, then self.choose_method will be the choose_method from
> UrnaryConstraint. If you call it on an object of class BinaryConstraint,
> then self.choose_method will be the choose_method from BinaryConstraint.
>
> hp
>
> PS: Pretty sure there's one "r" too many in UrnaryConstraint.
>
> --
> _ | Peter J. Holzer | Story must make more sense than reality.
> |_|_) | |
> | | | hjp at hjp.at | -- Charles Stross, "Creative writing
> __/ | http://www.hjp.at/ | challenge!"
>
More information about the Python-list
mailing list