{"id":3049,"date":"2025-09-21T05:57:15","date_gmt":"2025-09-21T03:57:15","guid":{"rendered":"https:\/\/davidka.net\/en\/?p=3049"},"modified":"2025-09-22T04:21:12","modified_gmt":"2025-09-22T02:21:12","slug":"python-classes-context-managers","status":"publish","type":"post","link":"https:\/\/de.davidka.net\/de\/2025\/09\/21\/python-classes-context-managers\/","title":{"rendered":"Klassen in Python, OOP und Kontextmanager: Vollst\u00e4ndiger Leitfaden"},"content":{"rendered":"\n<p class=\"has-neve-link-color-color has-text-color has-link-color has-medium-font-size wp-elements-0a7c92e6fbc72bd5e642a8c85548c700 wp-block-paragraph\">Dieser Leitfaden behandelt <strong>objektorientierte Programmierung (OOP)<\/strong> in Python und <strong>Kontextmanager<\/strong>, einschlie\u00dflich praktischer Beispiele zur <strong>Erfassung von stdout\/stderr<\/strong> und Verwendung des <strong>Tee-Musters<\/strong>, um Ausgaben gleichzeitig anzuzeigen und zu erfassen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Klassen in Python<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Klassen sind ein zentraler Mechanismus der <strong>OOP<\/strong>. Eine Klasse ist eine <strong>Vorlage<\/strong>, um Objekte mit <strong>Attributen<\/strong> (Daten) und <strong>Methoden<\/strong> (Funktionen) zu erstellen. Objekte, die aus einer Klasse erstellt werden, hei\u00dfen <strong>Instanzen<\/strong>. Klassen helfen, Code zu strukturieren, die Wiederverwendbarkeit zu erh\u00f6hen und die Wartung zu erleichtern.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Aufbau einer Klasse<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">class ClassName:\n    def __init__(self, param1, param2):\n        self.param1 = param1\n        self.param2 = param2\n\n    def method(self):\n        return f&#039;{self.param1} und {self.param2}&#039;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Wichtige Punkte:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code class=\"\" data-line=\"\">__init__<\/code>: Konstruktor zum Initialisieren von Objektattributen.<\/li>\n\n\n\n<li><code class=\"\" data-line=\"\">self<\/code>: Referenz auf die aktuelle Instanz.<\/li>\n\n\n\n<li>Attribute: werden \u00fcber <code class=\"\" data-line=\"\">self<\/code> definiert und sind in allen Methoden verf\u00fcgbar.<\/li>\n\n\n\n<li>Methoden: arbeiten mit den Daten des Objekts.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Objekte erstellen<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">class Car:\n    def __init__(self, make, model, year):\n        self.make = make\n        self.model = model\n        self.year = year\n\n    def description(self):\n        return f&#039;{self.year} {self.make} {self.model}&#039;\n\nmy_car = Car(&#039;Toyota&#039;, &#039;Corolla&#039;, 2020)\nprint(my_car.description())  # Ausgabe: 2020 Toyota Corolla\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Methodenarten<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Instanzmethoden<\/strong> \u2014 arbeiten auf Objekten (<code class=\"\" data-line=\"\">self<\/code>).<\/li>\n\n\n\n<li><strong>Klassenmethoden<\/strong> \u2014 arbeiten auf der Klasse (<code class=\"\" data-line=\"\">cls<\/code>) \u00fcber <code class=\"\" data-line=\"\">@classmethod<\/code>.<\/li>\n\n\n\n<li><strong>Statische Methoden<\/strong> \u2014 unabh\u00e4ngig von Instanz und Klasse (<code class=\"\" data-line=\"\">@staticmethod<\/code>).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Vererbung<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">class Animal:\n    def speak(self):\n        return &#039;Tierlaut&#039;\n\nclass Dog(Animal):\n    def speak(self):\n        return &#039;Wuff&#039;\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Polymorphismus<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">class Cat(Animal):\n    def speak(self):\n        return &#039;Miau&#039;\n\ncat = Cat()\nprint(cat.speak())  # Ausgabe: Miau\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Dieselbe Methode funktioniert je nach Objekttyp unterschiedlich.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Kapselung<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">class Car:\n    def __init__(self, make, model):\n        self._make = make  # Gesch\u00fctztes Attribut\n        self._model = model\n\n    def get_make(self):\n        return self._make\n\n    def set_make(self, make):\n        self._make = make\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Magische Methoden und Destruktor<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">class Point:\n    def __init__(self, x, y):\n        self.x = x\n        self.y = y\n\n    def __repr__(self):\n        return f&#039;Point({self.x}, {self.y})&#039;\n\np = Point(3, 4)\nprint(p)  # Ausgabe: Point(3, 4)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">ASCII-Diagramm: Vererbung und Polymorphismus<\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">       \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n       \u2502 Animal  \u2502\n       \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n       \u2502 speak() \u2502\n       \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n            \u25b2\n    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n    \u2502                \u2502\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510      \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Dog    \u2502      \u2502  Cat    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\u2502 speak() \u2502      \u2502 speak() \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518      \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Kontextmanager in Python<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kontextmanager erm\u00f6glichen <strong>automatisches Zuweisen und Freigeben von Ressourcen<\/strong>, auch bei Fehlern.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Verwendung von <code class=\"\" data-line=\"\">@contextmanager<\/code><\/h3>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">from contextlib import contextmanager\n\n@contextmanager\ndef my_context():\n    print(&quot;Betritt den Kontext&quot;)\n    try:\n        yield &quot;Ressource&quot;\n    finally:\n        print(&quot;Verl\u00e4sst den Kontext&quot;)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verwendung:<\/p>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">with my_context() as res:\n    print(&quot;Im Kontext:&quot;, res)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Erfassen von stdout\/stderr und Tee<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Python erlaubt das Erfassen von stdout, stderr oder beidem und die <strong>gleichzeitige Anzeige und Erfassung<\/strong> mit dem Tee-Muster.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Vollst\u00e4ndiges Beispiel: <code class=\"\" data-line=\"\">oop_and_context.py<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code line-numbers\"><code class=\" language-python\" data-line=\"\">&quot;&quot;&quot;\noop_and_context.py\n\nBeispiele f\u00fcr Klassen, OOP-Prinzipien und Kontextmanager in Python.\nEnth\u00e4lt:\n- Definition von Klassen, Vererbung, Polymorphismus, Kapselung\n- Instanz-, Klassen- und statische Methoden\n- Magische Methoden und Destruktor\n- Kontextmanager mit @contextmanager\n- Erfassen von stdout, stderr und kombiniert\n- Tee-Muster: gleichzeitig anzeigen und erfassen\n- Klassenbasierter Kontextmanager\n&quot;&quot;&quot;\n\nimport sys\nimport io\nfrom contextlib import contextmanager\n\n# ==========================\n# Teil 1: Klassen und OOP\n# ==========================\n\nclass Animal:\n    &quot;&quot;&quot;Basisklasse f\u00fcr Tiere.&quot;&quot;&quot;\n    def speak(self):\n        return &#039;Tierlaut&#039;\n\nclass Dog(Animal):\n    def speak(self):\n        return &#039;Wuff&#039;\n\nclass Cat(Animal):\n    def speak(self):\n        return &#039;Miau&#039;\n\nclass Car:\n    &quot;&quot;&quot;Beispiel f\u00fcr Kapselung.&quot;&quot;&quot;\n    def __init__(self, make, model, year=None):\n        self._make = make\n        self._model = model\n        self.year = year\n\n    def get_make(self):\n        return self._make\n\n    def set_make(self, make):\n        self._make = make\n\n    def description(self):\n        if self.year:\n            return f&#039;{self.year} {self._make} {self._model}&#039;\n        return f&#039;{self._make} {self._model}&#039;\n\nclass Point:\n    &quot;&quot;&quot;Klasse mit magischen Methoden.&quot;&quot;&quot;\n    def __init__(self, x, y):\n        self.x = x\n        self.y = y\n\n    def __repr__(self):\n        return f&#039;Point({self.x}, {self.y})&#039;\n\n# ==========================\n# Teil 2: Kontextmanager\n# ==========================\n\n@contextmanager\ndef my_context():\n    print(&quot;Betritt den Kontext&quot;)\n    try:\n        yield &quot;Ressource&quot;\n    finally:\n        print(&quot;Verl\u00e4sst den Kontext&quot;)\n\n@contextmanager\ndef capture_stdout():\n    old_stdout = sys.stdout\n    sys.stdout = buffer = io.StringIO()\n    try:\n        yield buffer\n    finally:\n        sys.stdout = old_stdout\n\n@contextmanager\ndef capture_stderr():\n    old_stderr = sys.stderr\n    sys.stderr = buffer = io.StringIO()\n    try:\n        yield buffer\n    finally:\n        sys.stderr = old_stderr\n\n@contextmanager\ndef capture_output():\n    old_stdout = sys.stdout\n    old_stderr = sys.stderr\n    sys.stdout = sys.stderr = buffer = io.StringIO()\n    try:\n        yield buffer\n    finally:\n        sys.stdout = old_stdout\n        sys.stderr = old_stderr\n\nclass Tee(io.StringIO):\n    &quot;&quot;&quot;Sichtbare Ausgabe und gleichzeitige Erfassung.&quot;&quot;&quot;\n    def __init__(self, original):\n        super().__init__()\n        self.original = original\n\n    def write(self, text):\n        self.original.write(text)\n        super().write(text)\n\n    def flush(self):\n        self.original.flush()\n\n@contextmanager\ndef capture_stdout_tee():\n    old_stdout = sys.stdout\n    sys.stdout = tee = Tee(old_stdout)\n    try:\n        yield tee\n    finally:\n        sys.stdout = old_stdout\n\n# ==========================\n# Teil 3: Klassenbasierter Kontextmanager\n# ==========================\n\nclass OutputCapture:\n    &quot;&quot;&quot;Klassenbasierter Kontextmanager zum Erfassen von stdout.&quot;&quot;&quot;\n    def __init__(self):\n        self._buffer = io.StringIO()\n        self._old_stdout = None\n\n    def __enter__(self):\n        self._old_stdout = sys.stdout\n        sys.stdout = self._buffer\n        return self._buffer\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        sys.stdout = self._old_stdout\n        return False  # Ausnahmen weitergeben\n\n# ==========================\n# Teil 4: Demonstrationen\n# ==========================\n\ndef demo_classes():\n    print(&quot;\\n--- Klassen-Demonstration ---&quot;)\n    dog = Dog()\n    cat = Cat()\n    print(&quot;Hund sagt:&quot;, dog.speak())\n    print(&quot;Katze sagt:&quot;, cat.speak())\n\n    my_car = Car(&#039;Toyota&#039;, &#039;Corolla&#039;, 2020)\n    print(&quot;Autobeschreibung:&quot;, my_car.description())\n    my_car.set_make(&#039;Honda&#039;)\n    print(&quot;Aktualisierte Marke:&quot;, my_car.get_make())\n\n    point = Point(3, 4)\n    print(&quot;Punkt:&quot;, point)\n\ndef demo_context_managers():\n    print(&quot;\\n--- Kontextmanager-Demonstration ---&quot;)\n    with my_context() as res:\n        print(&quot;Im Kontext:&quot;, res)\n\nwith capture_stdout() as out:\n    print(&quot;stdout erfasst&quot;)\nprint(&quot;Buffer:&quot;, out.getvalue().strip())\n\nwith capture_stderr() as err:\n    print(&quot;Geht zu stdout&quot;)\n    sys.stderr.write(&quot;Fehlermeldung\\n&quot;)\nprint(&quot;Fehler:&quot;, err.getvalue().strip())\n\nwith capture_output() as out_all:\n    print(&quot;Stdout in kombinierter Erfassung&quot;)\n    sys.stderr.write(&quot;Stderr in kombinierter Erfassung\\n&quot;)\nprint(&quot;Kombinierte Ausgabe:&quot;, out_all.getvalue().strip())\n\nwith capture_stdout_tee() as tee_out:\n    print(&quot;Ausgabe sichtbar UND erfasst mit Tee&quot;)\nprint(&quot;Tee Buffer:&quot;, tee_out.getvalue().strip())\n\nwith OutputCapture() as class_capture:\n    print(&quot;Erfassung mit klassenbasiertem Kontextmanager&quot;)\nprint(&quot;Buffer des Klassenmanagers:&quot;, class_capture.getvalue().strip())\n\n# ==========================\n# Hauptausf\u00fchrung\n# ==========================\n\nif name == &quot;main&quot;:\ndemo_classes()\ndemo_context_managers()\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Dieser Leitfaden behandelt objektorientierte Programmierung (OOP) in Python und Kontextmanager, einschlie\u00dflich praktischer Beispiele zur Erfassung von stdout\/stderr und Verwendung des Tee-Musters, um Ausgaben gleichzeitig anzuzeigen und zu erfassen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[],"tags":[],"class_list":["post-3049","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/posts\/3049","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/comments?post=3049"}],"version-history":[{"count":0,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/posts\/3049\/revisions"}],"wp:attachment":[{"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/media?parent=3049"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/categories?post=3049"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/de.davidka.net\/de\/wp-json\/wp\/v2\/tags?post=3049"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}