[Tutor] functions and default argument

2011-10-21 Thread Praveen Singh
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

2011-10-21 Thread Christian Witts

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

2011-10-21 Thread Crusier
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

2011-10-21 Thread Steven D'Aprano

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

2011-10-21 Thread Steven D'Aprano

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

2011-10-21 Thread Prasad, Ramit
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

2011-10-21 Thread Albert-Jan Roskam
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

2011-10-21 Thread Prasad, Ramit

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__()?

2011-10-21 Thread Alex Hall
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

2011-10-21 Thread Alan Gauld

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__()?

2011-10-21 Thread Steven D'Aprano

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

2011-10-21 Thread Alan Gauld

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

2011-10-21 Thread Steven D'Aprano

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__()?

2011-10-21 Thread Alex Hall
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