Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Extending the dict class

Reply
Thread Tools

Extending the dict class

 
 
chosechu
Guest
Posts: n/a
 
      08-29-2006
Hello Pythoneers:

I need to pass a list of named arguments to a function in a given
order,
and make sure these named arguments are retrieved using keys() in the
same order they were given. Example:

keyargs={}
keyargs['one']=1
keyargs['two']=2
keyargs['three']=3

myfunc(**keyargs)
-> myfunc would retrieve key arguments with keys() in the same order
as they were set, i.e. keyargs.keys() == ['one', 'two', 'three']

To achieve that, I subclassed dict and added the required lines
in __init__(), __setitem__() and keys(). I then assigned dict to
my new class but only get the desired behaviour for dictionaries
created like:
d=dict()
but not for dictionaries created like:
d={}
or
myfunc(**keyargs)

Is it possible to force dictionary creation in these case to use
my own dict class instead of the default one?

I guess we can formulate this as a more generic question: if I
want to modify the behaviour of the dictionary class, is there
any way to do it interpreter-wide so that special dict constructors
like those mentioned above use the modified version?

Thanks for helping

 
Reply With Quote
 
 
 
 
Duncan Booth
Guest
Posts: n/a
 
      08-29-2006
chosechu wrote:

> Is it possible to force dictionary creation in these case to use
> my own dict class instead of the default one?


No

> I guess we can formulate this as a more generic question: if I
> want to modify the behaviour of the dictionary class, is there
> any way to do it interpreter-wide so that special dict constructors
> like those mentioned above use the modified version?


Not without modifying and recompiling the interpreter.
 
Reply With Quote
 
 
 
 
chosechu
Guest
Posts: n/a
 
      08-29-2006

Duncan Booth wrote:
> > Is it possible to force dictionary creation in these case to use
> > my own dict class instead of the default one?

>
> No


Ouch. I was expecting something like that, thanks for confirming it.

If I may: this seems inconsistent to me. I have created an augmented
version of the class with no possibility to extend 2 of the 3 legal
constructors: {} and func(**d). While I agree changing base class
behaviour is a bad idea, since we have the possibility to re-assign
dict to another class we should be able to do it consistently, i.e.
re-assing the two special constructors too.

Just my 2c on the topic... I have found workarounds anyway.

 
Reply With Quote
 
Bruno Desthuilliers
Guest
Posts: n/a
 
      08-29-2006
chosechu wrote:
> Hello Pythoneers:
>
> I need to pass a list of named arguments to a function in a given
> order,
> and make sure these named arguments are retrieved using keys() in the
> same order they were given. Example:
>
> keyargs={}
> keyargs['one']=1
> keyargs['two']=2
> keyargs['three']=3
>
> myfunc(**keyargs)
> -> myfunc would retrieve key arguments with keys() in the same order
> as they were set, i.e. keyargs.keys() == ['one', 'two', 'three']


I'm not sure to understand why you want to do so - perhaps you could
tell more about your real use case ?

Anyway, and since it's not directly possible, a possible workaround
could be to pass a sequence of (key, value) tuples instead (possibly as
*args). This of course requires that you can modify the implementation
of myfunc().


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"
 
Reply With Quote
 
chosechu
Guest
Posts: n/a
 
      08-29-2006

> I'm not sure to understand why you want to do so - perhaps you could
> tell more about your real use case ?


Without diving into too many details: I am calling SOAPpy to build
SOAP requests. When calling a proxy, named arguments are used
to build up the corresponding XML like:

proxy.call(alpha=1, beta=2, gamma=3)
would end up like:
<alpha>1</alpha> <beta>2</beta> <gamma>3</gamma>

Unfortunately, since the arguments as retrieved with **k
their order is lost in the call. The corresponding XML file
re-arranges the parameter order randomly and the final
XML request is unordered, which is not supported by a
number of braindead SOAP servers (including one produced
by a well-known software company I will not name here).

SOAPpy cannot know in advance the argument names since
they are server-dependent and SOAPpy is generic, so retrieving
named arguments with **k seems like the sensible thing to do.
Unfortunately this gets converted to a dict so looses all ordering
when being received. Extending the base dict class to support ordering
was one possible idea.

> Anyway, and since it's not directly possible, a possible workaround
> could be to pass a sequence of (key, value) tuples instead (possibly as
> *args). This of course requires that you can modify the implementation
> of myfunc().


Yes, if I could simply modify myfunc() I would have workarounds.
This would mean me modifying SOAPpy and specializing it for
my needs.

There are other ways to implement SOAP clients anyway so
no real need. Just wanted to try out some metaclass stuff.

 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      08-29-2006
chosechu wrote:

> SOAPpy cannot know in advance the argument names since
> they are server-dependent and SOAPpy is generic, so retrieving
> named arguments with **k seems like the sensible thing to do.
> Unfortunately this gets converted to a dict so looses all ordering
> when being received. Extending the base dict class to support ordering
> was one possible idea.


If the order of the argument names matters, then it seems to me that should
be handled by the SOAP library, not pushed onto the end user whoch should
just be calling the function with the named arguments in the most
convenient order.

Shouldn't SOAPpy be able to get this information out of the WSDL?

 
Reply With Quote
 
Fredrik Lundh
Guest
Posts: n/a
 
      08-29-2006
"chosechu" wrote:

> Yes, if I could simply modify myfunc() I would have workarounds.
> This would mean me modifying SOAPpy and specializing it for
> my needs.


maybe you could fake it:

class fakedict(dict):
def __init__(self, *data):
self.data = list(data)
for k, v in data:
self[k] = v
def items(self):
return self.data

d = fakedict(("a", 1), ("b", 2), ("c", 3))

print d => {'a': 1, 'c': 3, 'b': 2}
print d.items() => [('a', 1), ('b', 2), ('c', 3)]
print isinstance(d, dict) => True

(the exact set of methods you need to override depends on how SOAPpy
fetches the members).

</F>



 
Reply With Quote
 
chosechu
Guest
Posts: n/a
 
      08-29-2006

Duncan Booth wrote:
> If the order of the argument names matters, then it seems to me that should
> be handled by the SOAP library, not pushed onto the end user whoch should
> just be calling the function with the named arguments in the most
> convenient order.
>
> Shouldn't SOAPpy be able to get this information out of the WSDL?


Yes, SOAPpy could extract this from the WSDL specs.
SOAPpy could also find another way to pass call parameters, but I kinda
like
the named parameters (seems really Python-like). Microsoft could also
build SOAP services that parse XML without making ordering mandatory
where
nobody said it was.

.... but we are living in a different dimension, one where I can extend
the Python dict class but not touch 2 of its 3 constructors (of course
the most
useful ones).

If you really want to know, I ended up at the socket level pushing
templatized
strings. Wish me luck with future server changes.

 
Reply With Quote
 
chosechu
Guest
Posts: n/a
 
      08-29-2006

> (the exact set of methods you need to override depends on how SOAPpy
> fetches the members).


[fakedict class]
This I did. And checking out the source it seems SOAPpy retrieves named
parameters through keys(), which is the method I tried to overload.
Trouble is:
something happens to my fakedict object when getting through this:
d = fakedict(...)
SOAPmethod(**d)
I have the impression **d acts like a dict constructor, taking over my
fakedict class. I know I could find the answer by scrutinizing the
source,
call me lazy.

 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      08-29-2006
chosechu wrote:

>
> Duncan Booth wrote:
>> If the order of the argument names matters, then it seems to me that
>> should be handled by the SOAP library, not pushed onto the end user
>> whoch should just be calling the function with the named arguments in
>> the most convenient order.
>>
>> Shouldn't SOAPpy be able to get this information out of the WSDL?

>
> Yes, SOAPpy could extract this from the WSDL specs.
> SOAPpy could also find another way to pass call parameters, but I
> kinda like
> the named parameters (seems really Python-like). Microsoft could also
> build SOAP services that parse XML without making ordering mandatory
> where
> nobody said it was.


Indeed, the spec says that parameterOrder is a hint and may be safely
ignored.

>
> ... but we are living in a different dimension, one where I can extend
> the Python dict class but not touch 2 of its 3 constructors (of course
> the most
> useful ones).


No, you weren't able to extend the builtin dict class nor touch any its
constructor.

All you did was to create a subclass with its own constructor and hide the
name for the builtin dictionary type. The original type was still unchanged
as you can see since anything which constructed a dictionary without using
the name you had overwritten still got the original type.

If you had looked at type(dict()) and type({}) after your subclassing, you
would see that they are different types.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Extending dict (dict's) to allow for multidimensional dictionary Ravi Python 4 03-07-2011 09:03 PM
Extending dict (dict's) to allow for multidimensional dictionary Ravi Python 3 03-07-2011 04:35 PM
dict.has_key(x) versus 'x in dict' Paul Melis Python 48 12-15-2006 05:55 PM
dict!ident as equivalent of dict["ident"] Alexander Kozlovsky Python 5 05-22-2006 08:06 AM
Re: dict->XML->dict? Or, passing small hashes through text? Skip Montanaro Python 0 08-15-2003 03:46 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57