Ich habe einige Zweifel an dem Design der mehrfache Vererbung in einigen Python-Klassen.Best Practices für die Mehrfachvererbung in diesem Python-Code
Die Sache ist, dass ich die TTK-Taste erweitern wollte. Das war mein erster Vorschlag (ich Weglassen des gesamten Quelltext in Methoden zur Verkürzung, außer init Methoden):
import tkinter as tk
import tkinter.ttk as ttk
class ImgButton(ttk.Button):
"""
This has all the behaviour for a button which has an image
"""
def __init__(self, master=None, **kw):
super().__init__(master, **kw)
self._img = kw.get('image')
def change_color(self, __=None):
"""
Changes the color of this widget randomly
:param __: the event, which is no needed
"""
pass
def get_style_name(self):
"""
Returns the specific style name applied for this widget
:return: the style name as a string
"""
pass
def set_background_color(self, color):
"""
Sets this widget's background color to that received as parameter
:param color: the color to be set
"""
pass
def get_background_color(self):
"""
Returns a string representing the background color of the widget
:return: the color of the widget
"""
pass
def change_highlight_style(self, __=None):
"""
Applies the highlight style for a color
:param __: the event, which is no needed
"""
pass
Aber ich später erkannte, dass ich auch eine Unterklasse dieser ImgButton wollte wie folgt:
import tkinter as tk
import tkinter.ttk as ttk
class MyButton(ImgButton):
"""
ImgButton with specifical purpose
"""
IMG_NAME = 'filename{}.jpg'
IMAGES_DIR = os.path.sep + os.path.sep.join(['home', 'user', 'myProjects', 'myProject', 'resources', 'images'])
UNKNOWN_IMG = os.path.sep.join([IMAGES_DIR, IMG_NAME.format(0)])
IMAGES = (lambda IMAGES_DIR=IMAGES_DIR, IMG_NAME=IMG_NAME: [os.path.sep.join([IMAGES_DIR, IMG_NAME.format(face)]) for face in [1,2,3,4,5] ])()
def change_image(self, __=None):
"""
Changes randomly the image in this MyButton
:param __: the event, which is no needed
"""
pass
def __init__(self, master=None, value=None, **kw):
# Default image when hidden or without value
current_img = PhotoImage(file=MyButton.UNKNOWN_IMG)
super().__init__(master, image=current_img, **kw)
if not value:
pass
elif not isinstance(value, (int, Die)):
pass
elif isinstance(value, MyValue):
self.myValue = value
elif isinstance(value, int):
self.myValue = MyValue(value)
else:
raise ValueError()
self.set_background_color('green')
self.bind('<Button-1>', self.change_image, add=True)
def select(self):
"""
Highlights this button as selected and changes its internal state
"""
pass
def toggleImage(self):
"""
Changes the image in this specific button for the next allowed for MyButton
"""
pass
Die Erbschaft fühlt sich natürlich richtig an. Das Problem kam, als ich bemerkte, dass die meisten Methoden in ImgButton für jedes Widget wiederverwendbar sind, das ich in Zukunft erstellen kann.
So etwa ich denke, eine zu machen:
class MyWidget(ttk.Widget):
denn in ihm alle Methoden setzen, die für Widgets mit Farbe helfen und dann brauche ich ImgButton sowohl von mywidget und ttk.Button zu erben:
class ImgButton(ttk.Button, MyWidget): ???
or
class ImgButton(MyWidget, ttk.Button): ???
Edited: auch möchte ich meine Objekte speicherbare sein, so habe ich diese Klasse:
class Loggable(object):
def __init__(self) -> None:
super().__init__()
self.__logger = None
self.__logger = self.get_logger()
self.debug = self.get_logger().debug
self.error = self.get_logger().error
self.critical = self.get_logger().critical
self.info = self.get_logger().info
self.warn = self.get_logger().warning
def get_logger(self):
if not self.__logger:
self.__logger = logging.getLogger(self.get_class())
return self.__logger
def get_class(self):
return self.__class__.__name__
So jetzt:
class ImgButton(Loggable, ttk.Button, MyWidget): ???
or
class ImgButton(Loggable, MyWidget, ttk.Button): ???
or
class ImgButton(MyWidget, Loggable, ttk.Button): ???
# ... this could go on ...
ich von Java kommen und ich weiß nicht, Best Practices für die Mehrfachvererbung. Ich weiß nicht, wie ich die Eltern in der besten Reihenfolge sortieren sollte, oder etwas anderes, das nützlich für die Gestaltung dieser Mehrfachvererbung ist.
Ich habe nach dem Thema gesucht und eine Menge Ressourcen gefunden, die das MRO erklären, aber nichts darüber, wie man eine Mehrfachvererbung richtig gestaltet. Ich weiß nicht, ob sogar mein Design falsch gemacht wurde, aber ich dachte, dass es sich ziemlich natürlich anfühlt.
Ich wäre dankbar für einen Rat, und für einige Links oder Ressourcen zu diesem Thema auch.
Vielen Dank.
ich schon dachte, die gleiche Gefahr mit tkinter, aber für Durch eine neue visuelle Kontrolle fühlt es sich natürlich an, eine bestehende zu erweitern. Ich kenne Mixins und ich habe keine Gründe gegen sie. Auswendig denke ich jetzt würde ich Vererbung verwenden und MyWidget Kind mit Eltern Loggable und ttk.Widget machen. ImgButton wäre Kind mit den Eltern MyWidget und ttk.Button. Zwei Eltern jeder Ebene, aber weiter unten würde es keine Notwendigkeit für Mehrfachvererbung mehr geben. – madtyn