JAvila-R
JAvila-R

Reputation: 43

How does value asignments within Tuples in Python work?

While working on a script in Python, I came accross this built-in method part of the sys module sys.flags which returns a tuple of flags used to run the python script. The output looks like:

(debug=0, inspect=0, interactive=0, optimize=1, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=0, hash_randomization=1, isolated=0, dev_mode=False, utf8_mode=0)

I'm confused, as I thought you could not embed an assignment within another expression in Python, and so far I haven't been able to find an answer on Google that explains the behavior of this tuple.

Upvotes: 1

Views: 91

Answers (3)

MSeifert
MSeifert

Reputation: 152745

The output doesn't show a tuple:

>>> import sys
>>> sys.flags
sys.flags(debug=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=0, hash_randomization=1, isolated=0, dev_mode=False, utf8_mode=0)
>>> type(sys.flags)
<class 'sys.flags'>

A tuple would look like this:

>>> tuple(sys.flags)
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, False, 0)

It actually returns an instance of a class that has a custom representation.

Note that this is a typical representation for a "data-class". It shows how such an object was created or could be created. For example namedtuple have a similar representation (not an accident because sys.flags is a namedtuple!):

>>> from collections import namedtuple
>>> Person = namedtuple('Person', 'name, age')
>>> Person(20, 'me')
Person(name=20, age='me')
>>> Person(name=20, age='me')
Person(name=20, age='me')

Upvotes: 2

ForceBru
ForceBru

Reputation: 44888

The actual output is:

>>> sys.flags
sys.flags(debug=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=0, hash_randomization=1, isolated=0, dev_mode=False, utf8_mode=0)

That sys.flags before the opening parenthesis is crucial. It shows that sys.flags is something else than a tuple.

Yet you could totally create a class whose __repr__ method would return this kind of tuple-like representation:

class Weird:
    def __init__(self, a, b):
        self.a, self.b = a, b

    def __repr__(self):
        return f"(a={self.a}, b={self.b})"

Then the output will look like this:

>>> Weird(1,2)
(a=1, b=2)

But Weird is definitely not a tuple.

Upvotes: 3

Tomerikoo
Tomerikoo

Reputation: 19432

Indeed, doing:

isinstance(sys.flags, tuple)

will return True. But that is because sys.flags is a named-tuple, which inherits from the tuple type. From the docs:

The term “named tuple” applies to any type or class that inherits from tuple and whose indexable elements are also accessible using named attributes.

Upvotes: 2

Related Questions