46

I have a class defined as follows

class M(object):
    def __init__(self, **kwargs):
        ...do_something

and I have the result of argparse.parse_args(), for example:

> args = parse_args()
> print args
Namespace(value=5, message='test', message_type='email', extra="blah", param="whatever")

I want to pass on the values of this namespace (except message_type) to create an instance of the class M. I have tried

M(args)

but got an error

TypeError: __init__() takes exactly 1 argument (2 given)

which I do not understand. How can I

  1. remove the value message_type from the list in args
  2. pass on the values as if I would type M(value=5, message='test', extra="blah", param="whatever") directly.
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Alex
  • 41,580
  • 88
  • 260
  • 469

1 Answers1

66

You need to pass in the result of vars(args) instead:

M(**vars(args))

The vars() function returns the namespace of the Namespace instance (its __dict__ attribute) as a dictionary.

Inside M.__init__(), simply ignore the message_type key.

Alonme
  • 1,364
  • 15
  • 28
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Thats exactly what I need. Thanks. Except for removal of the certain key. I need it to be removed, I cannot just ignore it for reasons outside the scope of this question. – Alex Mar 04 '13 at 16:22
  • 2
    I suggest to do `arg_dict = dict((k,v) for k,v in vars(args).items() if k!="message_type")` to avoid possible undefined behaviour with `vars`. – Alex Mar 04 '13 at 16:28
  • @Alex: what undefined behaviour with `vars`? You can filter out the `message_type` key that way, sure, but do that for it's own sake, not because `vars()` might have undefined behaviour (which it doesn't). – Martijn Pieters Mar 04 '13 at 16:30
  • @Alex: I'd rather make the `M` class more robust in the face of extra keyword arguments it doesn't support. – Martijn Pieters Mar 04 '13 at 16:30
  • Note From the documentation of vars: `The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined. [2]`. As for your suggestion, `M` can be one of many classes absolutely detached from what I am doing here. These classes cannot possibly know of some abundant keyword (and might give an error otherwise). Let's say, those classes cannot be modified. – Alex Mar 04 '13 at 16:48
  • 1
    @Alex: The values are *copied* into the `M.__init__` parameters, so the original mapping is never modified. If you need to regulate what keywords are passed in, use a whitelist instead. – Martijn Pieters Mar 04 '13 at 16:49