Re: Default parameter for a method

2008-04-16 Thread George Sakkis
On Apr 16, 4:21 pm, John Nagle <[EMAIL PROTECTED]> wrote:

> In general, default values should be immutable constants only.

This is more restrictive than necessary; it should rather read "In
general, default values should be *treated as* immutable objects
only". It's perfectly fine for a default value to be mutable if the
function doesn't modify it, as in the following example:

def parse(text, stopwords=set(w.strip() for w in
  open('stopwords.txt')):
words = [w for w in text.split() if w not in stopwords]
...

Since the set is not modified, there's no harm for being mutable; IOW
it's no different than using a frozenset instead. Similarly for dicts,
lists and other mutable containers, as long as they are treated as
read-only.

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


Re: Default parameter for a method

2008-04-16 Thread Terry Reedy

"John Nagle" <[EMAIL PROTECTED]> wrote in message 
news:[EMAIL PROTECTED]
| [EMAIL PROTECTED] wrote:
| > I wanted to know if there's any way to create a method that takes a
| > default parameter, and that parameter's default value is the return
| > value of another method of the same class. For example:
| >
| ...
|
| >
| > def meth2(self, arg=meth1()):
|
|Not good.  If the default value of an argument is mutable, there
| are wierd effects, because the default value is bound once when the
| class is created, then shared between all later uses.  This is almost
| never what was wanted or intended, and it's a common source of subtle
| bugs.
|
|In general, default values should be immutable constants only.

Then one would have to restrict default args to immutable builtins.
There is no way to determine (without reading code) whether instances of a 
user-defined class are mutable or not.

tjr



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


Re: Default parameter for a method

2008-04-16 Thread John Nagle
[EMAIL PROTECTED] wrote:
> I wanted to know if there's any way to create a method that takes a
> default parameter, and that parameter's default value is the return
> value of another method of the same class. For example:
> 
...

> 
> def meth2(self, arg=meth1()):

Not good.  If the default value of an argument is mutable, there
are wierd effects, because the default value is bound once when the
class is created, then shared between all later uses.  This is almost
never what was wanted or intended, and it's a common source of subtle
bugs.

In general, default values should be immutable constants only.
There's been talk of fixing this (it's really a design bug in Python),
but for now, it's still broken.

(I just had horrible thoughts about the implications of binding
a closure to a default argument.  You don't want to go there.)

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


Re: Default parameter for a method

2008-04-16 Thread Peter Otten
Cliff Wells wrote:

> 
> On Wed, 2008-04-16 at 13:47 -0500, Larry Bates wrote:
>> [EMAIL PROTECTED] wrote:
>> > I wanted to know if there's any way to create a method that takes a
>> > default parameter, and that parameter's default value is the return
>> > value of another method of the same class. For example:
>> > 
>> > class A:
>> > def __init__(self):
>> > self.x = 1
>> > 
>> > def meth1(self):
>> > return self.x
>> > 
>> > def meth2(self, arg=meth1()):
>> > # The default `arg' should would take the return value of
>> > meth1()
>> > print '"arg" is', arg
>> > 
>> > This obviously doesn't work. I know I could do
>> > 
>> > ...
>> > def meth2(self, arg=None):
>> > if arg is None:
>> > arg = self.meth1()
>> > 
>> > but I'm looking for a more straightforward way.
>> 
>> You can write this as:
>> 
>>  def meth2(self, arg=None):
>>  arg = arg or self.meth1()
>> 
>> IMHO - You can't get much more "straightforward" than that.
> 
> What if arg is 0 an empty list or anything else that's "False"?
> 
> def meth2(self, arg=None):
> arg = (arg is not None) or self.meth1()
> 
> is what you want.

No, it's not:

>>> for arg in None, 0, "yadda":
... print "---", arg, "---"
... if arg is None: arg = "call method"
... print "OP:", arg
... print "Larry:", arg or "call method"
... print "Cliff:", (arg is not None) or "call method"
...
--- None ---
OP: call method
Larry: call method
Cliff: True
--- 0 ---
OP: 0
Larry: call method
Cliff: True
--- yadda ---
OP: yadda
Larry: yadda
Cliff: True

Peter

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


Re: Default parameter for a method

2008-04-16 Thread Cliff Wells

On Wed, 2008-04-16 at 13:47 -0500, Larry Bates wrote:
> [EMAIL PROTECTED] wrote:
> > I wanted to know if there's any way to create a method that takes a
> > default parameter, and that parameter's default value is the return
> > value of another method of the same class. For example:
> > 
> > class A:
> > def __init__(self):
> > self.x = 1
> > 
> > def meth1(self):
> > return self.x
> > 
> > def meth2(self, arg=meth1()):
> > # The default `arg' should would take the return value of
> > meth1()
> > print '"arg" is', arg
> > 
> > This obviously doesn't work. I know I could do
> > 
> > ...
> > def meth2(self, arg=None):
> > if arg is None:
> > arg = self.meth1()
> > 
> > but I'm looking for a more straightforward way.
> 
> You can write this as:
> 
>  def meth2(self, arg=None):
>  arg = arg or self.meth1()
> 
> IMHO - You can't get much more "straightforward" than that.

What if arg is 0 an empty list or anything else that's "False"?

def meth2(self, arg=None):
arg = (arg is not None) or self.meth1()

is what you want.


Regards,
Cliff


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


Re: Default parameter for a method

2008-04-16 Thread Larry Bates
[EMAIL PROTECTED] wrote:
> I wanted to know if there's any way to create a method that takes a
> default parameter, and that parameter's default value is the return
> value of another method of the same class. For example:
> 
> class A:
> def __init__(self):
> self.x = 1
> 
> def meth1(self):
> return self.x
> 
> def meth2(self, arg=meth1()):
> # The default `arg' should would take the return value of
> meth1()
> print '"arg" is', arg
> 
> This obviously doesn't work. I know I could do
> 
> ...
> def meth2(self, arg=None):
> if arg is None:
> arg = self.meth1()
> 
> but I'm looking for a more straightforward way.

You can write this as:

 def meth2(self, arg=None):
 arg = arg or self.meth1()

IMHO - You can't get much more "straightforward" than that.

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


Re: Default parameter for a method... again

2008-04-16 Thread Matimus
On Apr 16, 9:26 am, [EMAIL PROTECTED] wrote:
> I had posted this before but all the spam whipped it out...
>
> I wanted to know if there's any way to create a method that takes a
> default parameter, and that parameter's default value is the return
> value of another method of the same class. For example:
>
> class A:
> def __init__(self):
> self.x = 1
>
> def meth1(self):
> return self.x
>
> def meth2(self, arg=meth1()):
> # The default `arg' should would take thereturn value of
> meth1()
> print '"arg" is', arg
>
> This obviously doesn't work. I know I could do
>
> ...
> def meth2(self, arg=None):
> if arg is None:
> arg = self.meth1()
>
> but I'm looking for a more straightforward way.

That is the straightforward way. It may not seem that way now but all
languages have patterns and this is a common one in python. You will
see code like this all over Python, even in the standard library. The
best thing to do is embrace it. It will not only work, but make your
code more readable to others.

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


Default parameter for a method... again

2008-04-16 Thread s0suk3
I had posted this before but all the spam whipped it out...

I wanted to know if there's any way to create a method that takes a
default parameter, and that parameter's default value is the return
value of another method of the same class. For example:

class A:
def __init__(self):
self.x = 1

def meth1(self):
return self.x

def meth2(self, arg=meth1()):
# The default `arg' should would take thereturn value of
meth1()
print '"arg" is', arg

This obviously doesn't work. I know I could do

...
def meth2(self, arg=None):
if arg is None:
arg = self.meth1()

but I'm looking for a more straightforward way.
-- 
http://mail.python.org/mailman/listinfo/python-list


Default parameter for a method

2008-04-16 Thread s0suk3
I wanted to know if there's any way to create a method that takes a
default parameter, and that parameter's default value is the return
value of another method of the same class. For example:

class A:
def __init__(self):
self.x = 1

def meth1(self):
return self.x

def meth2(self, arg=meth1()):
# The default `arg' should would take the return value of
meth1()
print '"arg" is', arg

This obviously doesn't work. I know I could do

...
def meth2(self, arg=None):
if arg is None:
arg = self.meth1()

but I'm looking for a more straightforward way.
-- 
http://mail.python.org/mailman/listinfo/python-list