keyword parameter order

A

Anthon

I am looking for a way to determine the order of keyword parameters
passed on to a class method.

In the source code the keyword parameters are ordered, an ordering
that is lost by putting them into a dictionary and then accessing them
by using **kw. If I had this order (either of the keyword+value pairs
or just of the keywords) I could meaningfully initialise my
ordereddict implemenation (which uses Key Insertion Order or KeyValue
Insertion Order).

I looked at traceback (which shows this info if all the keywords are
on one source line), and tracing that I found that it displays the
sourcecode line based on the code-object found in the frame stack. I
could persue that but I find the idea of reparsing the sourcecode kind
of ugly (although doable, as the keyword are never variables, and I
would not have to reevaluate the variables).

I am not sure if this kind of info is available internally to the
interpreter (ordereddict is in C, so I would even prefer that). Has
anyone done this or anything like it?

I could probably compile the python interpreter to use ordereddict
instead of dict and then the parser would insert the keyword
parameters in specification order in the **kw ordereddict, after which
iteration over parameters would be ordered. I am pretty sure though if
the 10% speed overhead of the ordereddict implementation compared to
dict is going to prevent people from using such an interpreter
version.

As an aside: I think that allowing dict to be initialised from keyword
parameters (introduced in Python 2.2 IIRC) was a mistake. This kind of
use of keyword parameters prevents any real keyword parameters. E.g.
with 'maxsize' that restricts the dictionary size or 'unique' that
would throw an Exception if an existing key gets reassigned.

Anthon
 
M

Martin v. Löwis

I am not sure if this kind of info is available internally to the
interpreter (ordereddict is in C, so I would even prefer that). Has
anyone done this or anything like it?

It's not available. See ceval.c:do_call; this fills the dictionary.
From then on, information about the order of keyword arguments is
lost.
I could probably compile the python interpreter to use ordereddict
instead of dict and then the parser would insert the keyword
parameters in specification order in the **kw ordereddict, after which
iteration over parameters would be ordered.

If you'ld do that literally, you'll find that the keyword arguments are
in reverse order.
As an aside: I think that allowing dict to be initialised from keyword
parameters (introduced in Python 2.2 IIRC) was a mistake. This kind of
use of keyword parameters prevents any real keyword parameters. E.g.
with 'maxsize' that restricts the dictionary size or 'unique' that
would throw an Exception if an existing key gets reassigned.

For your own dictionary implementation, you are not required to follow
this interface - in particular if you believe it was a mistake.

Regards,
Martin
 
T

Tim Chase

I am looking for a way to determine the order of keyword parameters
passed on to a class method.

I'm fairly certain it's not possible, as how would code like this
behave:

def my_func(**kwd):
kwd = OrderedDict(kwd) #magic happens here?
return do_something(kwd)

my_dict = {'hello':42, 'world':3.14159}
print my_func(**my_dict)

This is regularly used in lots of code. The ordering of the
contents of my_dict is already lost before the my_func() ever
gets a chance to see it. And in case one suggests trying to
sniff the source-code for the ordering, it's easy to break with
things like

my_dict = read_dict_from_file(get_filename_from_user())

where the dict and its source are completely outside the scope of
the code.

The only way around it I see is to force the user to pass in an
ordered dict explicitly:

def my_func(ordered_dict_of_kwdargs):
return do_something(ordered_dict_of_kwdargs)
my_dict = OrderedDict()
my_dict['hello'] = 42
my_dict['world'] = 3.14159
print my_func(my_dict)

-tkc
 
A

Anthon

Martin,

Thanks for pointing this out. I might have found that code eventualy
but it would
have taken me quite sometime.

There was a request from a user to make ordereddict more of drop-in
replacement for dict. That can be already be done by specifying the
relax keyword parameter (or defining a subclass that does so), but it
made me revisit the idea of investigating the keyword parameter
order..
I will just drop this idea

Thanks
Anthon
 
A

Anthon

Hi Tim,

Thanks for the comments, I obviously hadn't thought beyond the simple
case.
I am happy I wrote (and that you Martin answered) instead of trying to
program myself into a halffunctional implementation %-)

Regards
Anthon

I am looking for a way to determine the order of keyword parameters
passed on to a class method.

I'm fairly certain it's not possible, as how would code like this
behave:

def my_func(**kwd):
kwd = OrderedDict(kwd) #magic happens here?
return do_something(kwd)

my_dict = {'hello':42, 'world':3.14159}
print my_func(**my_dict)

This is regularly used in lots of code. The ordering of the
contents of my_dict is already lost before the my_func() ever
gets a chance to see it. And in case one suggests trying to
sniff the source-code for the ordering, it's easy to break with
things like

my_dict = read_dict_from_file(get_filename_from_user())

where the dict and its source are completely outside the scope of
the code.

The only way around it I see is to force the user to pass in an
ordered dict explicitly:

def my_func(ordered_dict_of_kwdargs):
return do_something(ordered_dict_of_kwdargs)
my_dict = OrderedDict()
my_dict['hello'] = 42
my_dict['world'] = 3.14159
print my_func(my_dict)

-tkc
 

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,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top