1

I came across a method in Python that returns a class, but can be destructured as if it's a tuple.

How can you define a result of a function to be both an instance of a class AND use destructure assignment as if it's a tuple?

An example where you see this behavior:

import scipy.stats as stats

res = stats.ttest_ind(data1, data2)

print(type(res)) # <class 'scipy.stats.stats.Ttest_indResult'>

# One way to assign values is by directly accessing the instance's properties.
p = res.pvalue
t = res.statistic

# A second way is to treat the result as a tuple, and assign to variables directly. But how is this working? 
# We saw above that the type of the result is NOT a tuple but a class. How would Python know the order of the properties here? (It's not like we're destructuring based on named properties)
t, p = stats.ttest_ind(data1, data2)
Don P
  • 60,113
  • 114
  • 300
  • 432
  • 2
    Something like [this](https://stackoverflow.com/questions/37837520/implement-packing-unpacking-in-an-object) maybe – Fractalism Jan 28 '23 at 18:37

2 Answers2

2

It's a named tuple, which is basically an extension to tuple type in python.

altunyurt
  • 2,821
  • 3
  • 38
  • 53
0

To unpack a data type with a, b = some_object, the object on the right side needs to be iterable. A list or tuple works, obviously, but you can make your own class iterable by implementing an __iter__ method.

For example, the following class would behave consistently with the interface you've shown the Ttest_indResult class to have (though it's probably implemented very differently):

class MyClass:
    def __init__(self, statistic, pvalue):
        self.statistic = statistic    # these attributes are accessible by name
        self.pvalue = pvalue

    def __iter__(self):               # but you can also iterate to get the same values
        yield self.statistic
        yield self.pvalue
Blckknght
  • 100,903
  • 11
  • 120
  • 169