Le 26/04/17 à 19:46, Mike Miller a écrit :

On 2017-04-26 04:12, Brice PARENT wrote:
Why not simply do this :

class MyClass:
    def _set_multiple(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

    def __init__(self, a, b, c):
        self._set_multiple(a=a, b=b, c=c)

If the goal is to not have to type out argument names three times (in DRY fashion), this doesn't quite fit the bill.

-Mike

You still save some typing (no need for self. for every assignment), and a lot of vertical space.

Also, it allows you to use any dict (like **kwargs) as well as doing very common things like :

class MyClass:
    def _set_multiple(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

    def __init__(self, a, b, c):
        self._set_multiple(a=a, _b=b)

which is equivalent to the following really common pattern :

class MyClass:
    def __init__(self, a, b, c):
        self.a = a
        self._b = b

(well, I didn't try it, but it should work)
This means your public API (the signature of the constructor here) has no incidence on the way the class works on the inside. Meaning an attribute can become a property, which is something that occurs from time to time, and you just need to update your constructor (self._set_multiple(a=a, b=b) becomes self._set_multiple(a=a, _b=b)) and you're done.
And if at some point your community doesn't think "a" is a good name for your variable, you can update it to something every user will understand without any significant change to your class (self._set_multiple(a=way_better, _b=b)).

-Brice