On Wed, 28 Apr 2010 07:53:06 +0100 Walter Wefft <walterwe...@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 _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor