7 Stimmen

Das Vererbungsverhalten von set und frozenset scheint sich zu unterscheiden

Kann jemand das folgende Verhalten erklären?

class derivedset1(frozenset):
    def __new__(cls,*args):
        return frozenset.__new__(cls,args)  

class derivedset2(set):
    def __new__(cls,*args):
        return set.__new__(cls,args)    

a=derivedset1('item1','item2') # WORKS 
b=derivedset2('item1','item2') # DOESN'T WORK

Traceback (most recent call last):
  File "inheriting-behaviours.py", line 12, in <module>
    b=derivedset2('item1','item2') # DOESN'T WORK
TypeError: derivedset2 expected at most 1 arguments, got 2

Es überrascht mich, dass man den Konstruktor einer eingefrorenen Menge ändern kann, während dies für den Konstruktor einer veränderbaren Menge nicht möglich ist.

4voto

phihag Punkte 261131

Von der Python-Dokumentation :

Wenn __new__() gibt eine Instanz von cls dann wird die neue Instanz __init__ ()-Methode wird wie folgt aufgerufen __init__(self[, ...]) , wobei self ist die neue Instanz und die verbleibenden Argumente sind die gleichen, die an __new__() .

set.__init__ benötigt nur ein Argument, eine Iterable, die den anfänglichen Mengeninhalt angibt. Daher sollten Sie einen eigenen Initialisierer hinzufügen, der alle zusätzlichen Argumente entgegennimmt und sie als anfängliche Set-Werte bereitstellt:

class derivedset2(set):
    def __new__(cls,*args):
        return set.__new__(cls,*args)

    def __init__(self, *initial_values):
        set.__init__(self, initial_values)

Beachten Sie, dass Sie die __init__ und von der Umsetzung absehen __new__ es sei denn, Sie wollen Objekt-Caching, Singletons oder ähnliche seltsame Dinge implementieren. Ihr Subclassing funktioniert für frozenset gerade weil frozenset tut vom Objekt-Caching profitieren, d.h. der Python-Interpreter benötigt nur eine frozenset Instanz für zwei frozenset Objekte mit demselben Inhalt.

Im Allgemeinen sollten Sie davon absehen, eingebaute Klassen in Unterklassen zu unterteilen, insbesondere wenn Ihre Semantik nicht kompatibel ist (in diesem Fall, set([]) y derivedset2([]) völlig unterschiedliche Ergebnisse liefern).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X