Named Arguments, Python, and PyObjC
August 31, 2005
It’s been a while since I’ve posted on here, but it’s been kinda busy these last few months.
Anyway, Today I was writing some PyObjC, I found an interesting issue: NSObject based classes don’t handle functions called with keyword arguments.
Click the More Link below to read more…
“Normal” Python has a construct that allows you to pass a variable number of “labeled” parameters to a function.
Examining The Python “Named Arguments” Syntax
Named arguments are useful in Python, like many languages, sometimes to just make the code easier to read. Sometimes named parameters allow useful tricks to be played with the language.
Take the following code, which takes one required argument, and an arbitrary number of additional named arguments. We simply print the required parameter, then iterate through the additional named arguments, printing their argument name and value.
`#!/usr/bin/env python
def myKeywordedFunction(requiredParameter, **otherParams): print “requiredParameter was”, requiredParameter print “now to tackle the passed parameters…” for each in otherParams.iteritems(): print “key =”, each[0], ”, value =”, each[1]
myKeywordedFunction(“hello world”, mine=42, powerbook=“excalibur”)`
A quick pass through the constructs to keep everybody on the same page:
-
the
**otherParams
construction means that any named arguments that aren’t explicitly in the argument list of the function should be put into a dictionary named “otherParams”.Note that we could have called
myKeywordedFunction()
like so:myKeywordedFunction(requiredParameter="hello world", mine=42, powerbook="excalibur")
-
otherParams.iteritems()
loops through a Python dictionary returning a key/value pair for every item.We also could have used the
iterkeys()
function, putting only the “current” key intoeach
. (orfor each in dictionaryVariable
, which is the same thing).To simply iterate through the values, we could have used
itervalues()
… but that’s not what we wanted. -
There’s also a “unnamed argument” syntax, which goes like:
def myArbitraryArgumentsFunction(required, *otherParams):
To call this code one would:
myArbitraryArgumentsFunction("hello world", 1, 2, 3, 4, 5, 42, excalibur)
*otherParams
is now a list of the “extra” parameters provided to the function
Named Arguments and PyObjC
A NSObject-based PyObjC class follows:
`class MyAppDelegate(NibClassBuilder.AutoBaseClass): def init(): self.mModel = [] #will be a list of dictionaries. return self
def awakeFromNib(self): self.addToModel(hello=“world”)
def addToModel(self, **nam_args): print nam_args self.mModel.append(nam_args)`
If you create a PyObjC project with this code and run it, you should see that nam_args is empty!!
My suggested workaround is: don’t do that. For this example, and for my own program, it’s easy enough to construct the dictionary by hand:
self.addToModel({'hello': 'world'})
Conclusion
I can make a hypothesis as to why this happens (I suspect python objc method conversion may have something to do with this). I’m not even sure if this is a bug or an “unintended design consequence”. I just know that it’s annoying and I spent about 15 minutes trying to figure out why my code wasn’t working. Hope to save someone else the hassle.
Have a comment? You should be able to comment using the Movable Type Comment Feature. If that’s turned off, or doesn’t work, feel free to use my Web Contact Form and I’ll insert your comments into this story myself.