11

I'm creating a simple class in Python 3.6 that should accept keys,values from a dictionary as arguments

my code:

class MyClass:
    def __init__(self, **kwargs):
        for a in kwargs:
            self.a=kwargs[a]
            for b in a:
                self.a.b = kwargs[a][b]
Test = MyClass( {"group1":{"property1":100, "property2":200},\
    "group2":{"property3":100, "property4":200}})

My code returns an error:

TypeError: init() takes 1 positional argument but 2 were given

I expect Test.group2.property4 to return 200

There are many similar questions I found however main problem everywhere is absence of "self" inside init method. But I have it.

Could someone explain the reason for this error? Thanks

Dant
  • 131
  • 1
  • 1
  • 5
  • 1
    You told `__init__` to take an arbitrary number of keyword arguments, but call it with two positional arguments (one of them being implicitly provided by Python as a reference to the object created, the other one being a dictionary).. – timgeb May 25 '17 at 14:35

1 Answers1

27

Pass the parameter(s) as an unpacked dict, not as a single positional argument:

MyClass(**{"group1":{"property1":100, "property2":200},\
    "group2":{"property3":100, "property4":200}})
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • 3
    equivalent: `MyClass(group1={"property": 100, ...)` – mdurant May 25 '17 at 14:38
  • Thank you. And then it appears a KeyError 'g' on line "self.b = kwargs[a][b]" So it doesn't want to open a dict in side a dict. Also if I try to left in the code only one for loop, dir(MyClass) returns (... a) instead of (...group1, group2). it means self.a doesn't convert itself into self.group1 when initializing. – Dant May 26 '17 at 10:49
  • Does your suggested code works for you or it also gives a KeyError? MyClass(**{"group1":{"property1":100, "property2":200},\ "group2":{"property3":100, "property4":200}}) – Dant May 26 '17 at 10:52
  • The problem is not with that line of code. It's with the for loop. `for b in a` should be `for b in kwargs[a]`, since `a` is a key not a dictionary. There are other problems with your code tho... – Moses Koledoye May 26 '17 at 10:55
  • As the result I found possible to __init__ nested dictionaries to kwargs using: `Class MyClass(object): def __init__(self, **kwargs): for key, value in kwargs.items(): val = value if isinstance(val, dict): val = MyClass(**val) setattr(self,key,val)` – Dant May 26 '17 at 14:14
  • If you already have a dictionary with they keywords, you could just pass your arguments like so: `MyClass(group1={"property1": 100, "property2": 200}, group2={"property3": 100, "property4": 200})` – Bobort Dec 28 '17 at 17:05