What value should be passed to make a function use the default argument value?

F

Fredrik Lundh

Georg said:
There's no possible value. You'll have to write this like

def myrepeat(obj, times=None):
if times is None:
return itertools.repeat(obj)
else:
return itertools.repeat(obj, times)

or:

def myrepeat(*args):
return itertools.repeat(*args)

</F>
 
A

Antoon Pardon

There's no possible value. You'll have to write this like

Yes, that was the point I wanted to make.
def myrepeat(obj, times=None):
if times is None:
return itertools.repeat(obj)
else:
return itertools.repeat(obj, times)

Many functions implemented in C have this behavior.

Which is a pity and IMO makes the documentation of these
functions a bit problematic. Take the itertool.repeat
documentation:

repeat(object[, times])
Make an iterator that returns object over and over again. Runs
indefinitely unless the times argument is specified. ...

My first impression from this, is that it is possible to call
this as follows:

repeat(None, times = 5)

But that doesn't work either.
For all functions written in Python, you can look up the default
value in the source.

That wont help much if you would like something like the following:

def fun(f):

arg = Default
try:
arg = Try_Processing()
except Nothing_To_Process:
pass
f(arg)
 
A

Antoon Pardon

or:

def myrepeat(*args):
return itertools.repeat(*args)

Yes that works but I have the impression that this solution
becomes complicated very fast once you want to do extra
processing in the function body. Take the following

def myrepeat(obj, times = xxx)"
newobj = Process(obj)
return itertools.repeat(obj, times)

I think it would become something like:

def myrepeat(*args):
obj = args[0]
tail = args[1:]
newobj = Process(obj)
newargs = (newobj,) + tail
return itertools.repeat(*newargs)
 
P

Paul Rubin

Antoon Pardon said:
repeat(object[, times])
Make an iterator that returns object over and over again. Runs
indefinitely unless the times argument is specified. ...

My first impression from this, is that it is possible to call
this as follows:
repeat(None, times = 5)
But that doesn't work either.

The code and/or doc is wrong, you have to use a positional arg
and not a named one. repeat(None, 5) does the right thing.
That wont help much if you would like something like the following:

def fun(f):

arg = Default
try:
arg = Try_Processing()
except Nothing_To_Process:
pass
f(arg)

Write it like this:

def fun(f):
args = ()
try:
args = (Try_Processing(),)
except Nothing_To_Process:
pass
f(*args)
 
P

Paul Rubin

Antoon Pardon said:
I think it would become something like:

def myrepeat(*args):
obj = args[0]
tail = args[1:]
newobj = Process(obj)
newargs = (newobj,) + tail
return itertools.repeat(*newargs)

Too messy. Just write:

def myrepeat(obj, *times):
return itertools.repeat(Process(obj), *times)
 
A

Antoon Pardon

Suppose I have this function:

def f(var=1):
return var*2

What value do I have to pass to f() if I want it to evaluate var to 1?
I know that f() will return 2, but what if I absolutely want to pass a
value to f()? "None" doesn't seem to work..

Thanks in advance.

I think the only general solution for your problem would be to
define a defaulter function. Something like the following:

Default = object()

def defaulter(f, *args):

while args:
if args[-1] is Default:
args = args[:-1]
else:
break
return f(*args)


The call:

defaulter(f, arg1, arg2, Default, ..., Default)

would then be equivallent to:

f(arg1, arg2)

Or in your case you would call:

defaulter(f, Default)
 
A

Antoon Pardon

Suppose I have this function:

def f(var=1):
return var*2

What value do I have to pass to f() if I want it to evaluate var to 1?
I know that f() will return 2, but what if I absolutely want to pass a
value to f()? "None" doesn't seem to work..

Thanks in advance.

I think the only general solution for your problem would be to
define a defaulter function. Something like the following:

Default = object()

def defaulter(f, *args):

while args:
if args[-1] is Default:
args = args[:-1]
else:
break
return f(*args)


The call:

defaulter(f, arg1, arg2, Default, ..., Default)

would then be equivallent to:

f(arg1, arg2)

Or in your case you would call:

defaulter(f, Default)

A little update, with the functools in python 2.5 you
could turn the above into a decorator. Something like
the following (not tested):

def defaulting(f):
return functools.partial(defaulter, f)

You could then simply write:

@defaulting
def f(var=1):
return var * 2

And for built in or library functions something like:

from itertools import repeat
repeat = defaulting(repeat)
 
G

Georg Brandl

Paul said:
Antoon Pardon said:
repeat(object[, times])
Make an iterator that returns object over and over again. Runs
indefinitely unless the times argument is specified. ...

My first impression from this, is that it is possible to call
this as follows:
repeat(None, times = 5)
But that doesn't work either.

The code and/or doc is wrong, you have to use a positional arg
and not a named one. repeat(None, 5) does the right thing.

This is an issue in most Python documentation: you're not told
if the described function is implemented in C, and if it is
keyword arg-enabled. The arguments must be given names though,
to be able to document them.

Georg
 
F

Fredrik Lundh

Georg said:
This is an issue in most Python documentation: you're not told
if the described function is implemented in C, and if it is
keyword arg-enabled. The arguments must be given names though,
to be able to document them.

the general rule is that if the documentation doesn't explicitly say
that something is a keyword argument, it isn't, and shouldn't be treated
as such.

</F>
 
A

Antoon Pardon

the general rule is that if the documentation doesn't explicitly say
that something is a keyword argument, it isn't, and shouldn't be treated
as such.

The first module I looked in to check this, it wasn't true. In the Queue
Module is isn't explicitly written that maxsize is a keyword argument yet
Queue.Queue(maxsize=9) works just fine.

I then took a look in the Threading module and found that the semaphore
documentation didn't mention anything about keyword arguments but
again they worked fine.

It wouldn't surprise me if this was true for the complete threading
documentation.
 
F

Fredrik Lundh

Antoon said:
The first module I looked in to check this, it wasn't true. In the Queue
Module is isn't explicitly written that maxsize is a keyword argument yet
Queue.Queue(maxsize=9) works just fine.

it's not a matter whether it works fine in any given version of Python,
it's a matter of whether it's *guaranteed* to work.

</F>
 
S

Steve Holden

Fredrik said:
Antoon Pardon wrote:




it's not a matter whether it works fine in any given version of Python,
it's a matter of whether it's *guaranteed* to work.
There are some sloppy places in the docs, though, perhaps where a
function has started out with positionals only and keyword arguments
have been added later, or it's just plain wrong. I remember an incident
a month or so ago when someone had called cgi.parse with a second
positional to retain blank values - the docs for 2.4.2 say:

parse( fp[, keep_blank_values[, strict_parsing]])

but the function signature in the code is

def parse(fp=None, environ=os.environ,
keep_blank_values=0, strict_parsing=0)

IIRC he reported this as a doc bug, though probably just too late to
make it into the initial 2.5 release. You can imagine his CGI scripts
didn't run too well with an integer as the environment ;-)

Someone with a tendency to salt every snail (that's dotting all the i's
and crossing all the t's for you English-speakers out there :) could
probably do the community a service by reviewing the documented
signatures and report such discrepancies.

regards
Steve
 
G

Gabriel Genellina

The first module I looked in to check this, it wasn't true. In the Queue
Module is isn't explicitly written that maxsize is a keyword argument yet
Queue.Queue(maxsize=9) works just fine.

This is true for most python code, unless the arguments are get as *args.
But it's not the same for the C code, where the argument parsing must
be done explicitely.



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas
 
F

Fredrik Lundh

Gabriel said:
This is true for most python code, unless the arguments are get as *args.

you guys need to look up the words "should" and "not" in a dictionary.

</F>
 
B

Ben Finney

Fredrik Lundh said:
you guys need to look up the words "should" and "not" in a dictionary.

Perhaps you meant something other than "if the documentation doesn't
explicitly say that something is a keyword argument, it isn't", then.
 
F

Fredrik Lundh

Ben said:
Perhaps you meant something other than "if the documentation doesn't
explicitly say that something is a keyword argument, it isn't", then.

I'm sure it's perfectly possibly to use your foot as a door stop, but
does that really mean that it is one?

</F>
 
A

Antoon Pardon

the general rule is that if the documentation doesn't explicitly say
that something is a keyword argument, it isn't, and shouldn't be treated
as such.

Is this general rules documeted somewhere? My impression is that readers
of the documentation will treat arguments as keyword arguments unless
this is explicitly contradicted. The reason for this is that when they learn
about writing functions, parameters can be used as keuword arguments by
default.

So I don't think you can fault the readers for treating the
documentation as if it is talking about python functions.
 
F

Fredrik Lundh

Antoon said:
Is this general rules documeted somewhere? My impression is that readers
of the documentation will treat arguments as keyword arguments unless
this is explicitly contradicted.

Sorry, I missed that this was comp.lang.python.alternate.reality. My
mistake.

</F>
 
A

Antoon Pardon

Sorry, I missed that this was comp.lang.python.alternate.reality. My
mistake.

A personal attack won't make my argument go away. It also doesn't
answer my question.
 
H

hanumizzle

A personal attack won't make my argument go away. It also doesn't
answer my question.

Not sure exactly what is going on / being argued about in this thread but HTH :?

http://docs.python.org/tut/node6.html

This doesn't say anything positive or negative about the practice in
question, but does point out that it is possible. I think it is a
reasonable assumption that if it isn't necessary, most users will
elide the keywords.

-- Theerasak
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top