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