[Tutor] Modify inherited methods
spir ☣
denis.spir at gmail.com
Wed Apr 28 10:45:16 CEST 2010
On Wed, 28 Apr 2010 07:53:06 +0100
Walter Wefft <walterwefft at googlemail.com> wrote:
> Steven D'Aprano wrote:
> > And for guru-level mastery, replace to call to dict.__init__ with ...
> nothing at all, because dict.__init__ doesn't do anything.
> >
> >
> >
>
> (Sorry, should have sent to list).
>
> I don't understand this - it must do something:
>
> class MyDict1(dict):
>
> def __init__(self, *args, **kw):
> pass
>
> class MyDict2(dict):
>
> def __init__(self, *args, **kw):
> dict.__init__(self, *args, **kw)
>
>
> d = MyDict1(y=2)
> print d
> {}
>
> d = MyDict2(y=2)
> print d
> {'y': 2}
>
> d = MyDict1({'x': 3})
> print d
> {}
>
> d = MyDict2({'x': 3})
> print d
> {'x': 3}
>
> Behaviour is different depending on whether you call the superclass
> __init__ or not.
>
> ?
Hem... this is a rather obscure point (I personly have it wrong each time I need to subtype builtin types). Maybe you find some enlightenment in the following code:
===============================
class MyDict0(dict):
pass
class MyDict1(dict):
def __init__(self, *args, **kw):
pass
class MyDict2(dict):
def __init__(self, *args, **kw):
dict.__init__(self, *args, **kw)
===============================
d0 = MyDict0(a=1) ; d1 = MyDict1(a=1) ; d2 = MyDict2(a=1)
print d0,d1,d2 # ==> {'a': 1} {} {'a': 1}
In case you do not define any custom __init__ *at all*, dict will transparently feed an instance of your type with provided entries, if any. If you define one, and don't feed the collection yourself, you need to call dict's __init__ to do it for you.
This behaviour allows having custom params at init:
===============================
class MyDict(dict):
def __init__(self, name="", **entries):
self.name = name
dict.__init__(self, **entries)
def __str__(self):
return "%s:%s" %(self.name,dict.__str__(self))
d = MyDict(name="XYZ", a=1,b=2,c=3)
print d # ==> XYZ:{'a': 1, 'c': 3, 'b': 2}
===============================
But all this does not apply to "atomic" builtin types such as int:
===============================
class MyInt0(int):
pass
class MyInt1(int):
def __init__(self, *args):
pass
class MyInt2(int):
def __init__(self, *args):
int.__init__(self, *args)
i0 = MyInt0(1) ; i1 = MyInt1(1) ; i2 = MyInt2(1)
print i0,i1,i2 # ==> 1 1 1
===============================
This runs by me with a message from the compiler: "DeprecationWarning: object.__init__() takes no parameters" (about the call to int.__init__).
I would like to understand the implementation and the reason for this difference.
This means one cannot customize the initialisation of a subtype of int like is done above for a subtype of dict:
===============================
class MyInt(int):
def __init__(self, value=0, name=""):
self.name = name
int.__init__(self, value)
def __str__(self):
return "%s:%s" %(self.name,int.__str__(self))
#~ i = MyInt(name="XYZ", value=3)
i = MyInt(3, "XYZ")
print i # ==> TypeError: an integer is required
===============================
(Keyword parameters will also be rejected.) This is due to the implicit execution of the builtin constructor, which requires definite parameters (here a value and possibly a base).
More info on this topic welcome :-)
Denis
________________________________
vit esse estrany ☣
spir.wikidot.com
More information about the Tutor
mailing list