I saw in the PEP that "Allow more flexible assignment targets instead" was
rejected, but I actually think it's a good idea. The current PEP means there
will be two different, subtly incompatible ways to destructure objects (match
statement and iterable unpacking). The reasoning given was that most cases
involve an if-statement, but there's no reason we can't have both flexible
assignment targets and a match statement. I think unifying the concepts will
make the language more consistent and easy to learn.
I also think destructuring an object with only one possible pattern can be very
useful, without the boilerplate to set up an entire match suite and manually
raise an exception. This will make the variable assignment statement much more
powerful. I don't see a good reason to arbitrarily restrict variable assignment
to only allow sequence patterns. This might not be a good idea, but it can even
potentially be used as an assert statement, like this:
def __init__(self, version, name, point):
self.version = 1 | 2 | 3 = type # assert that "version" is between 1
and 3
self.name = str() = string # assert that "name" is the correct type
Point(0, self.y) = point # assert that "point" is on the y-axis
The constant value pattern would have to be changed to something else, like
"@constant", and even though that's also rejected, I think the benefits
outweigh the costs here. The special treatment of "_" would have to go too, but
there's no reason it can't be used as a wildcard by convention anyway, similar
to how it can already be used in for loops. I don't see any benefit in treating
it specially. Or the question mark can be the wildcard instead.
If this is done, the "match statement" will become equivalent to trying
different variable assignments. Maybe it can even be changed to look something
like this (possibly with a keyword other than "with"):
def is_tuple(node) -> bool:
with Node(children=[LParen(), RParen()]) = node:
return True
or with Node(children=[Leaf(value="("), Node(), Leaf(value=")")]) =
node:
return True
or with _ = node:
return False
def match_shape(shape):
with Point(x, y) = shape:
...
or with Rectangle(x, y, _, _) = shape:
...
def type_new(cls, *args):
with (obj,) = args:
return obj.__class__
or with (name, bases, namespace) = args:
return cls(name, bases, namespace)
or with number_of_args = len(args):
raise TypeError(f"need 1 or 3 arguments, not {number_of_args}")
which has the benefit that it's obviously the same as a variable assignment
(which also makes it obvious that "Point(x, y)" isn't a constructor call),
making the match syntax less confusing. It also makes it more intuitive because
the similar semantics with existing iterable unpacking become obvious. The
expression can be seen right next to the pattern, instead of having to be
searched higher up. It can also have different expressions matched for
different cases. Maybe it can even be possible to stack "or with" and "elif"
clauses on top of each other.
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/B7PQKBSJANORF5LKN5GFRQBL7OUAY6IE/
Code of Conduct: http://python.org/psf/codeofconduct/