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.
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With