Default parameter for a method

S

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.
 
C

Cliff Wells

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
 
P

Peter Otten

Cliff said:
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:
.... 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
 
J

John Nagle

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
 
T

Terry Reedy

| (e-mail address removed) 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
 
G

George Sakkis

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top