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-pyt...@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. > |_|_) | | > | | | h...@hjp.at | -- Charles Stross, "Creative writing > __/ | http://www.hjp.at/ | challenge!" > -- https://mail.python.org/mailman/listinfo/python-list