Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elegantly Assign Variables of Unknown Length

Tags:

python

(Sorry. The title's pretty unclear. I couldn't come up with a good one.)

Say I have a url like so (it's root-relative):

"/forums/support/windows/help_i_deleted_sys32/6/"

and I'm trying to split this into a class structure like this:

class Forum_Spot:
    def __init__(self, url):
        parts = url.strip("/").split("/")
        #parts is now ["forums", "support", "windows", "help...", "6"]

        self.root = "forums"
        self.section = "support"
        self.subsection = "windows"
        self.thread = "help..."
        self.post = "6"

but say I don't know how long exactly the url will be (it could be "/forums/support/", "/forums/support/windows/", etc) (but I do know it won't be any deeper than 5 levels). Can anybody think of an elegant way to assign these values, letting any parts not assigned be None? (I.e. for "/forums/support/windows/", the thread and post attributes would be None)

I know I could do this:

class Forum_Spot:
    def __init__(self, url):
        parts = url.strip("/").split("/")
        #parts is now ["forums", "support", "windows", "help...", "6"]

        if len(parts) > 0:
            self.root = parts[0]
        else:
            self.root = None
        if len(parts) > 1:
            self.section = parts[1]
        else:
            #etc

but this is obviously superinelegant and obnoxiously labor-intensive. Can anybody think of a more elegant solution, keeping the class signature the same? (I could convert the __init__ function to take keyword parameters, defaulting to None, but I'd like to be able to just pass in the url and have the class figure it out on its own)

Thanks!

like image 732
marky1991 Avatar asked Dec 09 '22 14:12

marky1991


2 Answers

Use sequence unpacking:

>>> strs =  "/forums/support/"
>>> spl =strs.strip('/').split('/')
>>> a,b,c,d,e = spl + [None]*(5-len(spl))
>>> a,b,c,d,e
('forums', 'support', None, None, None)

>>> strs = "/forums/support/windows/"
>>> spl =strs.strip('/').split('/')
>>> a,b,c,d,e = spl + [None]*(5-len(spl))
>>> a,b,c,d,e
('forums', 'support', 'windows', None, None)

>>> strs = "/forums/support/windows/help_i_deleted_sys32/6/"
>>> spl =strs.strip('/').split('/')
>>> a,b,c,d,e = spl + [None]*(5-len(spl))
>>> a,b,c,d,e
('forums', 'support', 'windows', 'help_i_deleted_sys32', '6')
like image 195
Ashwini Chaudhary Avatar answered Dec 11 '22 09:12

Ashwini Chaudhary


You could add a setter method to your class that sets appropriate default values:

class Forum_Spot:
    def __init__(self, url):
        parts = url.split('/')[1:]
        # use function argument unpacking:
        self.set_url(*parts)

    def set_url(self, root, section=None, subsection=None, thread=None, post=None):
        self.root = root
        self.section = section
        self.subsection = subsection
        self.thread = thread
        self.post = post
like image 21
moooeeeep Avatar answered Dec 11 '22 09:12

moooeeeep