6
\$\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\$
  • 3
    \$\begingroup\$ Can you add a little code, with how you'd normally use Passenger. Also, can you fix your docstring. \$\endgroup\$ – Peilonrayz Jul 25 '17 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\$ – 200_success Jul 25 '17 at 20:04
10
\$\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\$
  • \$\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 Jul 26 '17 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 Jul 26 '17 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 Jul 26 '17 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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