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.)