GOOGLE ADS

Dienstag, 19. April 2022

Deaktivieren Sie die Vererbung einiger Methoden

Angenommen, ich habe eine Klasse mit 10 Methoden (ich schreibe passhier, gehe aber davon aus, dass sie eine Implementierung haben würden).

class KlassOne:
def method_one(self, x):
pass

def method_two(self, y, z):
pass
...
def method_five(self, a):
pass
...
def method_ten(self, b):
pass

und eine zweite Klasse, die von der ersten erbt.

class KlassTwo(KlassOne):
def method_eleven(self, w):
pass

will aber KlassTwonicht alle zehn Methoden von KlassOne, sagen wir, KlassTwowill nur diese vier Methoden erben,

wanted_methods = [method_one, method_three, method_eight, method_nine]

und der Rest trifft nicht zu, denn KlassTwo ein Beispiel könnte sein,
KlassOneist Person und KlassTwoist Robot und method_fiveist EatsFood so, unser Robotwill nicht erben, EatsFood während method_oneist BodyWeight, und nehmen wir mal an, es macht Sinn für beide Personund Robot, also Robotwill erben method_one.

aber wie könnte diese Teilvererbung erreicht werden???

Eine Möglichkeit, dies zu tun, ist NotImplementedbeispielsweise die Verwendung von

class KlassTwo(KlassOne):
def method_five(self, a):
raise NotImplemented

und machen Sie dasselbe für jede Methode, die nicht erwünscht ist.

oder der andere Weg könnte darin bestehen, Komposition zu verwenden, wie z.

class KlassTwo:
def __init__(self, x):
self.t = KlassOne.method_one(self, x)

so etwas, und verwenden Sie nur die gewünschten Methoden.

aber ich möchte die Vererbung verwenden und die Vererbung einiger Methoden vollständig deaktivieren, das ist so etwas wie

class KlassOne:
@not_inheritable
def method_five(self, a):
pass

damit keine Unterklasse method_five. wie erreiche ich das?

oder geben Sie eine Liste in KlassTwo, wieder wie,

wanted_methods = [method_one, method_three, method_eight, method_nine]

und stellen Sie sicher, dass nur diese vererbt werden.


Lösung des Problems

Dies beantwortet Ihre Frage "Wie man teilweise erbt" nicht direkt, sondern schlägt eine Alternative vor, falls wir mit einem XYZ-Problem konfrontiert sind.

In Anbetracht Ihres Beispiels aus Menschen und Robotern scheint Ihre Basisklasse nicht ganz eine Basisklasse (oder generisch) für das zu sein, was Sie versuchen zu tun.

Es könnte besser sein, die Basisklasse als Union von Unterklassen zu definieren, die Sie haben werden, und andere Might-need-might-not-Funktionen wie EatsFoodin subclass oder als Mixin hinzuzufügen.

Nehmen wir zum Beispiel an, wir möchten Menschen, Humanoide, Affen und Marcus Wright haben.

Was sie gemeinsam haben: Sie sind menschenähnliche Wesen mit menschlicher Gestalt. Lassen Sie uns die Basisklasse mit dem definieren, was übliche menschenähnliche Entitäten tun könnten.

from __future__ import annotations
class HumanLike:
"""
Base class for human-like entities
"""
def __init__(self):
# some required attributes or setups
pass
def left_punch(self, target: HumanLike):
"""punch target with left fist"""
def right_hook(self, target: HumanLike):
"""Give nice right hook to target"""
def walk(self, pos):
"""Walk towards pos"""

Jetzt wollen wir Menschen, Humanoide und Affen machen. Dann können wir etwas Gemeinsames zwischen Mensch und Affe finden, z. B. Mixin.

class BiologicalMixin:
"""
Mixin class for biological entities with basic needs
"""
def eat(self, food):
"""Eats given food"""
def breath(self):
"""Give that lung a fresh 'n nice air"""
class RoboticMixin:
"""
Mixin for Non-Biological entities with robot needs
"""
def recharge(self):
"""recharge energy"""
def robot_dance(self):
"""Pull out some sick moves that weak creatures can't"""

Und dann müssten wir diese nur noch in Unterklassen unterteilen, um verschiedene Sachen herzustellen.

class Human(HumanLike, BiologicalMixin):
"""
An obviously human like being with biological needs
"""
class Humanoid(HumanLike, RoboticMixin):
"""
A Human shaped robot
"""
class Monkey(HumanLike, BiologicalMixin):
"""
They love bananas!
"""
class TerminatorHybrid(HumanLike, BiologicalMixin, RoboticMixin):
"""
Marcus Wright would be here
"""

Dies ist eine gebräuchlichere Art der Vererbung - Optionale Vererbung ist keine Vererbung.

Wenn Sie solche wirklich brauchen, ist die beste Möglichkeit, die ich mir vorstellen kann, die manuelle Verwendung der gewünschten Kompositions- und Zuordnungsmethoden.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...