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