1

Python has the 2 operators * and ** for packing and unpacking of parameters, e.g.

print(*[1,2,3,4])

or

def test(*args, **kwargs):
    ...

There is no mention of these operators in the operator module, and there is no way to overwrite them. For example, this could be a thing:

class Test(object):

    def __init__(self):
        self.a = 5
        self.b = 10

    def __starstar__(self):
        # Not to be confused with __pow__!
        # Should return something that can be unpacked by the default ** operator
       return {"a": self.a, "b": self.b}

def print_a_b(a, b):
    print(f"a is {a} and b is {b}")

print_a_b(**Test())
# Should be unpacked into a and b parameters
# and print "a is 5 and b is 10"

It kind of works with the * operator and iterables:

class Test2(object):

    def __iter__(self):
        yield from range(10)

print(*Test2())
# prints "0 1 2 3 4 5 6 7 8 9"

I understand that we can not use ** and __getitem__, since we don't know the items that may be present. But why is there no operator that can be overwritten for **, and why is there no operator in the operator module for * and **?

One reason I could think of is that this would contribute to coupling in the wrong direction between classes, i.e. Test now implicitly knows about the signature of print_a_b.

A better use case might be a Config class that does some additional setup and can then be passed to another function, e.g run(**Config()).

RunOrVeith
  • 4,487
  • 4
  • 32
  • 50
  • What *would* be in the operator module? That syntax isn't an operator, and `tuple` and `dict` already exist. – jonrsharpe Jan 02 '19 at 15:17
  • Couldn't it be considered a binary operator? I understand that this is not how it is currently built, but why not? – RunOrVeith Jan 02 '19 at 15:20
  • Definitely not *binary*, given only one "operand"... But you seem to be confusing several things (the operator module, the data model, magic methods) so the question is still unclear. You *can* implement both `*` and `**` unpacking, per the duplicates. – jonrsharpe Jan 02 '19 at 15:30
  • how else would you call it if not binary? There is exactly one operand, which is the object itself. For the operator module, I was thinking of something like `d = dict(map(operator.starstar, list_of_dicts))` – RunOrVeith Jan 02 '19 at 16:51
  • Sorry I mean unary of course, not binary – RunOrVeith Jan 03 '19 at 09:45

0 Answers0