Seite 1 von 1

Methoden in Metaklassen

Verfasst: Samstag 28. Juli 2018, 11:06
von Antrazith
Noch eine Anfaengerfrage, es geht um Methoden in einer Metaklasse.

Der Interpreter meckert da (sicher mit Recht), dass da irgendwas nicht stimmt. Es geht eigentlich darum, dass die einige Methoden die in den echten Klassen definiert werden, Ergebnisse liefern sollen, die dann in einer allgemeinen Methode in der Metaklasse verwendet werden.

Bevor ich das Problem allerdings erklaeren kann, muss ich allerdings ein anderes Problem loesen. Der Kode den ich unten poste ist bei mir in der Datei "section.py" gewesen, und ist zu lang, um ihn hier zu posten. Ich hab daher die wichtigen Teile in eine neue Datei "test.py" ausgelagert.

Das erste Problem ist, dass ich den Kode nicht mehr in die Konsole laden kann.

Mit "from test import RectangularSection" bekomme ich einen ImportError: cannot import name 'RectangularSection' from 'test'. Das gleiche passiert, wenn ich den Kode 1:1 kopiere, ohne irgendwelche Aenderungen.

Code: Alles auswählen

import math
from abc import ABCMeta, abstractmethod


class Section(object):
    # https://jeffknupp.com/blog/2014/06/18/improve-your-python-python-classes-and-object-oriented-programming/
    __metaclass__ = ABCMeta

    height = 0

    @property
    def moment_of_inertia(self):
        """I"""
        return self.moment_of_inertia_y

    @property
    def radius_of_gyration(self):
        """i"""
        return self.radius_of_gyration_y

    @property
    def radius_of_gyration_y(self):
        """iy"""
        return math.sqrt(self.moment_of_inertia_y / self.area)

    @property
    def radius_of_gyration_z(self):  # public returns double
        """iz"""
        return math.sqrt(self.moment_of_inertia_z / self.area)

    @property
    def second_moment_of_area_y(self):
        """Wy"""
        return self.moment_of_inertia_y / self.z

    @abstractmethod
    def area(self):
        """A"""
        pass

    @abstractmethod
    def moment_of_inertia_y(self):
        """Iy"""
        pass

    @abstractmethod
    def moment_of_inertia_z(self):
        """Iz"""
        pass

    @abstractmethod
    def area_q(self):
        """Aq"""
        pass

    @abstractmethod
    def z(self):
        """max. distance from neutral axis to edge"""
        pass

    @abstractmethod
    def second_moment_of_area_z(self):
        """Wz"""
        pass


class RectangularSection(Section):
    """Rectangular-section"""

    def __init__(self, width, height):
        self.width = width
        self.height = height
        if self.width * self.height <= 0:
            raise Exception('Rectangular section: impossible geometry')

    @property
    def area(self):
        """A"""
        return self.height * self.width

    @property
    def area_q(self):
        """Aq"""
        return 5 / 6 * self.width * self.height  # Studienblatt 1.4

    @property
    def moment_of_inertia_y(self):
        """Iy"""
        return self.width * self.height ** 3 / 12

    @property
    def moment_of_inertia_z(self):
        """Iz"""
        return self.height * self.width ** 3 / 12

    @property
    def second_moment_of_area_z(self):
        """Wz"""
        return self.moment_of_inertia_z / self.width * 2

    @property
    def second_moment_of_area_y_plastic(self):
        """Wpy"""
        return self.width * self.height ** 2 / 4

    @property
    def z(self):
        """max. distance from neutral axis to edge"""
        return self.height / 2

    @property
    def s_y(self):
        return self.width * self.height / 2 * self.height / 4

Re: Methoden in Metaklassen

Verfasst: Samstag 28. Juli 2018, 11:42
von __blackjack__
Mach mal ganz am Anfang ein ``import test; print test`` und schau was da ausgegeben wird. Entweder ist das nicht das `test`-Modul das Du erwartest, oder die Klassendefinition wird aus irgend einem Grund nicht ausgeführt. Ausgelagert heisst in diesem Fall das `section`-Modul importiert das `test`-Modul und zwar ausschliesslich in diese Richtung? Also im `test`-Modul steht nicht auch noch ein ``import section`` oder ähnliches?

`abc` ist mir persönlich auch schon wieder zu ”javaesque”. Viel Schreibarbeit mit wenig bis keinem Nutzen. Wenn eine Klasse nicht alles implementiert was sie soll und das nicht auffällt, ist die Testabdeckung zu schlecht. So eine reine abstrakte Klasse macht wenn überhaupt in einer Bibliothek Sinn die man nicht selbst benutzt und da nicht zuletzt weil man die Dokumentation dann auch nicht in den abgeleiteten Klassen haben muss. Du hast das ja alles noch mal kopiert.

Re: Methoden in Metaklassen

Verfasst: Samstag 28. Juli 2018, 14:40
von Antrazith
Bingo.

Bei "import test" wird etwas anderes importiert, naemlich "AppData\Local\Programs\Python\Python37-32\Lib\test". Wenn ich meiner Datei einen anderen Namen gebe, funktioniert der import wieder.
Note to self - Testdateien nicht mit "test.py" bezeichnen.

Was meine eigentliche Frage betrifft, so hat sich die zur Zeit eruebrigt. Ich kann den Fehler naemlich nicht mehr reproduzieren.

Trotzdem vielen Dank.

Re: Methoden in Metaklassen

Verfasst: Samstag 28. Juli 2018, 15:26
von __blackjack__
@Antrazith: Man kann eigene Testdateien ruhig ``test.py`` nennen, aber dann sollten sie besser in einem Package stecken. Das hatte ich beim Thema aufteilen von Modulen ja bereits geschrieben: Wenn es mehr als ein Modul ist, fasse ich das zu einem Package zusammen, damit auf ”oberster Ebene” maximal ein Name, der des Package, mit irgend etwas anderem ”kollidieren” kann.

Noch eine kleine Anmerkung zum Betreff und der Formulierung im ersten Beitrag: Du hast hier keine Methoden in einer Metaklasse. `Section` ist eine normale Klasse. Die Metaklasse ist `ABCMeta`, da hast Du aber keine Fragen zu deren Methoden, denn von denen verwendest Du explizit gar keine.

Re: Methoden in Metaklassen

Verfasst: Samstag 28. Juli 2018, 22:06
von Antrazith
Falsche Formulierung von mir, sollte nicht Metaklasse heissen, sondern abstrakte Klasse (oder Klasse mit abstrakten Methoden).

Danke auch fuer den Hinweis mit den Package. Ich dachte, ein Projekt das ich in PyCharm anlege ist das Package. Aber wie ich sehe, ist dem nicht so. Ich kann unter dem Projekt auch noch Packages anlegen.

Re: Methoden in Metaklassen

Verfasst: Sonntag 29. Juli 2018, 07:34
von ThomasL
https://www.youtube.com/watch?v=BPC-bGd ... gmkwzjNLjP
Kann ich dir empfehlen, hat mir auch geholfen. 8)