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?
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>>
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With