2012-09-13 105 views
1

我構建了一類:Python類設計:屬性

class Foo (object): 
     def __init__(self,List): 
      self.List=List 
     @property 
     def numbers(self): 
      L=[] 
      for i in self.List: 
       if i.isdigit(): 
       L.append(i) 
      return L 
     @property 
     def letters(self): 
      L=[] 
      for i in self.List: 
       if i.isalpha(): 
       L.append(i) 
      return L 

>>> inst=Foo(['12','ae','45','bb']) 
>>> inst.letters 
['ae', 'bb'] 
>>> inst.numbers 
['12', '45'] 

我怎麼可以添加屬性,所以我可以做inst.numbers.odd,將返回['45']

回答

3

你的numbers屬性返回一個列表,所以numbers.odd將無法​​正常工作。

但是,您可以遵循類似的工作流程:

  • 定義一個小班Numbers,這將定義兩個屬性evenodd 例如,Numbers可以採取列表作爲其__init__,爭論even財產將只返回此列表的偶數[i for i in List if int(i)%2 == 0](和odd奇數)...

  • 創建一個在你的Foo.numbers財產Numbers實例(使用您的Foo.List對其進行初始化),並返回該實例...

Numbers類可以直接繼承內建list類,如建議。你也可以將它定義成

class Numbers(object): 
    def __init__(self,L): 
     self.L = L 
    @property 
    def even(self): 
     return [i for i in self.L if not int(i)%2] 
    def __repr__(self): 
     return repr(self.L) 

在這裏,我們返回的Numbers表示爲L屬性(列表)的代表性。罰款和花花公子,直到要附加的東西到Numbers實例,例如:你必須定義一個Numb.append方法......這可能是更容易堅持做Numbers列表的一個子類:

class Numbers(list): 
    @property 
    def even(self): 
     ... 

編輯:由%糾正//,因爲我去得太快,是不小心的話

+0

是的,但我怎麼能得到inst.numbers仍然返回['12','45']然後。我無法弄清楚...... – root

+0

@ Pierre GM:非常感謝您的幫助。 – root

+1

你的測試應該不是int(i)%2'。 '(不是int(57)// 2)是(not int(56)// 2)'應該返回True。 – mgilson

2

這是一個愚蠢的例子:

class mylst(list): 
    @property 
    def odd(self): 
     return [ i for i in self if int(i)%2 == 1 ] 

class Foo(object): 
    def __init__(self,lst): 
     self.lst = list(lst) 

    @property 
    def numbers(self): 
     return mylst(i for i in self.lst if i.isdigit()) 

a = Foo(["1","2","3","ab","cd"]) 
print(a.numbers) 
print(a.numbers.odd) 

基本上,我們只是子類list並添加一個屬性odd它返回另一個列表。由於我們的結構是列表的一個子類,它與真實事物幾乎沒有區別(Horray duck typing!)。 mylst.odd甚至可以返回一個新實例mylst如果你想能夠再次過濾它(例如a.numbers.odd.in_fibinocci

+0

@ mgilson:謝謝。我想我現在得到它。 – root

+0

我可以想到這可以實現的一些可怕的方式,但從列表繼承優雅+1 –

+0

@JonClements - 我敢肯定,你可以用'描述符'做這樣的事情,但我從來沒有機會使用它們。從python內建類型繼承是很容易的,因爲pi! – mgilson