Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python decorator to automatically define __init__ variables

I've got fed up of continually typing the same, repetitive commands over and over again in my __init__ function. I was wondering if I could write a decorator to do the work for me. Here's an example of my question:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

Is there some way in which I can automatically have all arguments passed into the function become instance variables with the same names? For example:

class Point:
    @instance_variables
    def __init__(self, x, y):
        pass

Where @instance_variables would automatically set self.x = x and self.y = y. How could I do this?
Thanks!

EDIT: I should mention that I use CPython 2.7.

like image 882
QuantumFool Avatar asked Feb 10 '15 22:02

QuantumFool


People also ask

How do you initialize a variable in init Python?

When you create a new object of the class, Python automatically calls __init__() right away to initialize the new object. But in fact, the standard way to initialize an object's values when creating objects is to use __init__( ) method in class.

Why do we use decorators in Python?

You'll use a decorator when you need to change the behavior of a function without modifying the function itself. A few good examples are when you want to add logging, test performance, perform caching, verify permissions, and so on. You can also use one when you need to run the same code on multiple functions.

What's a decorator in Python?

Decorators provide a simple syntax for calling higher-order functions. By definition, a decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.

What is decorator in Python with example?

A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate.


1 Answers

Here is my first try at the decorator:

[EDIT second try: I added handling defaults for variables and checking for valid keywords. Thanks ivan_pozdeev ]

[EDIT 3: Added check for defaults is not None]

def instanceVariables(func):
    def returnFunc(*args, **kwargs):
        selfVar = args[0]

        argSpec = inspect.getargspec(func)
        argumentNames = argSpec[0][1:]
        defaults = argSpec[3]
        if defaults is not None:
            defaultArgDict = dict(zip(reversed(argumentNames), reversed(defaults)))
            selfVar.__dict__.update(defaultArgDict)

        argDict = dict(zip(argumentNames, args[1:]))
        selfVar.__dict__.update(argDict)


        validKeywords = set(kwargs) & set(argumentNames)
        kwargDict = {k: kwargs[k] for k in validKeywords}
        selfVar.__dict__.update(kwargDict)

        func(*args, **kwargs)

    return returnFunc

Here is a example:

class Test():

    @instanceVariables
    def __init__(self, x, y=100, z=200):
        pass

    def printStr(self):
        print(self.x, self.y, self.z)

a = Test(1, z=2)

a.printStr()

>>> 1 100 2
like image 195
ashwinjv Avatar answered Nov 07 '22 12:11

ashwinjv