Generics und Metaclass-Problem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
christhis
User
Beiträge: 3
Registriert: Sonntag 27. Mai 2018, 23:09

Hallo,

ich wollte fragen, ob irgendwer hier einen halbwegs brauchbaren Trick/Hack kennt, um Mehrfachvererbung mit einer Generic-Klasse durchzuführen.

Heißt: Ich möchte gerne

Code: Alles auswählen

T = TypeVar("T")
class A(Generic[T]):
    pass

class B(IrgendeineAndereKlasse,A):
    pass
verwenden können, ohne die Fehlermeldung

Code: Alles auswählen

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
zu bekommen. Das Kernproblem ist mir bekannt, aber vielleicht gibt es ja einen Weg, wie man das doch irgendwie umgehen kann.

Vielen Dank bereits im Voraus :-)
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

Tritt der Fehler bei dir auf, wenn du die Klassen so wie oben definierst, oder wenn du ein Objekt von `B` instanziierst? Konnte den Fehler nicht nachstellen:

Code: Alles auswählen

>>> from typing import Generic
>>> from typing import TypeVar
>>>
>>> class IrgendeineAndereKlasse:
...     pass
... 
>>> T = TypeVar("T")
>>> class A(Generic[T]):
...     pass
... 
>>> class B(IrgendeineAndereKlasse,A):
...     pass
... 
>>> x = B()
>>> isinstance(x, A)
True
>>> isinstance(x, B)
True
>>> isinstance(x, IrgendeineAndereKlasse)
True
When we say computer, we mean the electronic computer.
Benutzeravatar
kbr
User
Beiträge: 1507
Registriert: Mittwoch 15. Oktober 2008, 09:27

@christhis: mit Python 3.5 und 3.6 kann ich den Fehler auch nicht nachvollziehen. Ansonsten könnte die Lösung darin bestehen, B eine Metaklasse zuzuweisen, die eine Subklasse der Metaklassen von A und IrgendeineAndereKlasse ist. Das habe ich in der Praxis aber noch nie anwenden brauchen (und auch noch nicht ausprobiert).
christhis
User
Beiträge: 3
Registriert: Sonntag 27. Mai 2018, 23:09

Hallo,
vielen Dank schon einmal für eure Antworten. Das Problem tritt immer dann auf, wenn B eine Klasse mit anderer Metaklasse ist - also zum Beispiel aus PyQt. Sorry, hatte vergessen, das dazu zu erwähnen.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

`IrgendeineAndereKlasse` und `A` haben anscheinend Metaklassen definiert, von denen sie abgeleitet werden.

Dazu folgendes Beispiel:

Code: Alles auswählen

>>> class A(type):
...     pass
... 
>>> class B(type):
...     pass
... 
>>> class C(metaclass=A):
...     pass
... 
>>> class D(metaclass=B):
...     pass
... 
>>> 
>>> class N(C,D):
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Was du hier tun kannst ist eine Klasse zu definieren, die direkt von A, und B erbt, in deinem Falle also nachforschen welche Metaklassen für deine Klassen `A` und `IrgendeineAndereKlasse` definiert sind.

Die Klasse `AB` erbt von den beiden Basisklassen A und B:

Code: Alles auswählen

>>> class AB(A, B):
...     pass
Anschließend kannst du `AB` als deine Metaklasse definieren:

Code: Alles auswählen

>>> class N(A, B):
...     __metaclass__ = AB
Ich hoffe dein Problem damit richtig adressiert zu haben.

EDIT: hier nochmal das selbe in Grün -> https://stackoverflow.com/questions/655 ... 47#7314847
When we say computer, we mean the electronic computer.
christhis
User
Beiträge: 3
Registriert: Sonntag 27. Mai 2018, 23:09

Wow, ich bedanke mich vielmals! Ich habe immer größte Freude daran, schön abstrakten und auch komplexen Code zu schreiben. Und da sind diese generischen Objekte oft eine bequeme Erleichterung - nicht zuletzt auch, was Codevervollständigung angeht :-).
Vielen Dank!
Antworten