Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > share function argument between subsequent calls but not between class instances!

Reply
Thread Tools

share function argument between subsequent calls but not between class instances!

 
 
K. Jansma
Guest
Posts: n/a
 
      02-18-2006
Hi,

given the following example class

class Test:
def f(self,a, L=[]):
L.append(a)
return L

and the following statements

a = Test()
a.f(0)
a.f(0)
a.f(0)
b = Test()
b.f(0)

this is the output I would like to have (i.e., expect)

>>> a = Test()
>>> a.f(0)

[0]
>>> a.f(0)

[0, 0]
>>> a.f(0)

[0, 0, 0]
>>> b = Test()
>>> b.f(0)

[0]

But this is what I get:

>>> a = Test()
>>> a.f(0)

[0]
>>> a.f(0)

[0, 0]
>>> a.f(0)

[0, 0, 0]
>>> b = Test()
>>> b.f(0)

[0, 0, 0, 0]


as you can see, the b.f method shares L with a.f.
How can I avoid this without using eg. self.L in an __init__?

Thanks in advance,
Karel.

 
Reply With Quote
 
 
 
 
Duncan Booth
Guest
Posts: n/a
 
      02-18-2006
K. Jansma wrote:

> as you can see, the b.f method shares L with a.f.
> How can I avoid this without using eg. self.L in an __init__?
>


You cannot.

If a method argument has a default value then the same default is used
whenever the method is called. If you want each instance to have its own
value then you must use an attribute on the instance.

If you intend to only use the default some of the time, and at other times
pass in a different list, then save the 'default' in the instance and use a
special marker value to indicate when you intend the default to be used:

marker = object()

class Test(object):
def __init__(self):
self.L = []

def f(self,a, L=marker):
if L is marker:
L = self.L
L.append(a)
return L
 
Reply With Quote
 
 
 
 
Felipe Almeida Lessa
Guest
Posts: n/a
 
      02-18-2006
Em S√°b, 2006-02-18 √*s 17:42 +0100, K. Jansma escreveu:
> How can I avoid this without using eg. self.L in an __init__?


Why not use it? That's how it's meant to be done!

> Thanks in advance,
> Karel.


Cya,
Felipe.

--
"Quem excele em empregar a força militar subjulga os exércitos dos
outros povos sem travar batalha, toma cidades fortificadas dos outros
povos sem as atacar e destrói os estados dos outros povos sem lutas
prolongadas. Deve lutar sob o Céu com o propósito primordial da
'preservação'. Desse modo suas armas não se embotarão, e os ganhos
poderão ser preservados. Essa é a estratégia para planejar ofensivas."

-- Sun Tzu, em "A arte da guerra"

 
Reply With Quote
 
Felipe Almeida Lessa
Guest
Posts: n/a
 
      02-18-2006
Em S√°b, 2006-02-18 √*s 16:50 +0000, Duncan Booth escreveu:
> marker = object()
>
> class Test(object):
> def __init__(self):
> self.L = []
>
> def f(self,a, L=marker):
> if L is marker:
> L = self.L
> L.append(a)
> return L


As hasattr(None, "append") == False, you could also do:

class Test(object):
def __init__(self):
self.L = []

def f(self, a, L=None):
if L is None:
L = self.L
L.append(a)
return L

--
"Quem excele em empregar a força militar subjulga os exércitos dos
outros povos sem travar batalha, toma cidades fortificadas dos outros
povos sem as atacar e destrói os estados dos outros povos sem lutas
prolongadas. Deve lutar sob o Céu com o propósito primordial da
'preservação'. Desse modo suas armas não se embotarão, e os ganhos
poderão ser preservados. Essa é a estratégia para planejar ofensivas."

-- Sun Tzu, em "A arte da guerra"

 
Reply With Quote
 
Ben Finney
Guest
Posts: n/a
 
      02-18-2006
Duncan Booth <(E-Mail Removed)> writes:
> If you intend to only use the default some of the time, and at other
> times pass in a different list, then save the 'default' in the
> instance and use a special marker value to indicate when you intend
> the default to be used:


The most common idiom for such a marker is the None value.

class Test(object):
def __init__(self):
self.L = []
def f(self, a, L=None):
if L is None:
L = self.L
L.append(a)
return L

--
\ "Consider the daffodil. And while you're doing that, I'll be |
`\ over here, looking through your stuff." -- Jack Handey |
_o__) |
Ben Finney <http://www.benfinney.id.au/>
 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      02-20-2006
Ben Finney wrote:

> Duncan Booth <(E-Mail Removed)> writes:
>> If you intend to only use the default some of the time, and at other
>> times pass in a different list, then save the 'default' in the
>> instance and use a special marker value to indicate when you intend
>> the default to be used:

>
> The most common idiom for such a marker is the None value.
>


Can you provide any firm evidence that using None is more common?

Both uses are common. Use whichever you are happier with (except of course
in the case where None is a potential value distinct from the default).
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      02-20-2006
On Mon, 20 Feb 2006 08:52:09 +0000, Duncan Booth wrote:

> Ben Finney wrote:
>
>> Duncan Booth <(E-Mail Removed)> writes:
>>> If you intend to only use the default some of the time, and at other
>>> times pass in a different list, then save the 'default' in the
>>> instance and use a special marker value to indicate when you intend
>>> the default to be used:

>>
>> The most common idiom for such a marker is the None value.
>>

>
> Can you provide any firm evidence that using None is more common?



Yes, I wrote a quick and dirty script to roughly count the default
values in the Python 2.3 standard library. Here are my results:

$ python default_counter.py
185 .py source files were opened.
4437 function or method definitions were found.
These functions included at least 1228 arguments with default values.
529 or 4.307818e+01% used None as the default value.

So, roughly 40% of default values in the standard library are None. If I
cared enough (I don't) I would re-write the counter to analyse all the
default values. But by eye-balling the function lines, the impression I
get is that the remaining 60% of default values are divided unequally
between dozens of different defaults. Some random examples:

"rb", "", "Prompt: ", -1, 0, 1, 3, sys.maxint, (), [].

My gut-feeling would be, 40-odd percent None, 40-odd percent for small
ints (-1, 0, 1, ..?), the remainder split between everything else.

If anyone cares to look at my quick and dirty source code, it is attached
following my signature.


--
Steven.




* * *

"""Rough and ready script to analyse the Python standard library
and count function definitions that use None as a default argument.
"""

from __future__ import division
import os

location = "/usr/lib/python2.3/"

file_count = 0 # number of files successfully opened
func_count = 0 # number of function definitions
default_count = 0 # number of functions with a default value
none_count = 0 # number of functions with None as a default value

for name in os.listdir(location):
if name.endswith(".py") and os.path.isfile(location+name):
try:
fp = file(location+name, "r")
except IOError:
continue
file_count += 1
lines = fp.readlines()
fp.close()
for line in lines:
line = line.strip()
if line.startswith("#"):
continue
elif line.startswith("def "):
func_count += 1
default_count += line.count("=")
none_count += line.count("None")
# if line.count("="): print line

# Report results found:

print "%d .py source files were opened." % file_count
print "%d function or method definitions were found." % func_count
print "These functions included at least %d arguments with default values." % default_count
print "%d or %e%% used None as the default value." % \
(none_count, none_count/default_count*100)


 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      02-21-2006
Steven D'Aprano wrote:

>>> The most common idiom for such a marker is the None value.
>>>

>>
>> Can you provide any firm evidence that using None is more common?

>
>
> Yes, I wrote a quick and dirty script to roughly count the default
> values in the Python 2.3 standard library. Here are my results:
>
> $ python default_counter.py
> 185 .py source files were opened.
> 4437 function or method definitions were found.
> These functions included at least 1228 arguments with default values.
> 529 or 4.307818e+01% used None as the default value.
>
> So, roughly 40% of default values in the standard library are None.


Fair enough, although I would point out that you haven't made any attempt
to distinguish those cases where None is being used as a marker from the
cases where it is being used as a value in its own right or a flag to
control the function logic.

The marker cases do seem to be the most common but there are plenty of
other cases:

e.g. base64.b64encode & base64.b64decode avoid part of the code if passed
None, but don't actually substitute another value in place of the default.

cgi.FieldStorage has methods getvalue, getfirst where the default=None is
simply that: the default to be returned. The make_file method has a
defaulted argument which it doesn't use at all.

Also, most of the standard library predates a time when you could create a
unique marker value just by calling 'object()'. When it was written None
was by far the simplest option even in cases where a separate marker value
might have been more appropriate.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Share-Point-2010 ,Share-Point -2010 Training , Share-point-2010Hyderabad , Share-point-2010 Institute Saraswati lakki ASP .Net 0 01-06-2012 06:39 AM
fopen() with full path affecting subsequent fopen calls Michel Rouzic C Programming 4 04-28-2008 04:48 PM
MIME::Head subsequent calls in a loop return empty values ebg005@gmail.com Perl Misc 0 02-07-2008 09:45 AM
tmpnam behaviour on subsequent calls Lars Uffmann C++ 8 01-22-2008 10:45 AM
This function has an onClick event that calls a function that calls This function Bob Javascript 5 10-24-2006 04:11 PM



Advertisments