9

I am trying to create class instance from dictionary that has keys more than class has attributes. I already read answers on the same question from this link: Creating class instance properties from a dictionary?. The problem is that I can't write __init__ in class definition as I want, because I'm using SQLAlchemy declarative style class definition. Also type('className', (object,), dict) creates wrong attributes that are not needed. Here is the solution that I found:

dict = {'key1': 'value1', 'key2': 'value2'}
object = MyClass(**dict)

But it does not work if dict has redundant keys:

dict = {'key1': 'value1', 'key2': 'value2', 'redundant_key': 'redundant_value'}
object = MyClass(**dict) # here need to ignore redundant_key

Are there any solutions except direct deleting all redundant keys from dict?

martineau
  • 119,623
  • 25
  • 170
  • 301
Demyanov
  • 901
  • 2
  • 10
  • 15
  • 1
    What is a `redundant_key`? – rafaelc May 08 '15 at 00:15
  • How do you want to write `__init__` for `MyClass`? Sorry I'm not familiar with SQLAlchemy declarative style class definitions. – Paul Rooney May 08 '15 at 00:17
  • @RafaelCardoso redundant_key is a key that exists in a dictionary, but doesn't exist in class attributes. – Demyanov May 08 '15 at 00:17
  • @PaulRooney `__init__` for MyClass such as in this answer http://stackoverflow.com/a/1639197/3700561 – Demyanov May 08 '15 at 00:21
  • So you know which keys will be input? – rafaelc May 08 '15 at 00:25
  • @RafaelCardoso Yes, I exactly know all class' attributes and dict keys and I can directly remove all "wrong keys" from dict and then use the solution that is mention above. But I don't think this is a right way – Demyanov May 08 '15 at 00:26

3 Answers3

14

Use a classmethod to filter the dict and return the object.

You then dont have to force your __init__ method to accept a dict.

import itertools

class MyClass(object):
    @classmethod
    def fromdict(cls, d):
        allowed = ('key1', 'key2')
        df = {k : v for k, v in d.iteritems() if k in allowed}
        return cls(**df)

    def __init__(self, key1, key2):
        self.key1 = key1
        self.key2 = key2

dict = {'key1': 'value1', 'key2': 'value2', 'redundant_key': 'redundant_value'}

ob = MyClass.fromdict(dict)

print ob.key1
print ob.key2
Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
1

The other solution is to Filter dict to contain only certain keys:

dict_you_want = { your_key: dict[your_key] for your_key in your_keys }
Community
  • 1
  • 1
Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
1

One of the special python magic methods of an object is object.__dict__ "A dictionary or other mapping object used to store an object’s (writable) attributes." So, by elevating this feature...

class MyClass(object):
   def __init__(self, **entries):
      self.__dict__.update(entries))

dict = {'key1': 'value1', 'key2': 'value2', 'redundant_key': 'redundant_value'}

ob = MyClass(**dict)

Note: It doesn't handle nested dictionary...

Ariel
  • 327
  • 2
  • 6