2016-03-24 7 views
0

Ich versuche, eine Klasse zu schreiben, die von mmap erbt wie folgt:Warum hat mein __init__ in der Vererbung keinen Vorrang?

from mmap import mmap 

class SBFMap(mmap): 
    def __init__(self, filename): 
     f=open(filename, 'rb') 
     fn = f.fileno() 
     super().__init__(fn, 0, access = mmap.ACCESS_READ) 

Wie Sie sich vorstellen können, ein Teil der Funktionalität meiner Klasse ist die Datei zum Öffnen/Schließen in meinem __init__ zu verstecken. Ich versuche dann, wie so ein SBFMap Objekt zu erhalten:

from SBFMap import SBFMap 
filename = "name\of\file" 
mymap = SBFMap(filename) 

ich diesen Fehler:

File "SBFReader.py", line 22 in <module> main() 
File "SBFReader.py", line 7, in main mymap=SBFMap(filename) 
TypeError: an integer is required (got type str) 
Press any key to continue . . . 

Es ist wie anstelle von Python erscheint SBFMap der __init__ Aufruf und ließ mich Mmap des __init__ rufen, wenn ich bereit bin zu, versucht Python, mmap __init__ aufzurufen. Wie behebe ich das?

+2

ist das ein Tippfehler? 'f = open (Dateiname, 'rb)' Bitte kopieren Sie auch den kompletten Stacktrace. – Markon

+0

Zwei mögliche Lösungen: Verwenden Sie Delegierung statt Vererbung. Und für einige Klassen, z.B. str oder datetime, Sie können __init__ nicht überladen. Ich habe die genauen Details vergessen, aber Sie können stattdessen "__new__" versuchen. – deets

+0

@Markon Ja, das war ein Tippfehler, der jetzt behoben ist. Ich habe auch den Stack-Trace hinzugefügt. –

Antwort

0

Da gibt es zwei verschiedene spezielle Methoden, die bei der Erstellung von Objekten beteiligt sind: __new__, die erstellt und Objekt und __init__, die es konfiguriert.

Im Allgemeinen verwenden Python-Mutable-Klassen einen Standardwert __new__, der den Aufruf von object.__new__ beendet, um ein neues Python-Objekt zu erstellen und alle Argumente zu akzeptieren.

Aber einige Klassen (vor allem nicht veränderbare) überschreiben __new__. In diesem Fall müssen Sie implementieren Sie eine in Ihrer Klasse und rufen Sie die eine aus der übergeordneten Klasse mit der erwarteten Signatur. Nachdem das Objekt erstellt wurde, ruft Python schließlich die __init__ Methode für das tatsächliche Objekt auf.

Hier sollten Sie tun:

class SBFMap(mmap): 
    def __new__(cls, filename): 
     f=open(filename, 'rb') 
     fn = f.fileno() 
     return super().__new__(cls, fn, 0, access = mmap.ACCESS_READ) 

Aber Vorsicht, wenn die Elternklasse seiner __init__ erwarteten Methode aufgerufen werden, würden Sie noch in Ihrer Klasse implementieren müssen, die die Eltern rufen __init__ mit der erwarteten Signatur .

+0

Genau das, was ich brauchte. Die __new__ Methode ist zunächst etwas verwirrend. –