471,306 Members | 867 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,306 software developers and data experts.

Built-in functions and keyword arguments

Why does Python give an error when I try to do this:
>>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments

but not when I use a "normal" function:
>>def my_len(object):
return len(object)
>>my_len(object=[1,2])
2

Oct 29 '07 #1
10 4730
Armando Serrano Lombillo <ar******@gmail.comwrote:
Why does Python give an error when I try to do this:
>>>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments

but not when I use a "normal" function:
>>>def my_len(object):
return len(object)
>>>my_len(object=[1,2])
2
At the C level there are several options for how you define a function
callable from Python. The most general form is
METH_VARARGS|METH_KEYWORDS which accepts both a tuple of arguments and a
dictionary of keyword arguments. These then have to be parsed to find
the actual arguments.

Many of the builtin functions use only METH_VARARGS which means they
don't support keyword arguments. "len" is even simpler and uses an
option METH_O which means it gets a single object as an argument. This
keeps the code very simple and may also make a slight difference to
performance.

I don't know if the reason that most builtin functions don't accept
keywords is just historical (someone would have to go through a lot of
code and add keyword argument names) or if there really is any
measurable performance difference to not using the METH_KEYWORDS option.
Being able to write less C code may be the main factor.
Oct 29 '07 #2
Armando Serrano Lombillo a écrit :
Why does Python give an error when I try to do this:
>>>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments

but not when I use a "normal" function:
>>>def my_len(object):
return len(object)
>>>my_len(object=[1,2])
2
In the second case, the name of the argument *is* 'object'. Which is not
the case for the builtin len (which, fwiw, has type
'builtin_function_or_method', not 'function', so inspect.getargspec
couldn't tell me more).

<ot>
While we're at it, you should avoid using builtin's names for
identifiers - here, using 'object' as the arg name shadows the builtin
'object' class).
</ot>

Oct 29 '07 #3
On Mon, 29 Oct 2007 13:52:04 +0000, Armando Serrano Lombillo wrote:
Why does Python give an error when I try to do this:
>>>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments

but not when I use a "normal" function:
>>>def my_len(object):
return len(object)
>>>my_len(object=[1,2])
2
Because len() takes no keyword arguments, just like it says, but my_len()
is written so it DOES take a keyword argument.

When you call a function foo(object=[1,2]) you are instructing Python to
bind the value [1,2] to the keyword argument "object". But if the
function doesn't have a keyword argument named "object" then it will fail
immediately. Since len() doesn't have ANY keyword arguments, naturally it
doesn't have one called "object".

You can see the same effect here:
>>def my_len2(*args):
.... return len(arg[0])
....
>>my_len2(object=[1,2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: my_len2() got an unexpected keyword argument 'object'
Apart from the error message being slightly different, many (most? all?)
of the built in functions are like my_len2().

You may be thinking that keyword arguments are the equivalent of this:

object=[1,2]
len(object)

That is not the case. They are not at all equivalent.

--
Steven.
Oct 29 '07 #4
Bruno Desthuilliers <br********************@wtf.websiteburo.oops.com >
wrote:
In the second case, the name of the argument *is* 'object'. Which is not
the case for the builtin len (which, fwiw, has type
'builtin_function_or_method', not 'function', so inspect.getargspec
couldn't tell me more).

<ot>
While we're at it, you should avoid using builtin's names for
identifiers - here, using 'object' as the arg name shadows the builtin
'object' class).
</ot>
I think you are being a little bit unfair here: help(len) says:

len(...)
len(object) -integer

Return the number of items of a sequence or mapping.

which implies that the argument to len has the name 'object' (although in
fact it doesn't have a name). The OP was simply asking about the difference
in calling conventions, not proposing to write code using 'object' as the
argument name.
Oct 29 '07 #5
><ot>
>While we're at it, you should avoid using builtin's names for
identifiers - here, using 'object' as the arg name shadows the builtin
'object' class).
</ot>

I think you are being a little bit unfair here: help(len) says:

len(...)
len(object) -integer

Return the number of items of a sequence or mapping.

which implies that the argument to len has the name 'object' (although in
fact it doesn't have a name).
And to confound matters even further for the uninitiated,

http://docs.python.org/lib/built-in-funcs.html#l2h-45

says that it's "len(s)" instead (but "len(s=[])" doesn't work either)

-tkc


Oct 29 '07 #6
On Oct 29, 3:10 pm, Duncan Booth <duncan.bo...@invalid.invalidwrote:
Armando Serrano Lombillo <arser...@gmail.comwrote:
Why does Python give an error when I try to do this:
>>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments
but not when I use a "normal" function:
>>def my_len(object):
return len(object)
>>my_len(object=[1,2])
2

At the C level there are several options for how you define a function
callable from Python. The most general form is
METH_VARARGS|METH_KEYWORDS which accepts both a tuple of arguments and a
dictionary of keyword arguments. These then have to be parsed to find
the actual arguments.

Many of the builtin functions use only METH_VARARGS which means they
don't support keyword arguments. "len" is even simpler and uses an
option METH_O which means it gets a single object as an argument. This
keeps the code very simple and may also make a slight difference to
performance.

I don't know if the reason that most builtin functions don't accept
keywords is just historical (someone would have to go through a lot of
code and add keyword argument names) or if there really is any
measurable performance difference to not using the METH_KEYWORDS option.
Being able to write less C code may be the main factor.
Ok. I was suspecting something like this. Performance issues aside, I
think it would be a good idea if built-in functions behaved exactly
the same as normal functions.

BTW, I came into this problem when trying to use functools.partial:

import functools
getattrF = functools.partial(getattr, default=False)

which I think should have worked if getattr behaved as normal
functions do.

In the end I did:

def getattrF(object, name):
return getattr(object, name, False)

Any better idea?

Oct 29 '07 #7
On Oct 29, 3:20 pm, Bruno Desthuilliers <bruno.
42.desthuilli...@wtf.websiteburo.oops.comwrote:
Armando Serrano Lombillo a écrit :
Why does Python give an error when I try to do this:
>>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments
but not when I use a "normal" function:
>>def my_len(object):
return len(object)
>>my_len(object=[1,2])
2

In the second case, the name of the argument *is* 'object'. Which is not
the case for the builtin len (which, fwiw, has type
'builtin_function_or_method', not 'function', so inspect.getargspec
couldn't tell me more).
so that's the point, built-in functions don't behave as normal
functions.
<ot>
While we're at it, you should avoid using builtin's names for
identifiers - here, using 'object' as the arg name shadows the builtin
'object' class).
</ot>
As Duncan points out, I was using the name object because it's what
you get when you type help(len) (or in the calltips, or in). Anyway, I
don't think there's any harm in overriding a builtin name in such a
small scope (the object=[1,2] won't shadow the built-in object outside
of the function).

Oct 29 '07 #8
On Mon, 29 Oct 2007 08:34:58 -0700, Armando Serrano Lombillo wrote:
On Oct 29, 3:10 pm, Duncan Booth <duncan.bo...@invalid.invalidwrote:
>>
I don't know if the reason that most builtin functions don't accept
keywords is just historical (someone would have to go through a lot of
code and add keyword argument names) or if there really is any
measurable performance difference to not using the METH_KEYWORDS option.
Being able to write less C code may be the main factor.

Ok. I was suspecting something like this. Performance issues aside, I
think it would be a good idea if built-in functions behaved exactly
the same as normal functions.
As Steven D'Aprano showed they behave like normal functions. Even pure
Python functions can have arguments without names:

def spam(*args):
pass

Ciao,
Marc 'BlackJack' Rintsch
Oct 29 '07 #9
"Tim Chase" <py*********@tim.thechases.com>
I think you are being a little bit unfair here: help(len) says:

len(...)
len(object) -integer

Return the number of items of a sequence or mapping.

which implies that the argument to len has the name 'object' (although in
fact it doesn't have a name).

And to confound matters even further for the uninitiated,

http://docs.python.org/lib/built-in-funcs.html#l2h-45

says that it's "len(s)" instead (but "len(s=[])" doesn't work either)
Looks like a gotcha to me - its the difference between a keyword
(master = 42) and an assignment (s='I am a string')

You just can't do that - how is the parser supposed to know that
the second one is an assignment and not a keyword?

len([]) should work, though.

- Hendrik

Oct 29 '07 #10
Armando Serrano Lombillo a écrit :
On Oct 29, 3:20 pm, Bruno Desthuilliers <bruno.
42.desthuilli...@wtf.websiteburo.oops.comwrote:
>Armando Serrano Lombillo a écrit :
>>Why does Python give an error when I try to do this:
>len(object=[1,2])
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
len(object=[1,2])
TypeError: len() takes no keyword arguments
but not when I use a "normal" function:
>def my_len(object):
return len(object)
>my_len(object=[1,2])
2
In the second case, the name of the argument *is* 'object'. Which is not
the case for the builtin len (which, fwiw, has type
'builtin_function_or_method', not 'function', so inspect.getargspec
couldn't tell me more).

so that's the point, built-in functions don't behave as normal
functions.
><ot>
While we're at it, you should avoid using builtin's names for
identifiers - here, using 'object' as the arg name shadows the builtin
'object' class).
</ot>

As Duncan points out, I was using the name object because it's what
you get when you type help(len)
That what I thought. But anyway, you're not the only person reading this
newsgroup, and there are a couple gotchas that are worth pointing out
for those who don't know yet.
>(or in the calltips, or in). Anyway, I
don't think there's any harm in overriding a builtin name in such a
small scope
In this specific case, possibly - because there are few chances you need
to get at the builtin object type here. Still, it's better to avoid
shadowing builtin names IMHO - if only for readability.
Oct 29 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Andrew Crook | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.