Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What does <type>.<attr> do during a match/case?

In general, the code <type>(arg1=value1) is changed to the code <type>(attr1=value1) during a case in a match statement. This allows for some very interesting and complex capturing.

For example, we can ask "does my instance have a attr called ‘sort’, if so capture it":

match [1,2,3]:
    case list(sort=f): # this isn't a call, it is an attr-capture statement
        print(f)

Since the first (and only) positional argument of the list instance is the list values, you can capture those items as well:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

match [1,2,3]:
    case list((x,*y),sort=f): # here we are capturing the 'attr' called 'sort' as 'f'
        print(x,y,f)

Likewise, you can specify the matching values instead of capturing them into variables:

g = list.sort
match [1,2,3]:
    case list((1,*y),sort=g):  # here we ask if the attr 'sort' is the same as 'g'
        print(y)

However, I am now confused by the following:

match [1,2,3]:
    case list(x,sort=list.sort):  # fails to match, but why???
        print(x)

I would have thought that this fails because list.sort means something different than to specify "the function ‘sort’ of ‘list’". Maybe sort=list.sort means "do I have an attr called ‘sort’ which itself is of ‘type’ ‘list’ that also has an attr called ‘sort’". So I tried:

match [1,2,3]:
    case list.sort:  # also fails, why?
        print('ya')

So, list.sort does not mean that I want type list with an attr of sort. So, then I tried:

match list.sort:
    case list.sort: # does match, wait, what?
        print('ya')

Which works. So, list.sort during a case does mean to use the function of sort from the type of list, but then why did list(sort=list.sort) fail?


Example of capturing an attr ‘y’ and matching an attr ‘x’:

class P:
    def __init__(self,a,b):
        self.x,self.y = a+b,a-b
match P(5,6):
    case P(x=11,y=a): # a is a new variable, 11 is a match
        print(a)

>Solution :

list.sort is a descriptor, so it’s not going to match sort= which will be a method or function.

You can see the type of f is a built-in method:

match [1,2,3]:
    case list(x,*y), sort=f): # inspect the capture of `sort` as `f`
        print('match', f) # match <built-in method sort of list object at 0x104d94c80>

But the type of list.sort is not:

>>> type(list.sort)
method_descriptor
>>> list.sort is [1,2,3].sort
False

But if you use the method from the same list instance, this works:

foo = [1,2,3]
match foo:
    case list((x, *y), sort=foo.sort):
        print('matched')

But this doesn’t make much sense to me to match on the sort attribute, as it’s different for each instance of a list:

>>> x = [1,2,3]
>>> y = [1,2,3]
>>> x.sort is y.sort
False
>>> x.sort == y.sort
False
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading