Method arguments set object attributes The code creates a meta class and its implementation to set the values passed in as arguments to methods on a class automatically on the object avoiding a lot of self.a=a code at the start of methods.

&gt;&gt;&gt; from functools import wraps
&gt;&gt;&gt; import inspect
&gt;&gt;&gt; 
&gt;&gt;&gt; def setMethodAttrs(func):
...    @wraps(func)
...    def wrapper(*args, **kwargs):
...        formalArgs=inspect.getargspec(func)[0]
...        if len(args)&gt;1:
...           for x in range(1, len(args)):
...              setattr(args[0], formalArgs[x], args[x])
...        for k, v in kwargs.iteritems():
...           setattr(vars()['args'][0], k, v)
...        return func(*args, **kwargs)
...    return wrapper
... 
&gt;&gt;&gt; def classAttrs(cls):
...     for key, val in vars(cls).items():
...         if callable(val):
...             setattr(cls,key, setMethodAttrs(val))
...     return cls
...  
... 
&gt;&gt;&gt; 
&gt;&gt;&gt; @classAttrs
... class trythis:
...    def __init__(self):
...       self.firstvar=1
...       self.secondvar=2
...       self.thirdvar=3
...       self.fourthvar=4
...    def method1(self,firstvar=None,secondvar=None,thirdvar=None):
...       print("firstvar {}".format(self.firstvar))
...       print("secondvar {}".format(self.secondvar))
...       print("thirdvar {}".format(self.thirdvar))
...       print("fourthvar {}".format(self.fourthvar))
...    def method2(self, secondvar=None, fourthvar=None):
...       print("firstvar {}".format(self.firstvar))
...       print("secondvar {}".format(self.secondvar))
...       print("thirdvar {}".format(self.thirdvar))
...       print("fourthvar {}".format(self.fourthvar))
...   
...  
... 
&gt;&gt;&gt; a=trythis()
&gt;&gt;&gt; a.method1()
firstvar 1
secondvar 2
thirdvar 3
fourthvar 4
&gt;&gt;&gt; a.method1(firstvar=9)
firstvar 9
secondvar 2
thirdvar 3
fourthvar 4
&gt;&gt;&gt; a.method2(11)
firstvar 9
secondvar 11
thirdvar 3
fourthvar 4
&gt;&gt;&gt; a.method1(19, thirdvar=21)
firstvar 19
secondvar 11
thirdvar 21
fourthvar 4
&gt;&gt;&gt; a.method2(fourthvar=40)
firstvar 19
secondvar 11
thirdvar 21
fourthvar 40
&gt;&gt;&gt;
...        if len(args)&gt;1:
...           for x in range(1, len(args)):
...              setattr(args[0], formalArgs[x], args[x])



You’re pretty much re-inventing zip here, use that instead. To extract out the first (self) parameter, you can use next (in Python 3) or slicing (in Python 2). To get a consistent behaviour accross Python versions, you can use itertools.izip in Python 2.

Something along the lines of:

arguments = zip(formalArgs, args)
_, self = next(arguments)
for name, value in arguments:
    setattr(self, name, value)


You can also define your wrapper as def wrapper(self, *args, **kwargs) to remove the need for next and already extract the value of self out of the args tuple. This will mean you’ll have to slice formalArgs though:

def wrapper(self, *args, **kwargs):
    formal_args = inspect.getargspec(func)[0][1:]
    for name, value in zip(formal_args, args):
        setattr(self, name, value)


You also don't need to inspect func at each call as, since you're using a decorator, you’re pretty much guaranteed that this object will never change during the lifetime of the program. Besides, it may be more readable to use the name, rather than the index, of the attribute you’re trying to extract out of the nametuple (since Python 2.6).

Lastly, getargspec has been deprecated since Python 3.0, so you'd better off using getfullargspec. But this function doesn't exist in Python 2, so you can try a conditional import:

from itertools import chain
from functools import wraps
try:
    # Python 3
    from inspect import getfullargspec as getargspec
except ImportError:
    # Python 2
    from inspect import getargspec
    from itertools import izip as zip


def store_attributes(method):
   arguments_names = getargspec(method).args[1:]

   @wraps(method)
   def wrapper(self, *args, **kwargs):
       for name, value in chain(zip(arguments_names, args), kwargs.items()):
           setattr(self, name, value)
       return method(self, *args, **kwargs)

   return wrapper


def class_store_attributes(cls):
    for name, value in vars(cls).items():
        if callable(value):
            setattr(cls, name, store_attributes(value))
    return cls


Usage being the same, even though I still don't get why you would use @class_store_attributes on the whole class rather than @store_attributes on a per-method basis.