'Subclass from instance of another class

I am trying to add functionality (new method) to temporary file. Usually, the file is called by tempfile.NamedTemporaryFile(*args, **kwargs), but NamedTemporaryFile is a function, not a class. I don't want to skip this function. I want to let the function create the file but also add my method.

I tried the following (among other stuff), but my methods were not recognized:

import tempfile
from tempfile import _TemporaryFileWrapper

class TempFile(_TemporaryFileWrapper):
    def __new__(cls, *args, **kwargs):
        ret= tempfile.NamedTemporaryFile(args, kwargs)
        self = cls.__init__(ret)
        return self

    def __init__(self, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None):
        print('__init__')
    
    def MyMethod(self):
        print('my method works')

any ideas?



Solution 1:[1]

You could subclass tempfile._TemporaryFileWrapper, then monkey-patch the name so that NamedTemporaryFile returns an instance of your subclass.

class TempFile(tempfile._TemporaryFileWrapper):
    ...

tempfile._TemporaryFileWrapper = TempFile

x = NamedTemporaryFile(...)

This should work (untested), since NamedTemporaryFile is hard-coded to return an instance of _TemporaryFileWrapper, whatever that name is bound to.

Solution 2:[2]

Ok, This seems to do the trick, it just doesn't really feel right. If some one have better idea I will happily accept their answer.

import tempfile
class TempFile(object):
    def __init__(self, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None):
        t = tempfile.NamedTemporaryFile(mode)
        self.file = t
        # These are actually not necessary, but they make it it easier with auto-complete in the IDE.
        self.name= t.name
        self.close = t.close
        self.write = t.write

    def __get__(self):
        return self.file

    def MyMethod(self):
        print('my method works')

if __name__ == '__main__':
    t = TempFile(mode='w')
    t2 = tempfile.NamedTemporaryFile(mode='w')
    print(t.name)
    print(t2.name)
    t.MyMethod()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chepner
Solution 2 Dror Paz