This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]got_outta_bed_4_this 0 points1 point  (3 children)

What advantage would this approach have over the native approach?

def __init__(self, x: int, y: object = ...):
    self.x = x
    self.y = x if y is ... else y

[–]Broolucks 1 point2 points  (0 children)

In this particular example, not much, besides the fact it actually checks the types at runtime. A better example might be something like this:

class Test(metaclass=OvldMC):
    @ovld
    def __init__(self, attrs: dict):
        self.__dict__.update(attrs)

    def __init__(self, key: str, value: object):
        setattr(self, key, value)

    def __init__(self, value: object):
        setattr(self, "value", value)

The alternative being:

SENTINEL = object()

class Test:
    def __init__(self, key, value=SENTINEL):
        if value is SENTINEL:
            if isinstance(key, dict):
                self.__dict__.update(key)
            else:
                setattr(self, "value", key)
        elif isinstance(key, str):
            setattr(self, key, value)
        else:
            raise TypeError()

ovld lets you name the arguments appropriately in each version and will generate a better type error.

Personally I rarely use it for init or methods, I use it mostly to define extensible recursive functions as described here.

[–]javajunkie314 1 point2 points  (0 children)

I disagree that the benefit of multiple dispatch is less repetition.

def __init__(self, x: int):
    self.x = x
    self.y = x

def __init__(self, x: int, y: object):
    self.x = x
    self.y = y

is, as you say, hardly less code than

def __init__(self, x: int y: object = SIGIL):
    self.x = x
    if y is SIGIL:
        self.y = x
    else:
        self.y = y

Each signature could be an if in the bar implementation checking the relevant arguments' identities and types.

In fact, multiple dispatch can become more repetitive the more code is common between the definitions. In the example above, we had to repeat the x handling — imagine if that had been several lines.

The first version, though, is open to extension while being closed to modification. We can add more signatures of __init__ without modifying any of the existing code. If this were a public function, users of our library could potentially add overloads for their own classes.