Seite 1 von 1

Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Freitag 25. Oktober 2019, 19:39
von Atalanttore
Hallo

Ich würde gerne mehrere Objekte des gleichen Typs erstellen. Der Name (Bezeichner) jedes zu erstellenden Objektes soll sich aus einem festen Präfix und String-Elementen aus einem Tupel zusammensetzen.

Etwas Python-Code zur Verdeutlichung was ich meine:

Code: Alles auswählen

from PyQt5.QtCore import QTimer


class Machine():
    def __init__(self):
        pump_names = ('water_pump, oil_pump', 'air_pump', 'grease_pump')

        self._timers = []

        for name in pump_names:
            timer = QTimer()
            timer.setSingleShot(True)
            # timer.timeout.connect(self._start_<name>) # Also `self._start_water_pump`, usw.
            # self._timers.append(self.timer_<name>) # Also `self.timer_water_pump`, usw.

    def _start_water_pump(self):
        pass

    def _start_oil_pump(self):
        pass

    def _start_air_pump(self):
        pass

    def _start_grease_pump(self):
        pass


def main():
    machine = Machine()


if __name__ == "__main__":
    main()
Am Ende sollen in der Liste `self._timers` dann 4 `QTimer`-Objekte mit folgenden Namen (Bezeichner) enthalten sein.
  • self.timer_water_pump
  • self.timer_oil_pump
  • self.timer_air_pump
  • self.timer_grease_pump
Lässt sich so etwas umsetzen?

Gruß
Atalanttore

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Freitag 25. Oktober 2019, 19:43
von __blackjack__
@Atalanttore: Ja, aber ich würde da ja erst einmal fragen warum das Attribute sein müssen und warum Du das nicht einfach in ein Wörterbuch stecken kannst das die Namen auf die Timer abbildet. Also beispielsweise anstelle der Liste. Und dann nur noch eine `_start_pump()`-Methode die den Namen der Pumpe als Argument bekommt.

Edit: Als Code:

Code: Alles auswählen

#!/usr/bin/env python3
from functools import partial

from PyQt5.QtCore import QTimer


class Machine:
    def __init__(self):
        self._timers = {
            name: QTimer(
                singleShot=True, timeout=partial(self._start_pump, name)
            )
            for name in ["water", "oil", "air", "grease"]
        }

    def _start_pump(self, name):
        pass


def main():
    machine = Machine()


if __name__ == "__main__":
    main()

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Samstag 26. Oktober 2019, 05:28
von snafu
Oder mit getattr() in etwa so:

Code: Alles auswählen

class Machine:
    def __init__(self):
        self._timers = {}
        for name in ("water", "oil", "air", "grease"):
            callback = getattr(self, f'_start_{name}_pump')
            self._timers[name] = QTimer(singleShot=True, timeout=callback)

    def _start_water_pump(self):
        pass

    def _start_oil_pump(self):
        pass

    def _start_air_pump(self):
        pass

    def _start_grease_pump(self):
        pass

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Samstag 26. Oktober 2019, 12:38
von Atalanttore
Danke für euren Code.
__blackjack__ hat geschrieben: Freitag 25. Oktober 2019, 19:43 @Atalanttore: Ja, aber ich würde da ja erst einmal fragen warum das Attribute sein müssen und warum Du das nicht einfach in ein Wörterbuch stecken kannst das die Namen auf die Timer abbildet. Also beispielsweise anstelle der Liste. Und dann nur noch eine `_start_pump()`-Methode die den Namen der Pumpe als Argument bekommt.
Natürlich könnte ich auch ein Wörterbuch nehmen, das die Namen auf die Timer abbildet. Mich würde nur interessieren, ob und wie man Bezeichner für Objekte aus Strings individuell zusammensetzen kann.

Gruß
Atalanttore

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Samstag 26. Oktober 2019, 13:05
von /me
Atalanttore hat geschrieben: Samstag 26. Oktober 2019, 12:38 Mich würde nur interessieren, ob und wie man Bezeichner für Objekte aus Strings individuell zusammensetzen kann.
Hier mal ein Beispiel.

Code: Alles auswählen

class Foo:
    def create_attribute(self, key, value):
        setattr(self, f'dynamic_{key}', value)

bar = Foo()
bar.create_attribute('baz', 42)
print(bar.dynamic_baz)
Aber wie gesagt: Tu es nicht! Genau für so etwas gibt es passende Datenstrukturen wie ein Dictionary. Im Endeffekt müsstest du ja doch wissen wie die Attribute heißen oder du baust dir die komplette Logik nach, die du mit einem Dictionary ohnehin bekommst.

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Samstag 26. Oktober 2019, 20:17
von Atalanttore
Ist die Abbildung auf ein Dictionary/Wörterbuch die pythonisch(t)e Art mehrere Objekte des gleichen Typs auf einmal zu erstellen?

Gruß
Atalanttore

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Samstag 26. Oktober 2019, 20:21
von snafu
Ein Dictionary ist als Datenstruktur auch in vielen anderen höheren Programmiersprachen bekannt (häufig auch Mapping genannt). Das ist keine spezielle Erfindung von Python. Auch muss man es nicht zwingend für Objekte gleicher Bauart verwenden.

Hier ist es aber sinnvoll, die Beziehung Name -> Methode darüber abzubilden. Wobei ich getattr() hier auch nicht falsch finde, falls man ohnehin auf der Klasseninstanz arbeitet...

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Samstag 26. Oktober 2019, 23:19
von __blackjack__
Die Frage bei den Attributen ist IMHO ob man da nur programmatisch drauf zugreift. Falls ja, stellt sich die Frage was da der Vorteil gegenüber einem dedizierten Wörterbuch sein soll. Denn auch die Attribute landen ja letztendlich in einem Wörterbuch (`__dict__` von dem Objekt), nur das sie sich da den Namensraum mit anderen ”Dingen” teilen. Warum macht das Sinn? Gibt es irgendwo Code wo der Programmierer tatsächlich im Quelltext über das Attribut zugreift in dem er die Namen selbst ausschreibt?

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Sonntag 27. Oktober 2019, 13:23
von kbr
@Atalanttore: Es war zwar nicht Deine Frage, aber ich würde die Strukturierung der Anwendung kritisch betrachten. Du hast bislang keine Maschine, sondern Pumpen. Vorschlag: modelliere zunächst die Pumpen. In einer späteren Machine-Klasse könntest Du dann Pumpen als Attribute anlegen (hier beispielhaft als dict umgesetzt):

Code: Alles auswählen

from PyQt5.QtCore import QTimer


PUMP_NAMES = ('water_pump, oil_pump', 'air_pump', 'grease_pump')


class Pump:

    def __init__(self, name):
        self.name = name
        self.timer = QTimer(...)
        ...
        
    def start(self):
        pass
        
        
pumps = {name: Pump(name) for name in PUMP_NAMES}

Re: Bezeichnername aus festem Präfix + String-Elementen aus einem Tupel zusammensetzen

Verfasst: Sonntag 27. Oktober 2019, 18:52
von Atalanttore
Danke für die vielen Erklärungen.

Gruß
Atalanttore