Assume I have many expression similar to
class X:
def __init__(self, a,b,c,d,e,f):
self.a = a
self.b = b
self.c = c
self.d = d
self.e = e
self.f = f
Is there an elegant way to rewrite this?
Thanks!
Starting from Python 3.7, It could be done using data classes
@dataclass
class X:
a: int
b: str
c: float
# etc...
The dataclass decorator automatically generates the suitable __init__ method.
As @Lie Ryan commented, you could also use namedtuple:
>>> X = namedtuple('X', ('a', 'b', 'c'))
>>> x = X(1, 2, 3)
>>> x
X(a=1, b=2, c=3)
>>> x.a
1
It can even be inherited to add or overload methods:
>>> class X(namedtuple('XSuper', ('a', 'b', 'c'))):
... def __repr__(self):
... return 'pouet'
...
>>> x = X(1, 2, 3)
>>> x
pouet
>>> x.a
1
The answer from fountainhead is also a nice version-agnostic trick.
class X:
def __init__(self, a,b,c,d,e,f):
self.a = a
self.b = b
self.c = c
self.d = d
self.e = e
self.f = f
class X:
def __init__(self, *args):
arglist = ['a', 'b', 'c', 'd']
for i in range(0, len(arglist):
try:
setattr(self, arglist[i], args[i])
except IndexError:
raise Exception('Arg {} needs to be given a value'.format(arglist[i]))
Does not look like the most elegant thing everbut the longer the list the more simplified, also you only need to modify arglist and it will be reflected. Bad thing, you lose the signature (any non runtime checks you could make are lost, e.g. your IDE will freak out
Other suggestions include enumerate (cleaner way to work with indices).
Or you could just use zip, and do the check at the begginign:
class X:
def __init__(self, *args):
arglist = ['a', 'b', 'c', 'd']
if len(arglist) != len(args):
raise CustomExceptino('Too few/many arguments...')
for keyval_tuple in zip(arglist, args):
setattr(self, keyval_tuple[0], keyval_tuple[1])
Note that you can still add arguments that don't behave this way:
class X:
def __init__(self, special_arg, *args):
self.special_consequence = self.do_sth_with_special_arg(special_arg)
arglist = ['a', 'b', 'c', 'd']
if len(arglist) != len(args):
raise CustomExceptino('Too few/many arguments...')
for keyval_tuple in zip(arglist, args):
setattr(self, keyval_tuple[0], keyval_tuple[1])
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