0

I am trying to write a class that inherits from mmap as follows:

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)

As you can guess, part of my class's functionality is to hide the file opening/closing inside my __init__. i then try to get an SBFMap object like so:

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

I get this error:

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 . . . 

It appears like instead of python calling SBFMap's __init__ and letting me call mmap's __init__ when I'm ready to, python is trying to call mmap's __init__. How do I fix this?

5
  • 2
    is this a typo? f=open(filename, 'rb) Please copy/paste also the full stacktrace. Commented Mar 24, 2016 at 14:42
  • Two possible solutions: use delegation instead of inheritance. And for some classes, e.g. str or datetime, you can't overload init. I forgot the exact details, but you can try __new__ instead. Commented Mar 24, 2016 at 14:47
  • @Markon Yes, that was a typo, which is now fixed. I also added the stack trace. Commented Mar 24, 2016 at 14:57
  • 3
    The error is indeed being raised by SBFMap.__new__. Note that mmap is implemented in a shared library in C, not pure Python, and it does not actually have an __init__ method. Commented Mar 24, 2016 at 15:00
  • Read about __new__. Commented Mar 24, 2016 at 15:08

1 Answer 1

1

Because there are two different special methods that are involved in object creation: __new__ that creates and object and __init__ that configures it.

Generally Python mutable classes use a default __new__ that ends calling object.__new__ to create a new python object and accept any arguments.

But some classes (notably non mutable ones) do override __new__. In that case, you must implement one in your class and call the one from the parent class with the expected signature.

Once the object will be constructed, Python will eventually call the __init__ method for the actual object.

Here you should do:

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

But beware, if the parent class expected its __init__ method to be called, you would still have to implement one in your class that calls the parent __init__ with the expected signature.

Sign up to request clarification or add additional context in comments.

1 Comment

Exactly what I needed. The new method is a bit confusing at first.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.