Re: [Tutor] Modify inherited methods
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. ? ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
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
Re: [Tutor] Modify inherited methods
spir ☣ wrote: 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} You reiterate my point. To say that dict.__init__ can be omitted in a subclass's __init__ with no effect, is not a correct statement. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
On Wed, 28 Apr 2010 04:53:06 pm Walter Wefft 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. [...] Behaviour is different depending on whether you call the superclass __init__ or not. ? Fascinating... it seems that you are correct. Just goes to show, you can be programming in Python for well over a decade and still learn something new. Believe it or not, I did test the behaviour before posting, but obviously my tests were faulty! -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
Emile van Sebille wrote: On 4/28/2010 3:20 AM Walter Wefft said... spir ☣ wrote: On Wed, 28 Apr 2010 07:53:06 +0100 Walter Wefft walterwe...@googlemail.com wrote: snip === 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} You reiterate my point. To say that dict.__init__ can be omitted in a subclass's __init__ with no effect, is not a correct statement. It wasn't the omitted case that exhibits the difference. When sub-classing, any methods omitted defer to the parent's version so the init from the dict parent happened. omitted in a subclass's __init__, ie. a *call* to the superclass's method ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
On 4/28/2010 9:32 AM Walter Wefft said... Emile van Sebille wrote: On 4/28/2010 3:20 AM Walter Wefft said... You reiterate my point. To say that dict.__init__ can be omitted in a subclass's __init__ with no effect, is not a correct statement. It wasn't the omitted case that exhibits the difference. When sub-classing, any methods omitted defer to the parent's version so the init from the dict parent happened. omitted in a subclass's __init__, ie. a *call* to the superclass's method You're right. Failure to read on my part. Sorry. Emile ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
On Wednesday April 28 2010 13:04:30 Steven D'Aprano wrote: On Wed, 28 Apr 2010 04:53:06 pm Walter Wefft 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. [...] Behaviour is different depending on whether you call the superclass __init__ or not. ? Fascinating... it seems that you are correct. Just goes to show, you can be programming in Python for well over a decade and still learn something new. You probably thought of tuple, where __init__ really does nothing. Tuple instances are created by __new__. Eike. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
Thank you all. One tangentially related question: what does (self, *args, **kwargs) actually mean? How does one reference variables given to a function that accepts these inputs? Colin ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
On Wednesday April 28 2010 20:57:27 C M Caine wrote: Thank you all. One tangentially related question: what does (self, *args, **kwargs) actually mean? How does one reference variables given to a function that accepts these inputs? *args is a tuple containing the positional arguments; **kwargs is a dictionary which contains the keyword arguments. The stars before the variable names are the special syntax to handle arbitrary function arguments; you can use any variable names you want. You can use the syntax in a function call and in a function definition. Here's an example session with Ipython: In [5]: def foo(*args, **kwargs): ...: print args: , args ...: print kwargs: , kwargs ...: ...: In [6]: foo(1, 2, 3) args: (1, 2, 3) kwargs: {} In [7]: foo(1, 2, 3, a=4, b=5) args: (1, 2, 3) kwargs: {'a': 4, 'b': 5} In [8]: foo( *(10, 11), **{p:20, q:21}) args: (10, 11) kwargs: {'q': 21, 'p': 20} Eike. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Modify inherited methods
I'm writing a class that inherits the inbuilt dict class and want some of my own code to run at initialisation, on the other hand, I still want the original dict.__init__ function to run. Can I ask the class to run the original __init__ and then my own function at initialisation automatically? If so, how? Regards, Colin Caine ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
On Wed, 28 Apr 2010 07:24:48 am C M Caine wrote: I'm writing a class that inherits the inbuilt dict class and want some of my own code to run at initialisation, on the other hand, I still want the original dict.__init__ function to run. Can I ask the class to run the original __init__ and then my own function at initialisation automatically? If so, how? This is the general technique for calling the superclass' method: class MyDict(dict): def __init__(self, *args, **kwargs): # Call the superclass method. dict.__init__(self, *args, **kwargs) # Perform my own initialisation code. print Calling my init code... For advanced usage, replace the call to dict.__init__ with a call to super: super(MyDict, self).__init__(*args, **kwargs) And for guru-level mastery, replace to call to dict.__init__ with ... nothing at all, because dict.__init__ doesn't do anything. Some people argue that you must call dict.__init__ even though it doesn't do anything. Their reasoning is, some day its behaviour might change, and if you don't call it in your subclass, then your class may break. This is true, as far as it goes, but what they say is that if the behaviour of dict.__init__ changes, and you *do* call it, your class may still break. (This is why dict is unlikely to change any time soon.) -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
On Wed, 28 Apr 2010 08:08:12 am Steven D'Aprano wrote: Some people argue that you must call dict.__init__ even though it doesn't do anything. Their reasoning is, some day its behaviour might change, and if you don't call it in your subclass, then your class may break. This is true, as far as it goes, but what they say is that if the behaviour of dict.__init__ changes, and you *do* call it, your class may still break. (This is why dict is unlikely to change any time soon.) Oops, left out a word. I meant to say what they *don't* say is -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Modify inherited methods
Steven D'Aprano st...@pearwood.info wrote On Wed, 28 Apr 2010 07:24:48 am C M Caine wrote: I'm writing a class that inherits the inbuilt dict class and want some of my own code to run at initialisation, on the other hand, I still want the original dict.__init__ function to run. ... This is the general technique for calling the superclass' method: class MyDict(dict): def __init__(self, *args, **kwargs): # Call the superclass method. dict.__init__(self, *args, **kwargs) # Perform my own initialisation code. print Calling my init code... And just to be clear that applies to any method not just __init__ Also you can do your intialisation before or after or both. eg. def __init__() # do local pre processing(optional) super().__init__(...) # do local post processing(optional) Some people argue that you must call dict.__init__ even though it doesn't do anything. Their reasoning is, some day its behaviour might change, and if you don't call it in your subclass, then your class may break. I tend to argue for calling even if its a null call. Mainly because you sometimes don't know what the superclass does or doesn't do (eg you might not have access to the source) so its safer to call it... the behaviour of dict.__init__ changes, and you *do* call it, your class may still break. ... and if it breaks you at least have access to your own code to fix it... But if you do have access to the superclass source then you can make an informed decision. In general I'm too lazy to go looking for it and just put the super call in :-) HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor