Object destructuring in Python

It was decided long ago that there wasn’t going to be a Python 4 with the same level of breakage involved with the transition from Python 2 to Python 3.

1 Like
  • it’s very unlikely that there will ever be a python 4
  • if there is, it’s not worth discussion ideas for it now
  • even with python 4, this is not going to happen. I don’t think you are properly understanding what the code currently means

If you want a different language, go create a different language. Or use Php. But suggesting features that are fundamentally incompatible with currently existing features is not going to get you far.

This like suggesting that it would be far better to for a(b) to mean multiplication. Sure, maybe correct in some context. Still not going to happen in python.

1 Like

I think it is possible to port some good bits of match to assignment.
Spec is worked out for a lot of things. E.g.:

{'a': 1, 'b': 2, **rest} = {"a": 1, "b": 2, "c": 3}

Isn’t this another instance of a proposal for match as an assignment syntax?

I like the idea of using the existing soft keyword and destructuring match syntax for this. Something like…

match Person(age=age) = a_person
print(age)

(It can raise an exception on a failed match)

But if that’s too verbose for the OP, then I agree with the comments that this is just not going to happen.

5 Likes

This tightens the barrier between raising an error and silently propagating a false statement. I think it is deteimental for python usage safety.

But I would definitely be happy with a way to unpack dict values to variables without having to write the names twice. I would better like something like

name, age **= person.as_dict()

Or whatever is OK to use in place of **= here.

1 Like

Unfortunately your preferred syntax is already take (it’s unpacking). The Pythonic way to do what you want is to use a match statement.

Also, I disagree that “leaner” code is a good idea for the reason you mention (“to write simple code”). The match is concise and clear for readers. And code readers (not writers) are the people who matter.

If Python ever adds a way to do this, it will almost surely be something like:

{"name": n, "age": a} = person.as_dict()

This is already in the Python code, but is explicitly blocked.

But I doubt it will be allowed since I think it’s been proposed a few times and never found traction. Especially now with match statements, the need for this is dwarfed by the added complexity.

1 Like

While I don’t always think that quoting the “Zen of Python” helps in a discussion, in this case I think it is useful, because it contrasts with your characterisation of Python here. In particular, the principle “Explicit is better than implicit” applies here. You propose:

name, age = person

The link between the target variables and the attribute names for the Person class is completely implicit - you have to know that’s what will happen, and there’s no indication that it will (if person were a tuple, the behaviour would be completely different). That’s unlike anything else in Python, and would be very confusing for experienced Python developers (and probably for many new users, who aren’t familiar with the Javascript feature).

Also, your proposal breaks existing code, and worse, it does so silently. Consider the following class:

# This is working code in current Python
@dataclass
class Family:
    father: str
    mother: str
    children: list[str]
    def __iter__(self):
        yield from self.children

f = Family("dad", "mom", ["joe", "amy"])
father, mother = f
father
# This prints 'joe', not 'dad'!!!
mother
# This prints 'amy', not 'mom'!!!

The fact that you don’t get “dad” and “mom” here is not an error - it’s how the class was designed to work (iteration returns the children, not the parents).

Changing that behaviour simply isn’t an option. You’re welcome to come up with a different proposal, but as it stands, your suggested syntax has no chance of being accepted.

6 Likes

Can we re-purpose walrus operator for this?

E.g.:

name, age := person

I have never seen anyone using it.

No.

That’s irrelevant. Many people do use it, just because you haven’t seen them doesn’t prove anything.

Comments like this do nothing to help your case, they simply give the impression that you’re not serious about helping improve Python.

11 Likes

What if we adopt JS syntax:

{ name, age } = person

About “using/not using”. I am engineer and I trust numbers. If someone will say this operator is actively used in more than 1% of popular packages then I do agree, it is helpful and useful.

How Python as a project tracks the usage of the features?

You’re proposing a language change. It’s up to you to do the research, understand the process (such as “you can’t break existing code”) and come up with numbers yourself. No-one else will do that work for you.

As an engineer, you should be used to being expected to provide numbers, as well. That applies here.

6 Likes

1% is huge. Mindbogglingly huge. If 0.1% of packages are using something, that’s still a very large number. We don’t break things just because fewer than 1% of people are using them.

I would draw an analogy but I’m scared that there are people who really would think tha way (like “less than 1% of people walk to work, so we don’t need any pedestrian infrastructure”). Fortunately, that’s not how Python is run.

I think the JS style syntax is a much more reasonable one, but throwing it out there as a brief “what if” is not a language proposal. Start over. Read vital documents like PEP 1, particularly the section “Start with an idea for Python”, which talks about the steps prior to writing a PEP. There needs to be a lot more effort put into the proposal and, especially, understanding how it will fit into the Python ecosystem as a whole. Notably, “Python 4” is NOT the answer to all backward compatibility concerns.

6 Likes

Thank you, I will study PEP 1.

It looks like js like

{ name, age, other_attribute } = person 

is our best bet at this moment. It is laconic and easy to understand.