Automate boring constructors that simply create lots of private member variables.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | def vars_private(func):
def wrapper(*args):
for i, arg in enumerate(args[1:]):
setattr(args[0], '_' + func.func_code.co_varnames[i + 1], arg)
return func(*args)
return wrapper
# -- Test --
class Student:
@vars_private
def __init__(self, name, age):
# make young
self._age = self._age - 2
def info(self):
return self._name, self._age
s = Student('Ravi Teja', 28)
print s.info()
|
It is all too common to use the constructor to simply assign private variables. This decorator automates that boring code.
So instead of class MyClass: ....def __init__(self, first, last, age, email, address, zip, state, country): ........self._first = first ........self._last = last ........self._age = age ........self._email = email ........self._address = address ........self._zip = zip ........self._state = state ........self._country = country ........print 'New class created'
simply becomes
class MyClass: ....@vars_private ....def __init__(self, first, last, age, email, address, zip, state, country): ........print 'New class created'
Just fiddle with the for loop in the decorator to customerize it further
Gotcha: You can put further code in the constructor but be sure to use the newly created member variables rather than the function arguments as the member variables are not automatically updated by the results of such modifications
eval() is not necessary. You can remove the eval() call and replace it with just
.
Defaults and keyword arguments. The following will also handle defaults and keyword arguments. It still does not handle possible errors and will fail badly if you miss the correct signature.
Much simpler way.
Yes! But ... Simple. Yes! But not quite the same.
This requires that all instantiations use named arguments which could get tiedious if there are several being done. And argument mismatch at instantiation passes by silently.