5

I'm trying to do the following: After performing a regex group search, I'm trying to assign the results to the class properties by a specific order. the number of results from the regex search varies from 1-5 values.

class Classification():
    def __init__(self, Entry):
        self.Entry = Entry
        self.Section = ''
        self.Class = 'Null'
        self.Subclass = 'Null'
        self.Group = 'Null'
        self.Subgroup = 'Null'


    def ParseSymbol(self,regex):

        Properties_Pointers = [self.Section,self.Class,self.Subclass,self.Group,self.Subgroup]

        Pattern_groups = re.search(regex, self.Symbol)

        i = 0
        for group in Pattern_groups.groups():
            Properties_Pointers[i] = group
            i += 1

the problem is that for each loop iteration, instead of the class property, Properties_Pointers[i] gets the property's value (and of course in this case I can't assign the desired value to the property).

thanks.

3 Answers 3

4

Refer to attribute names instead, and use the setattr() function to store a new value on self:

def ParseSymbol(self, regex):
    attributes = ['Section', 'Class', 'Subclass', 'Group', 'Subgroup']

    Pattern_groups = re.search(regex, self.Symbol)

    for group, attr in zip(Pattern_groups.groups(), attributes):
        setattr(self, attr, group)

setattr() lets you set attributes based on a variable, here taking from attributes; there is also a companion getattr() function to retrieve attributes dynamically.

Sign up to request clarification or add additional context in comments.

Comments

1

setattr() will set the attributes of an object based on a string name. You can rewrite ParseSymbol above:

    def ParseSymbol(self,regex):

        Properties_Pointers = ['Section','Class','Subclass','Group','Subgroup']

        Pattern_groups = re.search(regex, self.Symbol)

        i = 0
        for group in Pattern_groups.groups():
            setattr(self, Properties_Pointers[i], group)
            i += 1

As a side note, you can iterate over both Pattern_groups.groups() and Pattern_Pointers simultaneously by using zip(). This cleans up the code by removing the index variable i and its incrementation:

        for pointer, group in zip(Properties_Pointers, Pattern_groups.groups()):
            setattr(self, pointer, group)

2 Comments

My original version did that, until I realized that there could be fewer groups than there are attributes.
But then again, zip() will terminate when the shortest list is exhausted anyway. I need more caffeine, clearly.
0

If you know that your regex will always contain the same number of groups, you can just use tuple unpacking:

self.Section, self.Class, self.Subclass,self.Group, self.Subgroup = Pattern_groups.groups()

7 Comments

Except that the regular expression may contain fewer groups than attributes?
Yes, but in that case the original code would also assign the matching groups to the wrong attributes so I assume that all the groups will match for the expected input.
Why would it do that? If the regex has 3 groups, then only the first three attributes are assigned to.
I was talking about the case where some groups might not match, e.g. r'(SECTION:.*?)?(CLASS:.*?)?(SUBCLASS:.*?)?'.But if there are less actual groups in the regex than there are properties, then of course tuple unpacking won't work.
Clearly the original code did not use named groups; it was expecting to work with positional groups only. :-)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.