By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,092 Members | 1,650 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,092 IT Pros & Developers. It's quick & easy.

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

P: n/a
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.

Oct 3 '06 #1
Share this Question
Share on Google+
50 Replies


P: n/a
LaundroMat <La*****@gmail.comwrote:
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..
I don't know if I understand correctly here but:

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

f() returns 2
f(1) returns 2 too

v = 1
f(v) returns 2 too

What do you mean?

--
Lawrence - http://www.oluyede.org/blog
"Nothing is more dangerous than an idea
if it's the only one you have" - E. A. Chartier
Oct 3 '06 #2

P: n/a
LaundroMat wrote:
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()?
f(1)
"None" doesn't seem to work..
None is an object.

</F>

Oct 3 '06 #3

P: n/a
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..
>>def f(var=1):
.... return var*2
....
>>f()
2
>>f(0.5)
1.0
>>f(123)
246
>>f('hello')
'hellohello'
I'm not sure I follow your problem...what's stopping you from
passing a value?

-tkc


Oct 3 '06 #4

P: n/a
LaundroMat wrote:
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.
The answer is don't pass any value.

print f()

will print 2

-Larry Bates
Oct 3 '06 #5

P: n/a
On Tue, 03 Oct 2006 13:16:57 -0700, "LaundroMat" <La*****@gmail.comlet
this slip:
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.
a) if you feel that your program needs to pass a value, fix the program.

b)
>>def f(v=1):
.... return v*2
....
>>f()
2
>>f(1)
2
>>f(*[1])
2
>>f(*[])
2
>>>
*[list] is the reverse of def f(*args)

--
Thomas Jollans alias free-zombie
Oct 3 '06 #6

P: n/a
LaundroMat wrote:
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..

What about this?
>>def f(var=None):
.... if var == None:
.... var = 1
.... return 2*var
....
>>f()
2
>>f(3)
6
>>a=4
f(a)
8
>>b=None
f(b)
2
>>>
--Stan Graves

Oct 3 '06 #7

P: n/a
LaundroMat a écrit :
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..
Have you tried f(1) ?
Oct 3 '06 #8

P: n/a
LaundroMat wrote:
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..
If you *absolutely* want to pass a value and you don't know the default
value (otherwise you could just pass it):
>>import inspect
v = inspect.getargspec(f)[3][0] # first default value
f(v)
2

Oct 3 '06 #9

P: n/a
On 2006-10-03, LaundroMat <La*****@gmail.comwrote:
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.
One possible way to do what I think you want is to code as follows:

class Default (object):
pass

def f(var=Default):
if var is Default:
var = 1
return var * 2

--
Antoon Pardon
Oct 4 '06 #10

P: n/a

Rob De Almeida wrote:
LaundroMat wrote:
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..

If you *absolutely* want to pass a value and you don't know the default
value (otherwise you could just pass it):
>import inspect
v = inspect.getargspec(f)[3][0] # first default value
f(v)
2
I have in fact a bunch of functions that all pass similar information
to one main function. That function takes (amongst others) a template
variable. If it's not being passed, it is set to a default value by the
function called upon.

For the moment, whenever a function calls the main function, I check
whether the calling function has the template variable set:
>>if template:
return mainFunction(var, template)
else:
return mainFunction(var)
Now, I thought this isn't the cleanest way to do things; so I was
looking for ways to initialize the template variable, so that I could
always return mainFunction(var, template). mainFunction() would then
assign the default value to template.
>From your answers, this seems to be impossible. The minute my variable
is initialised, there's no way I can have mainFunction() assign a value
without explicitly asking it to do so.

I guess the best way would then be to change mainFunction from:
>>def mainFunction(var, template='base'):
to
>>def mainFunction(var, template):
if len(template)=0:
template = 'base'
and have the calling functions call mainFunction (var, template) and
initialise template to ''.

I still have that nagging feeling nicer code could be written to solve
this, but I won't try to lose any sleep over it.

Thanks for all the replies.

Oct 4 '06 #11

P: n/a
"LaundroMat" <La*****@gmail.comwrites:
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..
I don't understand your question. You can call f(var=1) just fine.
Oct 4 '06 #12

P: n/a
On 2006-10-04, Paul Rubin <httpwrote:
"LaundroMat" <La*****@gmail.comwrites:
>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..

I don't understand your question. You can call f(var=1) just fine.
The problem is like the following.

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

def g():
arg = None
try:
arg = Try_Processing() / 3 + 1
except Nothing_To_Process:
pass
if arg is None:
return f()
else:
return f(arg)

Now in this case you could start by assigning arg the value 1 and
eliminate the if test. However that only works if you know the
default value for the argument. What he seems to be asking for
is if there is an object, (let as call it Default), that would
make code like:

def f(var=1):

Equivallent to:

def f(var=Default)
if var is Default)
var = 1

So that we could write the following without the need of the
f's default value.

def g():
arg = Default
try:
arg = Try_Processing() / 3 + 1
except Nothing_To_Process:
pass
f(arg)

--
Antoon Pardon
Oct 4 '06 #13

P: n/a
Antoon Pardon wrote:
The problem is like the following.

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

def g():
arg = None
try:
arg = Try_Processing() / 3 + 1
except Nothing_To_Process:
pass
if arg is None:
return f()
else:
return f(arg)

Now in this case you could start by assigning arg the value 1 and
eliminate the if test. However that only works if you know the
default value for the argument. What he seems to be asking for
is if there is an object, (let as call it Default), that would
make code like:

def f(var=1):

Equivallent to:

def f(var=Default)
if var is Default)
var = 1

So that we could write the following without the need of the
f's default value.

def g():
arg = Default
try:
arg = Try_Processing() / 3 + 1
except Nothing_To_Process:
pass
f(arg)

--
Antoon Pardon
Exactly. Thanks for helping out.

Oct 4 '06 #14

P: n/a
Antoon Pardon <ap*****@forel.vub.ac.bewrites:
Now in this case you could start by assigning arg the value 1 and
eliminate the if test. However that only works if you know the
default value for the argument. What he seems to be asking for
is if there is an object, (let as call it Default), that would
make code like:

def f(var=1):

Equivallent to:

def f(var=Default)
if var is Default)
var = 1
Oh, I see. Yes, the OP should just use a distinct default value
instead of 1. I usually do this with

sentinel = object()

def f(var=sentinel):
if var is sentinel:
# f was called without an arg
Oct 4 '06 #15

P: n/a
LaundroMat <La*****@gmail.comwrote:
I have in fact a bunch of functions that all pass similar information
to one main function. That function takes (amongst others) a template
variable. If it's not being passed, it is set to a default value by the
function called upon.

For the moment, whenever a function calls the main function, I check
whether the calling function has the template variable set:
>if template:
return mainFunction(var, template)
else:
return mainFunction(var)

Now, I thought this isn't the cleanest way to do things; so I was
looking for ways to initialize the template variable, so that I could
always return mainFunction(var, template). mainFunction() would then
assign the default value to template.

From your answers, this seems to be impossible. The minute my variable
is initialised, there's no way I can have mainFunction() assign a value
without explicitly asking it to do so.

I guess the best way would then be to change mainFunction from:
>def mainFunction(var, template='base'):
to
>def mainFunction(var, template):
if len(template)=0:
template = 'base'

and have the calling functions call mainFunction (var, template) and
initialise template to ''.
None is the traditional value to use for value not present, then you'd
get this for the function

def mainFunction(var, template=None):
if template is None:
template = 'base'

And this for the calling bit

if not_set_properly(template):
template = None
return mainFunction(var, template)

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Oct 4 '06 #16

P: n/a
Antoon Pardon <ap*****@forel.vub.ac.bewrote:
One possible way to do what I think you want is to code as follows:

class Default (object):
pass
I'd have written

Default = object()
def f(var=Default):
if var is Default:
var = 1
return var * 2
But yes, defining a sentinel like this is a good idea.

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Oct 4 '06 #17

P: n/a
On 2006-10-04, Nick Craig-Wood <ni**@craig-wood.comwrote:
Antoon Pardon <ap*****@forel.vub.ac.bewrote:
> One possible way to do what I think you want is to code as follows:

class Default (object):
pass

I'd have written

Default = object()
> def f(var=Default):
if var is Default:
var = 1
return var * 2

But yes, defining a sentinel like this is a good idea.
The problem is that a lot of built in and library functions
are not written this way. So when f is one of those, you
are stuck.

--
Antoon Pardon
Oct 4 '06 #18

P: n/a
On 2006-10-04, Paul Rubin <httpwrote:
Antoon Pardon <ap*****@forel.vub.ac.bewrites:
>Now in this case you could start by assigning arg the value 1 and
eliminate the if test. However that only works if you know the
default value for the argument. What he seems to be asking for
is if there is an object, (let as call it Default), that would
make code like:

def f(var=1):

Equivallent to:

def f(var=Default)
if var is Default)
var = 1

Oh, I see. Yes, the OP should just use a distinct default value
instead of 1. I usually do this with

sentinel = object()

def f(var=sentinel):
if var is sentinel:
# f was called without an arg
But that can only work if you are the author of f. Take the
following code:

def myrepeat(obj, times = xxx):
return itertools.repeat(obj, times)

What value do I have to substitue for xxx, so that myrepeat
will have the exact same function as itertools.repeat?

--
Antoon Pardon
Oct 4 '06 #19

P: n/a
Antoon Pardon wrote:
On 2006-10-04, Paul Rubin <httpwrote:
>Antoon Pardon <ap*****@forel.vub.ac.bewrites:
>>Now in this case you could start by assigning arg the value 1 and
eliminate the if test. However that only works if you know the
default value for the argument. What he seems to be asking for
is if there is an object, (let as call it Default), that would
make code like:

def f(var=1):

Equivallent to:

def f(var=Default)
if var is Default)
var = 1

Oh, I see. Yes, the OP should just use a distinct default value
instead of 1. I usually do this with

sentinel = object()

def f(var=sentinel):
if var is sentinel:
# f was called without an arg

But that can only work if you are the author of f. Take the
following code:

def myrepeat(obj, times = xxx):
return itertools.repeat(obj, times)

What value do I have to substitue for xxx, so that myrepeat
will have the exact same function as itertools.repeat?
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)

Many functions implemented in C have this behavior.

For all functions written in Python, you can look up the default
value in the source.

Georg
Oct 4 '06 #20

P: n/a
Georg Brandl wrote:
>But that can only work if you are the author of f. Take the
following code:

def myrepeat(obj, times = xxx):
return itertools.repeat(obj, times)

What value do I have to substitue for xxx, so that myrepeat
will have the exact same function as itertools.repeat?

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>

Oct 4 '06 #21

P: n/a
On 2006-10-04, Georg Brandl <g.*************@gmx.netwrote:
Antoon Pardon wrote:
>On 2006-10-04, Paul Rubin <httpwrote:
>>Antoon Pardon <ap*****@forel.vub.ac.bewrites:
Now in this case you could start by assigning arg the value 1 and
eliminate the if test. However that only works if you know the
default value for the argument. What he seems to be asking for
is if there is an object, (let as call it Default), that would
make code like:

def f(var=1):

Equivallent to:

def f(var=Default)
if var is Default)
var = 1

Oh, I see. Yes, the OP should just use a distinct default value
instead of 1. I usually do this with

sentinel = object()

def f(var=sentinel):
if var is sentinel:
# f was called without an arg

But that can only work if you are the author of f. Take the
following code:

def myrepeat(obj, times = xxx):
return itertools.repeat(obj, times)

What value do I have to substitue for xxx, so that myrepeat
will have the exact same function as itertools.repeat?

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)

--
Antoon Pardon
Oct 4 '06 #22

P: n/a
On 2006-10-04, Fredrik Lundh <fr*****@pythonware.comwrote:
Georg Brandl wrote:
>>But that can only work if you are the author of f. Take the
following code:

def myrepeat(obj, times = xxx):
return itertools.repeat(obj, times)

What value do I have to substitue for xxx, so that myrepeat
will have the exact same function as itertools.repeat?

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)
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)
Oct 4 '06 #23

P: n/a
Antoon Pardon <ap*****@forel.vub.ac.bewrites:
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)
Oct 4 '06 #24

P: n/a
Antoon Pardon <ap*****@forel.vub.ac.bewrites:
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)
Oct 4 '06 #25

P: n/a
On 2006-10-03, LaundroMat <La*****@gmail.comwrote:
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)

--
Antoon Pardon
Oct 4 '06 #26

P: n/a
On 2006-10-04, Antoon Pardon <ap*****@forel.vub.ac.bewrote:
On 2006-10-03, LaundroMat <La*****@gmail.comwrote:
>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)

--
Antoon Pardon
Oct 4 '06 #27

P: n/a
Paul Rubin wrote:
Antoon Pardon <ap*****@forel.vub.ac.bewrites:
>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
Oct 4 '06 #28

P: n/a
Georg Brandl wrote:
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>

Oct 4 '06 #29

P: n/a
On 2006-10-04, Fredrik Lundh <fr*****@pythonware.comwrote:
Georg Brandl wrote:
>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.
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.

--
Antoon Pardon
Oct 5 '06 #30

P: n/a
Antoon Pardon wrote:
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>

Oct 5 '06 #31

P: n/a
Fredrik Lundh wrote:
Antoon Pardon wrote:

>>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.
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
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 5 '06 #32

P: n/a
At Thursday 5/10/2006 11:41, Antoon Pardon wrote:
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.
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

Oct 5 '06 #33

P: n/a
Gabriel Genellina wrote:
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.

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>

Oct 5 '06 #34

P: n/a
Fredrik Lundh <fr*****@pythonware.comwrites:
Gabriel Genellina wrote:
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.

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.

--
\ "If I ever get real rich, I hope I'm not real mean to poor |
`\ people, like I am now." -- Jack Handey |
_o__) |
Ben Finney

Oct 5 '06 #35

P: n/a
Ben Finney wrote:
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>

Oct 6 '06 #36

P: n/a
On 2006-10-04, Fredrik Lundh <fr*****@pythonware.comwrote:
Georg Brandl wrote:
>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.
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.

--
Antoon Pardon
Oct 6 '06 #37

P: n/a
Antoon Pardon wrote:
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>

Oct 6 '06 #38

P: n/a
On 2006-10-06, Fredrik Lundh <fr*****@pythonware.comwrote:
Antoon Pardon wrote:
>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.
A personal attack won't make my argument go away. It also doesn't
answer my question.

--
Antoon Pardon
Oct 6 '06 #39

P: n/a
On 6 Oct 2006 09:21:11 GMT, Antoon Pardon <ap*****@forel.vub.ac.bewrote:
On 2006-10-06, Fredrik Lundh <fr*****@pythonware.comwrote:
Antoon Pardon wrote:
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.

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
Oct 6 '06 #40

P: n/a
hanumizzle wrote:
Not sure exactly what is going on / being argued about in this
thread
I'm describing best practices based on long experience of using and
developing and teaching and writing about Python stuff. Others have
other priorities, it seems.
This doesn't say anything positive or negative about the practice in
question
The tutorial tends to describe mechanisms, not best practices, and it
also assumes prior programming experience. After all, basic stuff like
"minimize coupling" and "don't depend on implementation artifacts" apply
to all software engineering, not just Python.

</F>

Oct 6 '06 #41

P: n/a
On 2006-10-06, hanumizzle <ha********@gmail.comwrote:
On 6 Oct 2006 09:21:11 GMT, Antoon Pardon <ap*****@forel.vub.ac.bewrote:
>On 2006-10-06, Fredrik Lundh <fr*****@pythonware.comwrote:
Antoon Pardon wrote:

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.

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.
What I am argueing is that it is very natural for python programmers to
assume that keyword arguments will work if they see a signature. IMO
if a python programmer sees something like:

abs(x)

It is very natural to envision a corresponding def statement like:

def abs(x):

and a python function written like this will work if called as
follows:

abs(x=5)

IMO this is a very natural thought process for a python programmer.
So a python programmer seeing the first will tend to expect that
last call to work.

Now frederic claims that the general rule is different. Now I'm
perfectly happy to accept that those who write the documentation
do so based aacording to the rule frederic stated (you can't/shouldn't
use a parameter as a keyword argument unless explictly stated in the
documentation), but that doesn't contradict that readers may have
different expectations.

--
Antoon Pardon
Oct 6 '06 #42

P: n/a
On 2006-10-06, Fredrik Lundh <fr*****@pythonware.comwrote:
hanumizzle wrote:
>Not sure exactly what is going on / being argued about in this
thread

I'm describing best practices based on long experience of using and
developing and teaching and writing about Python stuff. Others have
other priorities, it seems.
I just think you shouldn't assume the readers of the documentation
are aware of best practices.

--
Antoon Pardon
Oct 6 '06 #43

P: n/a
Antoon Pardon wrote:
IMO this is a very natural thought process for a python programmer.
So a python programmer seeing the first will tend to expect that
last call to work.
on the other hand, if a Python programmer *writes* some code instead;
say, a trivial function like:

def calculate(a, b):
# approximate; gonna have to fix this later
return a + b * 1.2

chances are that he did *not* intend this to be called as

calculate(a=1, b=2)

or, for that matter,

calculate(b=2, a=1)

or

calculate(1, b=2)

just because the Python calling machinery currently happens to allow
that. And chances are that he did *not* expect to be stuck with those
argument names for the foreseeable future, just because someone else
decided to interpret things in the most literal way they possibly could.

Python 2.X doesn't provide convenient support for distinguishing between
accidental and intentional argument names when you implement a function;
that's a wart, not a feature, and it may be addressed in 3.X.

</F>

Oct 6 '06 #44

P: n/a
On 2006-10-06, Fredrik Lundh <fr*****@pythonware.comwrote:
Antoon Pardon wrote:
>IMO this is a very natural thought process for a python programmer.
So a python programmer seeing the first will tend to expect that
last call to work.

on the other hand, if a Python programmer *writes* some code instead;
say, a trivial function like:

def calculate(a, b):
# approximate; gonna have to fix this later
return a + b * 1.2

chances are that he did *not* intend this to be called as

calculate(a=1, b=2)

or, for that matter,

calculate(b=2, a=1)

or

calculate(1, b=2)
Well maybe he didn't intend that, but how is the reader of the
documentation to know that? The reader can only go by how
things are documented. If those are not entirely consistent
with the intend of the programmer, that is not the readers
fault.
just because the Python calling machinery currently happens to allow
that. And chances are that he did *not* expect to be stuck with those
argument names for the foreseeable future, just because someone else
decided to interpret things in the most literal way they possibly could.
And how it the reader of the documentation to know about the
expectations of the programmer? It isn't the readers fault
if those expectations aren't easily inferred from the documenation.
Python 2.X doesn't provide convenient support for distinguishing between
accidental and intentional argument names when you implement a function;
that's a wart, not a feature, and it may be addressed in 3.X.
Again that is not the fault of those that read the documentation. If
this discinction can't be easily made in python 2.X, you can't fault
the reader for coming to a conclusion that seems to follow rather
naturally from how python currently works.

--
Antoon Pardon
Oct 6 '06 #45

P: n/a
On Fri, 06 Oct 2006 12:42:08 +0200, Fredrik Lundh wrote:
Antoon Pardon wrote:
>IMO this is a very natural thought process for a python programmer.
So a python programmer seeing the first will tend to expect that
last call to work.

on the other hand, if a Python programmer *writes* some code instead;
say, a trivial function like:

def calculate(a, b):
# approximate; gonna have to fix this later
return a + b * 1.2

chances are that he did *not* intend this to be called as

calculate(a=1, b=2)
Developers enable lots of things that they didn't intend. For example,
that function works perfectly well with complex numbers, regardless of
whether or not the developer who wrote it even knows that complex numbers
exist.

We've recently had rather vigorous argument on this list about an alleged
bug in cgi.escape, and the consensus was that it wasn't a bug, but *even
if it were* it couldn't be changed without making a backwards-incompatible
change, and therefore it wouldn't be changed.

For the developer to change the names of a and b in the above published
code would be a backwards-incompatible change.

Under the currently existing Python (rather than some future, hypothetical
Python, or some Python in an alternative reality) all Python arguments are
keyword arguments, whether the developer intends it or not. (Functions
written in C are different.)

At the very least, since names a and b are now part of his code's
published interface, he is responsible for documenting that they are
subject to change. The argument that we should assume that argument names
are subject to change unless told otherwise gets it backwards -- argument
names are part of the published interface to the code, just like the
function name, and therefore should NOT change without warning, if at all.

Now, since so many programmers seem to ignore best-practices, common
practices and even common sense, perhaps Fredrik's heuristic "don't assume
keyword args are keyword args unless explicitly told" might be good,
defensive programming -- a little like "just because the published
interface says the function returns an integer, don't assume it returns an
integer without checking" might be good, defensive practice too.

or, for that matter,

calculate(b=2, a=1)

or

calculate(1, b=2)

just because the Python calling machinery currently happens to allow
that. And chances are that he did *not* expect to be stuck with those
argument names for the foreseeable future, just because someone else
decided to interpret things in the most literal way they possibly could.
There is a convention for marking names as "touch at your own risk". That
convention isn't "everything is touch at your own risk unless told
otherwise". The convention is to use names with a leading underscore.
--
Steve.

Oct 7 '06 #46

P: n/a
On 6 Oct 2006 10:57:01 GMT, Antoon Pardon <ap*****@forel.vub.ac.bewrote:
Again that is not the fault of those that read the documentation. If
this discinction can't be easily made in python 2.X, you can't fault
the reader for coming to a conclusion that seems to follow rather
naturally from how python currently works.
It would depend on prior experience with programming (and perhaps mathematics).

-- Theerasak
Oct 7 '06 #47

P: n/a
Antoon Pardon wrote:
Well maybe he didn't intend that, but how is the reader of the
documentation to know that? The reader can only go by how
things are documented. If those are not entirely consistent
with the intend of the programmer, that is not the readers
fault.
I don't think I ever assumed that it was right to call functions
with keyword arguments if they weren't defined with keyword
parameters, but when I read 4.7.2 of the tutorial, I can see that
it's stated through an example that this is a correct thing to do.
I suppose the tutorial (and maybe the language reference) should
be corrected if this isn't supposed to be guaranteed behavior.

It seems like a bad idea to have different calling semantics
depending on whether a callable is implemented in C or Python.
Even if non-keyword parameters in Python implemented callables,
*can* be called with keyword arguments, it seems like a bad
idea to encourage that use. Perhaps it would be a good idea
to deprecate that possibility and remove it in Python 3.0?

I think it's better to force some calls into using f(*a, **kw)
instead of f(**kw) if it decreases the risk that reimplementing
functions in C in an API will break client code. Sure, it's
simple to make a Python wrapper, but if you're after raw speed,
you might not want to do that.

The main downside to removing the possibility of calling non
keyword parameters with keyword arguments might be that using
keyword arguments could fill a documentation purpose in the
code, e.g. x=get(host=arg[0], port=arg[1], path=arg[2]) would
be clearer than x=get(arg[0], arg[1], arg[2]). Of course,
host, port, path = arg; x=get(host, port, path) is even better
(if s/;/\n) but in some cases, it's better to be able to
inline things.
Oct 12 '06 #48

P: n/a
On 2006-10-12, Magnus Lycka <ly***@carmen.sewrote:
Antoon Pardon wrote:
>Well maybe he didn't intend that, but how is the reader of the
documentation to know that? The reader can only go by how
things are documented. If those are not entirely consistent
with the intend of the programmer, that is not the readers
fault.

I don't think I ever assumed that it was right to call functions
with keyword arguments if they weren't defined with keyword
parameters,
I'm not sure I follow here. AFAICS, you can't define keyword
parameters. You can give default values to parameters but
this is orthogonal to calling a function with keywords.

If we somehow want to seperate parameters in those that
can be used with a keyword and those that don't it has
to be something different than providing a default value
to that parameter.

--
Antoon Pardon
Oct 13 '06 #49

P: n/a
Antoon Pardon wrote:
On 2006-10-12, Magnus Lycka <ly***@carmen.sewrote:
>>Antoon Pardon wrote:
>>>Well maybe he didn't intend that, but how is the reader of the
documentation to know that? The reader can only go by how
things are documented. If those are not entirely consistent
with the intend of the programmer, that is not the readers
fault.

I don't think I ever assumed that it was right to call functions
with keyword arguments if they weren't defined with keyword
parameters,


I'm not sure I follow here. AFAICS, you can't define keyword
parameters. You can give default values to parameters but
this is orthogonal to calling a function with keywords.
Yup, that's a point that the documentation doesn't make stringly enough.
If we somehow want to seperate parameters in those that
can be used with a keyword and those that don't it has
to be something different than providing a default value
to that parameter.
Indeed.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Oct 13 '06 #50

50 Replies

This discussion thread is closed

Replies have been disabled for this discussion.