Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

saving constructor arguments automatically

Frequently the constructor of a class will take it's arguments and save them on the instance. For example:

class Example(object):
    def __init__(self, title='',backtitle='', height=20, width=50):
        self.title = title
        self.backtitle = backtitle
        self.height = height
        self.width = width

This is repetitious so I made a helper function to do this automatically:

from inspect import getargspec
def save_args(values):
    for i in getargspec(values['self'].__init__).args[1:]:
        values['self'].__dict__[i] = values[i]

class Example(object):
    def __init__(self, title='',backtitle='', height=20, width=50):
        save_args(vars())

My questions are as follows:

  • Will this fail with certain classes or agruments
  • Is it portable, will it work on Jython, etc.. It worked for me on python 2.7 and 3.2
  • Is there a simpler alternative?
  • Is there a python package out there that already does this?
like image 950
Marwan Alsabbagh Avatar asked Mar 18 '13 18:03

Marwan Alsabbagh


2 Answers

It'll fail when your class uses __slots__. You could use setattr() instead:

from inspect import getargspec
def save_args(values):
    for i in getargspec(values['self'].__init__).args[1:]:
        setattr(values['self'], i, values[i])

provided the arguments keyword arguments to __init__ are all declared slots of course.

Otherwise this should work on any Python implementation.

You may be interested in a previous discussion of the topic, which sparked a Python-ideas list thread.

like image 93
Martijn Pieters Avatar answered Oct 24 '22 08:10

Martijn Pieters


This requires you to write more code, silently ignores all erroneous arguments to the Example constructor, and doesn't support positional arguments to the Example constructor, but avoids use of inspect:

def save_args(obj, defaults, kwargs):
    for k,v in defaults.iteritems():
        if k in kwargs: v = kwargs[k]
        setattr(obj, k, v)

class Example(object):
    def __init__(self, **kwargs):
        defaults = { 'title': '',
                     'backtitle': '',
                     'height': 20,
                     'width': 50 }
        save_args(self, defaults, kwargs)
like image 27
zwol Avatar answered Oct 24 '22 09:10

zwol