Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: object.__init__() takes no parameters

I'm stumped by this inheritance behavior in Python. As far as I can tell the super class constructor is being called correctly although the syntax differs from 2.7 to 3.5.

Python 2.7.11 |Continuum Analytics, Inc.| (default, Dec  6 2015, 18:08:32) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> 
>>> import pandas as pd
>>> class MyTimestamp(pd.Timestamp):
...     def __init__(self, arg, **kwargs):
...         super(MyTimestamp, self).__init__(arg, **kwargs)
... 
>>> a=MyTimestamp(1312342152423, unit='us')
>>> a
Timestamp('1970-01-16 04:32:22.152423')

Using a Python 3.5.1 interpreter I get the following result, both have the same version of Pandas installed (0.18.0) but I believe it is more a Python inheritance thing.

Python 3.5.1 |Continuum Analytics, Inc.| (default, Dec  7 2015, 11:16:01) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import pandas as pd
>>> class MyTimestamp(pd.Timestamp):
...     def __init__(self, arg, **kwargs):
...         super().__init__(arg, **kwargs)
... 
>>> a=MyTimestamp(1312342152423, unit='us')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__

TypeError: object.__init__() takes no parameters

The mro for MyTimestamp specifies:

(<class '__main__.MyTimestamp'>, 
 <class 'pandas.tslib.Timestamp'>, 
 <class 'pandas.tslib._Timestamp'>, 
 <class 'datetime.datetime'>, 
 <class 'datetime.date'>, 
 <class 'object'>)

so object is not the next class in the resolution order. Where is this error coming from and perhaps more to the point what am I doing incorrectly that I can change to fix the issue?

like image 601
Paul Joireman Avatar asked Mar 12 '23 10:03

Paul Joireman


2 Answers

I don't think this has anything to do with your use of super. If you test that same code with another class, it works fine. E.g.:

class Foo:
    def __init__(self, arg):
        print ("Foo",arg)

class Bar(Foo):
    def __init__(self, arg):
        super().__init__(arg)

b=Bar(1) #Prints "Foo 1"

It seems like Pandas is doing something odd with that Timestamp class, and I can't exactly figure out what, but it's something to do with C extensions:

https://github.com/pydata/pandas/blob/master/pandas/tslib.pyx#L222 https://github.com/pydata/pandas/blob/master/pandas/tslib.pyx#L881

Anyway, the following seems to work as intended:

import pandas

class MyTimestamp(pandas.Timestamp):
    def __init__(self, arg, **kwargs):
        pass

a=MyTimestamp(1312342152423, unit='us') #Timestamp('1970-01-16 04:32:22.152423')

Also, take a look at the variation in output between these two definitions:

import pandas

class MyTimestamp(pandas.Timestamp):
    def __init__(self, arg, **kwargs):
        print(super().__init__)

class Foo:
    def __init__(self, arg):
        print ("Foo",arg)

class Bar(Foo):
    def __init__(self, arg):
        print(super().__init__)

a=MyTimestamp(1612342152423, unit='us')
b=Bar(1)

Which yields:

<method-wrapper '__init__' of MyTimestamp object at 0x04981AD0>
<bound method Foo.__init__ of <__main__.Bar object at 0x033C2070>>
like image 161
Kal Zekdor Avatar answered Mar 24 '23 08:03

Kal Zekdor


The problem is that in this case, you should be overriding __new__. It seems panda's Timestamp is immutable (like datetime that it inherits from) so it's __init__ method does nothing.

The way you wrote it works fine with python 3. Substitute pd.Timestamp with your own custom class and you will see super gets called normally.

Similar problem and solution: Python: how to extend datetime.timedelta

like image 31
fips Avatar answered Mar 24 '23 08:03

fips