|
Prev: Segmentation Fault
Next: python loops
From: chosechu on 29 Aug 2006 08:01 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
From: Duncan Booth on 29 Aug 2006 08:05 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.
From: chosechu on 29 Aug 2006 08:17 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.
From: Bruno Desthuilliers on 29 Aug 2006 08:21 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 'onurb(a)xiludom.gro'.split('@')])"
From: chosechu on 29 Aug 2006 08:35
> 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. |