Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

If the facts don't fit the theory, change the facts. -- Albert Einstein


devel / comp.lang.python / Re: How does a method of a subclass become a method of the base class?

SubjectAuthor
o Re: How does a method of a subclass become a method of the base class?Jen Kris

1
Re: How does a method of a subclass become a method of the base class?

<mailman.2404.1679862980.20444.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=22589&group=comp.lang.python#22589

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: jenk...@tutanota.com (Jen Kris)
Newsgroups: comp.lang.python
Subject: Re: How does a method of a subclass become a method of the base class?
Date: Sun, 26 Mar 2023 22:36:18 +0200 (CEST)
Lines: 146
Message-ID: <mailman.2404.1679862980.20444.python-list@python.org>
References: <NRU0CaG--3-9@tutanota.com>
<20230326184825.vjb5zwhi3elrfxsw@hjp.at>
<NRUchKZ--3-9@tutanota.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de xwR1qKcyCWefckYcVCPvAQN8g+bxtXEbO6kOTbIx68xA==
Return-Path: <jenkris@tutanota.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=tutanota.com header.i=@tutanota.com header.b=sXpdzN/Z;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.000
X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'def': 0.04; 'class,':
0.05; '26,': 0.07; 'clarify': 0.07; 'class.': 0.07; 'mar': 0.07;
'above.\xc2\xa0': 0.09; 'call:': 0.09; 'cc:addr:python-list':
0.09; 'else:': 0.09; 'skip:x 10': 0.09; 'skip:\xc2 20': 0.09;
'subject:class': 0.09; 'cc:no real name:2**0': 0.14; 'that.':
0.15; '"creative': 0.16; '+0200,': 0.16; '__/': 0.16;
'challenge!"': 0.16; 'constraint,': 0.16; 'hjp@hjp.at': 0.16;
'holzer': 0.16; 'implements': 0.16; 'inspecting': 0.16;
'instance': 0.16; 'nothing.': 0.16; 'reality.': 0.16; 'stross,':
0.16; 'subject:does': 0.16; 'url-ip:212.17.106.137/32': 0.16;
'url-ip:212.17.106/24': 0.16; 'url-ip:212.17/16': 0.16; 'url:hjp':
0.16; 'use?': 0.16; '|_|_)': 0.16; 'wrote:': 0.16; 'python': 0.16;
'instead': 0.17; 'uses': 0.19; 'calls': 0.19;
'cc:addr:python.org': 0.20; 'skip:_ 10': 0.22; 'code': 0.23;
'subject:How': 0.23; 'received:de': 0.23; 'cc:2**0': 0.25;
'object': 0.26; "isn't": 0.27; 'fact': 0.28; 'sense': 0.28;
'program': 0.31; 'question': 0.32; 'end.': 0.32; 'python-list':
0.32; 'said,': 0.32; 'mark': 0.32; 'received:192.168.1': 0.32;
'but': 0.32; 'requires': 0.34; 'skip:" 20': 0.34; 'header:In-
Reply-To:1': 0.34; 'following': 0.35; 'final': 0.35; 'also,':
0.36; 'member': 0.37; 'class': 0.37; 'received:192.168': 0.37;
'thanks': 0.38; 'skip:u 20': 0.39; 'base': 0.40; 'something':
0.40; 'method': 0.61; "there's": 0.61; 'above': 0.62; 'skip:\xc2
10': 0.62; 'skip:i 20': 0.62; 'true': 0.63; 'skip:b 10': 0.63;
'your': 0.64; 'similar': 0.65; 'skip:e 20': 0.67; 'ps:': 0.69;
'remaining': 0.69; 'subject:method': 0.69; 'url-ip:212/8': 0.69;
'url-ip:lookup error': 0.70; '8bit%:6': 0.71; 'global': 0.73;
'8bit%:100': 0.76; 'chain': 0.76; 'follow-up': 0.84; 'method,':
0.84; 'subject: \n ': 0.84; '\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0':
0.84; '\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0': 0.84
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1679862978;
s=s1; d=tutanota.com;
h=From:From:To:To:Subject:Subject:Content-Description:Content-ID:Content-Type:Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:In-Reply-To:In-Reply-To:MIME-Version:MIME-Version:Message-ID:Message-ID:Reply-To:References:References:Sender;
bh=CnBMIzoNKI3SOgx8OZWgF4tJjA1GcMCnMG/uTpTeUp0=;
b=sXpdzN/ZqQ0jlLSGmesLUT59wseFsl3wd7UlNjbfMzxxK8JqAfG98KkU3SPxG4xT
Mrc3ZLjJ4uTMgyRGnDKGCSvWJjdW2gYahHXAkwd861Ga7S8KStwMH8HwmS16HAH/ySC
TaE2jEjCmERPsyrBc6CpgykuCcN0rhl+Tq7TXTgRXzioX2yY/byk+ruIAw4lPu2VGP9
eTqYRoVBTSW/qYjgE+6HY7aR78Y48t3fkgKglN9idnSEHrjPQneN+bYk5errTCysoVD
2vNIrf5PHd2c1u6mP3twmxU8cDllVBHmqOZA6PPuQCGZKy036cp5GT2kzRA/U2wvehj
o1PfBygcpg==
In-Reply-To: <20230326184825.vjb5zwhi3elrfxsw@hjp.at>
X-Content-Filtered-By: Mailman/MimeDel 2.1.39
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <NRUchKZ--3-9@tutanota.com>
X-Mailman-Original-References: <NRU0CaG--3-9@tutanota.com>
<20230326184825.vjb5zwhi3elrfxsw@hjp.at>
 by: Jen Kris - Sun, 26 Mar 2023 20:36 UTC

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@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@hjp.at | -- Charles Stross, "Creative writing
> __/ | http://www.hjp.at/ | challenge!"
>

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor