2013-07-02 84 views
4

的優雅分配變量(對不起標題的不太清楚我不能想出一個好。)長度未知

說我有像這樣(它的根目錄相對)的URL:

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

,我想這個分成階級結構是這樣的:

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" 

而且說我不知道​​過了多久究竟將URL(也可能是「/論壇/支持/ 「,」/ forums/support/windows /「等)(但我知道它不會超過5級)。任何人都可以想到一個優雅的方式來分配這些值,讓任何未分配的部分爲None? (例如,對於「/論壇/支持/窗/」,線程和後屬性將無)

我知道我可以做到這一點:

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 

但這顯然superinelegant和令人討厭勞動密集型。任何人都可以想到更優雅的解決方案,保持類簽名相同嗎? (我可以轉換__init__功能採取關鍵字參數,默認爲None,但我希望能夠只通過在URL,並有一流的數字出來自身)

謝謝!

+0

將在級別的順序永遠是一樣的嗎? –

+0

是的.___________________ – marky1991

回答

7

使用序列拆包:

>>> 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') 
+0

啊,那很完美!我認爲元組解包在這裏可能會有所幫助,但是我不夠聰明以解決問題。 :(謝謝kajillion!(只要SO讓我接受答案) – marky1991

+1

您也可以使用一個列表,而不是製作5個不同的變量:) –

+0

我想通過名稱來引用它們。這就是爲什麼我要首先創建一個班級。 – marky1991

3

你可以添加一個setter方法到類,設置適當的默認值:

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 
1

比moooeeeep的票友方法是使用一個namedtuple。 (或者更確切地說,一個帶有默認值的子類。)

from collections import namedtuple 

class _Path(namedtuple('Path', 'root section subsection thread post')): 
    def __new__(cls, root=None, section=None, subsection=None, thread=None, post=None): 
     # add default values 
     return super(_Path, cls).__new__(cls, root, section, subsection, thread, post) 

Path = lambda s: _Path(*s.strip('/').split('/')) 

然後......

>>> Path("/forums/support/") 
_Path(root='forums', section='support', subsection=None, thread=None, post=None) 
3

我建議使用itertools.izip_longest(在Python 3更名爲zip_longest)來構建字典創建name, value元組,與None填充任何遺漏值:

import itertools 

names = ["root", "section", "subsection", "thread", "post"] 
values = url.strip("/").split("/") 

name_value_dict = dict(itertools.izip_longest(names, values)) 

現在你可以使用詞典直接,如果你需要到c在對象上reate成員變量,你可以使用dict.update合併成一個現有的字典:

self.__dict__.update(name_value_dict)