johnramsden
johnramsden

Reputation: 291

Is there a more pythonic way to have multiple defaults arguments to a class?

I have a class with many defaults since I can't function overload. Is there a better way than having multiple default arguments, or using kwargs?

I thought about passing a dictionary in to my class but then how do I control whether or not the necessary arguments will be passed in?

If there's a more pythonic way to have arguments be allowed without defining them all as defaults?

For example, i'm allowing many defaults:

class Editor:
    def __init__(self,
                 ffmpeg: str,
                 font_file=None,
                 font_size=148,
                 font_color="white",
                 title_length=5,
                 title_x="(w-text_w)/2",
                 title_y="(h-text_h)/2",
                 box=1,
                 box_color="black",
                 box_opacity=0.5,
                 box_border_width=25):

        self.ffmpeg = ffmpeg

        self.title s= define_title(
            font_file, font_size, font_color, title_length)

        self.box = define_box(
            box, box_color, box_opacity, box_border_width},

        self.coordinates = {"x": title_x, "y": title_y}

Where in other languages I might overload the constructor.

Upvotes: 6

Views: 1043

Answers (2)

Tore Eschliman
Tore Eschliman

Reputation: 2507

You can specify default attributes on the class object itself if you expect them to be pretty standard, which can then be obscured by re-assigning those attributes on the instance when desired. You can also create multiple constructors using @classmethod, if you want different groups of arguments to be passed in.

class Editor(object):
    font_file = None
    font_size = 148
    def __init__(self, ffmpeg=str):
        self.ffmpeg = ffmpeg
    @classmethod
    def with_box(cls, ffmpeg=str, box=1):
        new_editor = cls(ffmpeg)
        new_editor.box = box
        return new_editor

And then you would call:

Editor.with_box(ffmpeg=int, box=2)

and get back a properly box-initialized Editor instance.

Upvotes: 3

Ami Tavory
Ami Tavory

Reputation: 76297

One way is to use method chaining.

You can start with some class setting all (or most) parameters to defaults:

class Kls(object):
    def __init__(self):
        self._var0 = 0
        self._var1 = 1

Then you add methods for setting each needed one:

    def set_var_0(self, val):
        self._var0 = val
        return self

    def set_var_1(self, val):
        self._var1 = val
        return self

Now, when you create an object, you can just set the necessary ones:

c = Kls()

c = Kls().set_var_1(2)

c = Kls().set_var_1(22).set_var_0(333)

Of course, you are not restricted to writing a method that sets a single parameter each time, you could write methods that set small "families" of parameters. These already might have regular default values, if needed.

Upvotes: 1

Related Questions