[Tutor] functions and default argument
In function- Default value is *evaluated only once*.This makes different when the default is a mutable object such as a list, dictionary or instance of most classes. I am not getting it properly-evaluated once?? different behaviour???-- please explain this. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions and default argument
On 2011/10/21 03:00 PM, Praveen Singh wrote: In function- Default value is *evaluated only once*.This makes different when the default is a mutable object such as a list, dictionary or instance of most classes. I am not getting it properly-evaluated once?? different behaviour???-- please explain this. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor Mutable defaults for function/method arguments is a Python Gotcha, you can find a good read here [1]. It's a better read than how I would explain it. [1] http://www.ferg.org/projects/python_gotchas.html#contents_item_6 -- Christian Witts Python Developer // ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] Web Praser
Hi, I am new to programming. I want to know what I should look at if I want to learn more about Web Praser. I know there is something called Beautiful Soup but I think it is kind of difficult for me at this stage. Thank you Regards, Crusier ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions and default argument
Praveen Singh wrote: In function- Default value is *evaluated only once*.This makes different when the default is a mutable object such as a list, dictionary or instance of most classes. I am not getting it properly-evaluated once?? different behaviour???-- please explain this. Look at an example: import time def test(t=time.asctime()): ... print t, ***, time.asctime() ... time.sleep(30) # wait a little bit test() Sat Oct 22 04:17:08 2011 *** Sat Oct 22 04:17:57 2011 time.sleep(30) # wait a little bit longer test() Sat Oct 22 04:17:08 2011 *** Sat Oct 22 04:18:46 2011 Notice that the first time printed, using the default value, is the same. The default value for t is assigned once, and not calculated again. Since t is a string, it is immutable and can never change. The same thing occurs when you use a mutable object like a list or a dict. The default value is assigned once, and once only. But notice that you can modify the default value, say by appending to it: def test(x=[]): ... print x, id(x) ... x.append(1) ... test() [] 3085600236L test() [1] 3085600236L test() [1, 1] 3085600236L It is the same default list every time, but the *contents* of the list are changing. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Web Praser
Crusier wrote: Hi, I am new to programming. I want to know what I should look at if I want to learn more about Web Praser. I know there is something called Beautiful Soup but I think it is kind of difficult for me at this stage. What do you mean by web parser? The web (world wide web) is a network on the internet, you can't parse it. Do you mean a parser for HTML files? If you want to learn about parsing, then you should start with something simpler than HTML. If you want to learn about HTML, start with a good book or tutorial about HTML. There are dozens of them. Before we can advise you properly, you need to explain what it is you actually want to do. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions and default argument
The same thing occurs when you use a mutable object like a list or a dict. The default value is assigned once, and once only. But notice that you can modify the default value, say by appending to it: Not sure this will work exactly the same way in other IDEs, but in mine: a = [] def foo(x=a): ... x.append(1) ... a.append( 2 ) foo() print a [2, 1] help(foo) Help on function foo in module __pieshell__: foo(x=[2, 1]) foo() help(foo) Help on function foo in module __pieshell__: foo(x=[2, 1, 1]) a.append( 3 ) help(foo) Help on function foo in module __pieshell__: foo(x=[2, 1, 1, 3]) b = [] foo(b) b [1] Notice how it is always bound to the list a, but can be overridden. I know this has been discussed on this list or the main list before if you take a look through the archives. Sorry I can't remember what the thread would be like or when it was :( http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions and default argument
Interesting thread and webpages. Insightful, but is this really used as a technique in daily practice? It feels a bit like a hack to me. Like the author of one of the websites said: rule #1 don't mess with this. Cheers!! Albert-Jan ~~ All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a fresh water system, and public health, what have the Romans ever done for us? ~~ From: Prasad, Ramit ramit.pra...@jpmorgan.com To: tutor@python.org tutor@python.org Sent: Friday, October 21, 2011 9:40 PM Subject: Re: [Tutor] functions and default argument The same thing occurs when you use a mutable object like a list or a dict. The default value is assigned once, and once only. But notice that you can modify the default value, say by appending to it: Not sure this will work exactly the same way in other IDEs, but in mine: a = [] def foo(x=a): ... x.append(1) ... a.append( 2 ) foo() print a [2, 1] help(foo) Help on function foo in module __pieshell__: foo(x=[2, 1]) foo() help(foo) Help on function foo in module __pieshell__: foo(x=[2, 1, 1]) a.append( 3 ) help(foo) Help on function foo in module __pieshell__: foo(x=[2, 1, 1, 3]) b = [] foo(b) b [1] Notice how it is always bound to the list a, but can be overridden. I know this has been discussed on this list or the main list before if you take a look through the archives. Sorry I can't remember what the thread would be like or when it was :( http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions and default argument
Interesting thread and webpages. Insightful, but is this really used as a technique in daily practice? It feels a bit like a hack to me. Like the author of one of the websites said: rule #1 don't mess with this. I think the problem with rule #1 is that this can occur when you do *not* understand what is going on. The behavior can be non-intuitive for programmers coming from other (more statically-typed) languages and figuring out the programming error can be difficult depending on the complexity/design of the function or program. As for daily usage, well that depends on each person's needs; I do not need to write to files daily either, but I suspect most people would consider my Python knowledge lacking if I did not ;). I suspect you are right and it is not used on a daily basis by the majority of Python users/developers. In my opinion, knowledge ignorance. Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
[Tutor] difference between super() and parent.__init__()?
Hi all, I am just curious: I have seen classes that are subclasses initialize their parents through both super and parentClass.__init__. What is the difference, if any, and is one better or more pythonic than the other? -- Have a great day, Alex (msg sent from GMail website) mehg...@gmail.com; http://www.facebook.com/mehgcap ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] functions and default argument
On 21/10/11 21:40, Albert-Jan Roskam wrote: Interesting thread and webpages. Insightful, but is this really used as a technique in daily practice? Yes, one example is where you use it for a counter to determine how often a function gets called: def reserveScarceResource(p1,p2,count = [0]): : count is mutable count[0] += 1 if count[0] 100: raise UsedTooManyException # allocate resources Its not really a hack, it's an implementation feature and it's a fair impression of a closure in languages like Lisp, which makes it useful for certain classes of problem. It can also be useful in state machines where you want to carry through a state value across transitions but don't need to retain it after the state sequence completes. You don't need it often but its nice to have when you do! -- Alan G 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
Re: [Tutor] difference between super() and parent.__init__()?
Alex Hall wrote: Hi all, I am just curious: I have seen classes that are subclasses initialize their parents through both super and parentClass.__init__. What is the difference, if any, and is one better or more pythonic than the other? A simple question with a complicated answer... First off, the answer depends on whether you are using so-called classic classes or new-style classes. If you are using Python 3, there are only new-style classes: classic classes are gone. But in Python 2, classic classes are written like this: class MyClass: # Don't inherit from anything. pass while new-style classes inherit from either object or some other built-in type which inherits from object: class MyClass(object): # Inherit from object, new-style class. pass class MyInt(int): pass class MyStr(str): pass class MyList(list): pass # etc. super *does not work* for classic classes, end of story. So in the following discussion, I'm only talking about new-style classes, the only sort of class in Python 3. Secondly, let's talk about the difference between simple, single inheritance and multiple inheritance. Single inheritance is when each class inherits from exactly one parent, or superclass: class A(object): pass class B(A): pass class C(B): pass gives an inheritance hierarchy (a family tree, if you like): object | A | B | C In the case of single inheritance, super doesn't do anything special. It is the recommended way to handle inheritance: you are encouraged to write something like this: class C(B): def method(self, arg): x = super().method(arg) # Only works in Python 3 # or in Python 2, use super(C, self).method(arg) instead of x = B.method(arg), but functionality-wise, there is no difference between the two. In Python 3, super becomes a little more convenient, but it doesn't really matter much which you use. (But keep reading, for a reason why you *should* use super even in single inheritance.) The situation is more complicated once you have multiple inheritance. In multiple inheritance, at least one of the classes involved inherits from two or more superclasses. Here's a particularly simple example: class A(object): pass class B(A): pass class C(A): pass class D(B, C): pass # multiple superclasses or: object | A / \ B C \ / D In full generality, multiple inheritance can be so complex that most programming languages prohibit it, or put severe restrictions on it. Python is one of the very few that support it with very few restrictions. The difficulty occurs when you override a method in D. Now you need to ensure that each superclass (B and C) gets a shot at having their method called too. Here is a simple example showing how NOT to do it: class A(object): def save(self): print(class A saves) class B(A): def save(self): print(B saves stuff) A.save(self) # call the parent class method too class C(A): def save(self): print(C saves stuff) A.save(self) class D(B, C): def save(self): print (D saves stuff) # make sure you let both B and C save too B.save(self) C.save(self) Simple, obvious... but wrong. Try it and see: d = D() d.save() D saves stuff B saves stuff class A saves C saves stuff class A saves The problem is that the A.save method gets called twice. In general, it is very hard to solve this problem by hand, especially if you have a complex family tree. You have to manage the entire family tree, keeping track of which superclasses you have already called, and avoid calling them a second time. That's fiddly and annoying and hard to do right. But super can do it for you. Here's a version that works correctly: class A(object): def save(self): print(class A saves) class B(A): def save(self): print(B saves stuff) super(B, self).save() # In Python 3, you can abbreviate this as super().save() class C(A): def save(self): print(C saves stuff) super(C, self).save() class D(B, C): def save(self): print (D saves stuff) super(D, self).save() and in use: d = D() d.save() D saves stuff B saves stuff C saves stuff class A saves Now each class gets called exactly once, and in the right order. All the smarts managing the entire inheritance hierarchy is built into super, so each method gets called once and exactly once, provided that every class *only* uses super. If you try to mix super calls and direct method calls like B.method(self, arg), it probably won't work correctly, and if it does, it will probably be by accident. So please use super, even in single inheritance. Otherwise you are restricting the usefulness of your class: it can never be used with multiple inheritance. The one exception to this is if your class changes the method signature. E.g. if A.method takes no arguments, but B.method requires an argument.
Re: [Tutor] Web Praser
On 21/10/11 17:37, Crusier wrote: want to learn more about Web Praser. I know there is something called Beautiful Soup but I think it is kind of difficult for me at this stage. One of the objectives of Beautiful Soup is to make parsing fairly easy. Its certainly easier than most of the other HTML parsers out there! But parsing is not a trivial task regardless of the tool you use, especially something like HTML (which is what the web is made up of!) which is loosely defined and even more loosely implemented/used. -- Alan G 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
Re: [Tutor] functions and default argument
Prasad, Ramit wrote: Interesting thread and webpages. Insightful, but is this really used as a technique in daily practice? It feels a bit like a hack to me. Like the author of one of the websites said: rule #1 don't mess with this. I think the problem with rule #1 is that this can occur when you do *not* understand what is going on. The behavior can be non-intuitive for programmers coming from other (more statically-typed) languages and figuring out the programming error can be difficult depending on the complexity/design of the function or program. It actually has nothing to do with whether the language is statically typed or dynamically typed. It has everything to do with whether default arguments are early bound or late bound. That is, given the function definition: def func(arg=something): pass does the default argument `something` get created once (early binding, occurs one time only when the function is defined) or multiple times (late binding, each time the function is called)? In my experience, most people aren't even aware that there are two potential behaviours until they implicitly assume the one their language doesn't support. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] difference between super() and parent.__init__()?
On 10/21/11, Steven D'Aprano st...@pearwood.info wrote: Alex Hall wrote: Hi all, I am just curious: I have seen classes that are subclasses initialize their parents through both super and parentClass.__init__. What is the difference, if any, and is one better or more pythonic than the other? A simple question with a complicated answer... First off, the answer depends on whether you are using so-called classic classes or new-style classes. I always use new-style (python2.7). If you are using Python 3, there are only new-style classes: classic classes are gone. But in Python 2, classic classes are written like this: class MyClass: # Don't inherit from anything. pass while new-style classes inherit from either object or some other built-in type which inherits from object: class MyClass(object): # Inherit from object, new-style class. pass class MyInt(int): pass class MyStr(str): pass class MyList(list): pass # etc. super *does not work* for classic classes, end of story. So in the following discussion, I'm only talking about new-style classes, the only sort of class in Python 3. Secondly, let's talk about the difference between simple, single inheritance and multiple inheritance. Single inheritance is when each class inherits from exactly one parent, or superclass: class A(object): pass class B(A): pass class C(B): pass gives an inheritance hierarchy (a family tree, if you like): object | A | B | C In the case of single inheritance, super doesn't do anything special. It is the recommended way to handle inheritance: you are encouraged to write something like this: class C(B): def method(self, arg): x = super().method(arg) # Only works in Python 3 # or in Python 2, use super(C, self).method(arg) instead of x = B.method(arg), but functionality-wise, there is no difference between the two. In Python 3, super becomes a little more convenient, but it doesn't really matter much which you use. (But keep reading, for a reason why you *should* use super even in single inheritance.) The situation is more complicated once you have multiple inheritance. In multiple inheritance, at least one of the classes involved inherits from two or more superclasses. Here's a particularly simple example: class A(object): pass class B(A): pass class C(A): pass class D(B, C): pass # multiple superclasses or: object | A / \ B C \ / D In full generality, multiple inheritance can be so complex that most programming languages prohibit it, or put severe restrictions on it. Python is one of the very few that support it with very few restrictions. The difficulty occurs when you override a method in D. Now you need to ensure that each superclass (B and C) gets a shot at having their method called too. Here is a simple example showing how NOT to do it: class A(object): def save(self): print(class A saves) class B(A): def save(self): print(B saves stuff) A.save(self) # call the parent class method too class C(A): def save(self): print(C saves stuff) A.save(self) class D(B, C): def save(self): print (D saves stuff) # make sure you let both B and C save too B.save(self) C.save(self) Simple, obvious... but wrong. Try it and see: d = D() d.save() D saves stuff B saves stuff class A saves C saves stuff class A saves The problem is that the A.save method gets called twice. In general, it is very hard to solve this problem by hand, especially if you have a complex family tree. You have to manage the entire family tree, keeping track of which superclasses you have already called, and avoid calling them a second time. That's fiddly and annoying and hard to do right. But super can do it for you. Here's a version that works correctly: class A(object): def save(self): print(class A saves) class B(A): def save(self): print(B saves stuff) super(B, self).save() # In Python 3, you can abbreviate this as super().save() class C(A): def save(self): print(C saves stuff) super(C, self).save() class D(B, C): def save(self): print (D saves stuff) super(D, self).save() and in use: d = D() d.save() D saves stuff B saves stuff C saves stuff class A saves Now each class gets called exactly once, and in the right order. That all makes sense, and explains a lot. All the smarts managing the entire inheritance hierarchy is built into super, so each method gets called once and exactly once, provided that every class *only* uses super. If you try to mix super calls and direct method calls like B.method(self, arg), it probably won't work correctly, and if it does, it will probably be by accident. I'll keep it in mind; super() is to be