14
\$\begingroup\$

how can I express this idea in Pythonic way? The problem is that I want to create class with many attributes, but don't want to initialize all in __init__(self, arg1, arg2, ..., argN). Instead of this I want use some like this:

class DummyUpdater(object):

    def from_dict(self, d):
        self.__dict__.update(d)
        return self

    def __repr__(self):
        attributes = inspect.getmembers(self.__class__, lambda a: not(inspect.isroutine(a)))
        return '{}'.format({a[0]: getattr(self, a[0]) for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))})


class Passenger(DummyUpdater):
    """docstring for Passenger"""

    first_name = ''
    last_name = ''
    middle_name = ''
    title = ''
    maturity = ''
    document_number = ''
    document_type = ''

What is used now (with dummy updater):

passenger = Passenger().from_dict({'first_name' : 'Name', ...})

What I want to achive:

passenger = Passenger({'first_name' : 'Name', ...})
# and when I print passenger object I want see
print(passenger) # {'first_name' : 'Name', ...}
\$\endgroup\$
2
  • 4
    \$\begingroup\$ Can you add a little code, with how you'd normally use Passenger. Also, can you fix your docstring. \$\endgroup\$
    – Peilonrayz
    Commented Jul 25, 2017 at 11:11
  • \$\begingroup\$ Welcome to Code Review. I've downvoted this question for being a bit hypothetical, and for lacking context. What classes are there going to be, and how are you going to use them? Please provide some real examples. \$\endgroup\$ Commented Jul 25, 2017 at 20:04

1 Answer 1

18
\$\begingroup\$

Python and the power of unpacking may help you in this one,

As it is unclear how your Class is used, I will give an example of how to initialize the dictionary with unpacking. This will work on any iterable.

True to it's name, what this does is pack all the arguments that this method call receives into one single variable, a tuple called *args. The same principle applies to **kwargs too, except that in this case it applies to keyword arguments. This most of the time corresponds to dictionaries

An example on how to use **kwargs to initialise your dictionary class

class DummyUpdater(object):
    def __init__(self, iterable=(), **kwargs):
        self.__dict__.update(iterable, **kwargs)

class Passenger(DummyUpdater):
    def __init__(self, iterable=(), **kwargs):
       super().__init__(iterable, **kwargs)

# See the power of unpacking!
# We can create a class like this just with variables
d = DummyUpdater(first_name="abc", last_name='sgkf', middle_name='something else', title='ook iets', maturity='', doc_num='4', doc_type='1900')

# Or with a dictionary
d2 = Passenger({'first_name' : 'abc', 'last_name' : 'def'}) # etc..

EDIT

I am unsure if this is in scope or not, since this question doesn't address this at all, but since @Peilonrayz attended me to the usage of __slots__ I learned something myself and am willing to share this with everyone who is interested.

Secondly setting up a class this way, will imrprove memory usage a lot!

class DummyUpdater(object):
    __slots__ = ['first_name', 'last_name']
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

class Passenger(DummyUpdater):
    __slots__ = ['first_name', 'last_name']
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


# SLOTS MAGIC
# HOWTO init from variables
p = Passenger(first_name='abc', last_name='def')
print(p.first_name) # prints abs
print(p.last_name)  # prints def

# HOWTO init from a dict, notice how I unpack the dictionary to pass all the variables
p2 = Passenger(**{'first_name':'abc', 'last_name':'def'})
print(p2.first_name) # prints abc
print(p2.last_name)  # prints def
\$\endgroup\$
3
  • \$\begingroup\$ If you add __slots__ to this, then the code stops working as expected. Say you add __slots__ = ['a'] to Passenger, then use Passenger(a='A').a you'll get an AttributeError on trying to read a. \$\endgroup\$
    – Peilonrayz
    Commented Jul 26, 2017 at 9:14
  • \$\begingroup\$ You are correct, I'm still a beginner myself and to be honest never even heard of __slots__. You made me learn something new :), but I would not know how to solve this. \$\endgroup\$
    – Ludisposed
    Commented Jul 26, 2017 at 9:31
  • \$\begingroup\$ No problem Ludisposed, :) I found it only half a year or so ago. You can use setattr to fix this :) \$\endgroup\$
    – Peilonrayz
    Commented Jul 26, 2017 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.