Re: retain values between fun calls

2006-05-15 Thread bruno at modulix
Gary Wessle wrote:
 Hi
 
 the second argument in the functions below suppose to retain its value
 between function calls, the first does, the second does not and I
 would like to know why it doesn't? 

Fisrt thing to remember is that function's default args are eval'd only
once - when the def block is eval'd, which is usually at import time.

 # it does
 def f(a, L=[]):
 L.append(a)

Here, you are modifying the (list) object bound to local name L.

 return L
 print f('a')
 print f('b')
 
 
 # it does not
 def f(a, b=1):
 b = a + b

And here, you are *rebinding* the local name b to another object.
Understand that modifying an object in-place and rebinding a name are
two really different operations...

 return b
 print f(1)
 print f(2)

 and how to make it so it does?

The QD solution is to wrap :

def f(a, b = [1])
  b[0] = b[0] + a
  return b[0]

But this is really a hack - it's ok for a throw-away script, but may not
be the best thing to do in a more serious piece of software.

The clean solution to maintain state between calls is to use a custom
class - hopefully, Python is OO enough to let you write your own callables:

class MyFunc(object):
  def __init__(self, initstate=1):
self._state = default
  def __call__(self, a):
 self._state += a
 return self._state

f = MyFunc(1)
print f(1)
print f(2)

HTH

-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: retain values between fun calls

2006-05-14 Thread Kent Johnson
George Sakkis wrote:
 Gary Wessle wrote:
 Hi

 the second argument in the functions below suppose to retain its value
 between function calls, the first does, the second does not and I
 would like to know why it doesn't? and how to make it so it does?

 thanks

 # it does
 def f(a, L=[]):
 L.append(a)
 return L
 print f('a')
 print f('b')


 # it does not
 def f(a, b=1):
 b = a + b
 return b
 print f(1)
 print f(2)
 
 It's a FAQ:
 http://www.python.org/doc/faq/general/#why-are-default-values-shared-between-objects.
 
 Whenever you want to control one or more objects beyond the lifetime of
 a single function call, your first thought should be to use a class to
 couple behaviour with state:
 
 class SomeFancyClassName(object):
 def __init__(self, b=1):
 self.b = b
 def f(self, a):
 self.b += a
 return self.b
 
 x = SomeFancyClassName()
 print x.f(1)
 print x.f(2)

If you make the class callable you can match the original syntax:
In [40]: class F(object):
: b=1
: def __call__(self, a):
: F.b += a
: return F.b
:
:

In [41]: f=F()

In [42]: f(1)
Out[42]: 2

In [43]: f(2)
Out[43]: 4

Alternately you can use an attribute of the function to save the state:

In [35]: def f(a):
: f.b += a
: return f.b
:

In [36]: f.b=1

In [37]: f(1)
Out[37]: 2

In [38]: f(2)
Out[38]: 4

Kent
-- 
http://mail.python.org/mailman/listinfo/python-list


retain values between fun calls

2006-05-13 Thread Gary Wessle
Hi

the second argument in the functions below suppose to retain its value
between function calls, the first does, the second does not and I
would like to know why it doesn't? and how to make it so it does?

thanks

# it does
def f(a, L=[]):
L.append(a)
return L
print f('a')
print f('b')


# it does not
def f(a, b=1):
b = a + b
return b
print f(1)
print f(2)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: retain values between fun calls

2006-05-13 Thread George Sakkis
Gary Wessle wrote:
 Hi

 the second argument in the functions below suppose to retain its value
 between function calls, the first does, the second does not and I
 would like to know why it doesn't? and how to make it so it does?

 thanks

 # it does
 def f(a, L=[]):
 L.append(a)
 return L
 print f('a')
 print f('b')


 # it does not
 def f(a, b=1):
 b = a + b
 return b
 print f(1)
 print f(2)

It's a FAQ:
http://www.python.org/doc/faq/general/#why-are-default-values-shared-between-objects.

Whenever you want to control one or more objects beyond the lifetime of
a single function call, your first thought should be to use a class to
couple behaviour with state:

class SomeFancyClassName(object):
def __init__(self, b=1):
self.b = b
def f(self, a):
self.b += a
return self.b

x = SomeFancyClassName()
print x.f(1)
print x.f(2)


HTH,
George

-- 
http://mail.python.org/mailman/listinfo/python-list