2005-12-19
Initializing Python struct objects with optional defaults
Recently I was writing code to register names and their
attributes. There were enough attributes that I didn't want to specify
all of them all of the time, so I did the obvious Python thing: I made
the register() function take a bunch of keyword arguments that had
default values. The attributes are stored with a
struct object, because I wanted an
attrs.attribute syntax for accessing them.
The straightforward way to initialize the struct object was to write
'vi = ViewInfo(factory = factory, onDir = onDir, ...)', but that
sort of repetition is annoying, especially when I had a perfectly good
set of name/value pairs in the form of register()'s arguments. If
only I could get at them.
It turns out that you can use the locals() dictionary for this, if
you use it before you set any local variables in the function. So:
class ViewInfo(Struct):
pass
def register(name, factory, onDir = False, \
onFile = True, ...):
vi = ViewInfo(**locals())
view_dict[name] = vi
(I did not strictly need the name attribute in the ViewInfo data,
but it doesn't do any harm and it meant I could use locals()
straight.)
A similar pattern can be done directly in a struct class as:
class ViewInfo:
def __init__(self, name, factory, \
onDir = False, ...):
for k, v in locals().items():
if k != "self":
setattr(self, k, v)
(You really want to exclude self, since circular references make the
garbage collector work harder than necessary.)