2014-06-20 40 views
2

我有以下問題返回所有對象:添加屬性類列表與特定屬性

讓我們來設置場景!

說我有一類人有幾個基本屬性:

class Person(object): 
    def __init__(self, name=None, gender=None, single=None): 
     self.name=name 
     self.gender=gender 
     self.single=single 

我創建一個名爲約會列表類,將容納所有Person對象

class Dating(object): 
    def __init__(self): 
     self.members=[] 

My_People=Dating() 

My_People.members.append(Person("Jack","Male",False)) 
My_People.members.append(Person("Jill","Female",True)) 
My_People.members.append(Person("George","Male",True)) 
My_People.members.append(Person("Sandy","Female",False)) 

對,所以問題是什麼?

是否有可能分配到列表類的屬性,通過建立某種類似屬性的訪問My_People列表的單一成員:

My_People.members.singles 

所以,這將返回Person對象的列表有單個==真屬性?

感謝您的幫助。 (順便說一下,我有使用Python很少以往的經驗)

+0

結束調用的'__init__'方法,它以這種方式工作沒有你的幫助) – alexvassel

+0

已編輯的問題。現在好多了? – user1083734

+0

是的,當然!) – alexvassel

回答

3

要添加這樣的屬性,你就必須列表類型:

class FilterableList(list): 
    def __getattr__(self, name): 
     # assume non-existing attributes are boolean filters 
     return [elem for elem in self if getattr(elem, name)] 

注意,這還不是全部那靈活;只有True值可以通過這種方式找到。你可以給屬性名更多的含義,但通常會想這樣做的Dating類不管怎樣,使用方法更意味深長地過濾數據。

演示:

所有的
>>> class Person(object): 
...  def __init__(self, name, gender, single): 
...   self.name=name 
...   self.gender=gender 
...   self.single=single 
...  def __repr__(self): 
...   return 'Person({name!r}, {gender!r}, {single!r})'.format(**vars(self)) 
... 
>>> class FilterableList(list): 
...  def __getattr__(self, name): 
...   # assume non-existing attributes are boolean filters 
...   return [elem for elem in self if getattr(elem, name)] 
... 
>>> members = FilterableList([Person("Jack","Male",False), Person("Jill","Female",True), Person("George","Male",True), Person("Sandy","Female",False)]) 
>>> members 
[Person('Jack', 'Male', False), Person('Jill', 'Female', True), Person('George', 'Male', True), Person('Sandy', 'Female', False)] 
>>> members.single 
[Person('Jill', 'Female', True), Person('George', 'Male', True)] 
+0

感謝這一點,這正是我需要的,我喜歡解決方案的靈活性。此外,我從來沒有使用__repr__,它真的會派上用場! – user1083734

2

首先,你並不需要調用__init__()My_People例如,Python做自動。

對於這個問題,你可以從list子類,並添加singles屬性是這樣的:

class Person(object): 
    def __init__(self, name=None, gender=None, single=None): 
     self.name=name 
     self.gender=gender 
     self.single=single 

class Dating(list): 
    @property 
    def singles(self): 
     return [person for person in self if person.single ] 

My_People=Dating() 

My_People.append(Person("Jack","Male",False)) 
My_People.append(Person("Jill","Female",True)) 
My_People.append(Person("George","Male",True)) 
My_People.append(Person("Sandy","Female",False)) 

print My_People.singles 
+0

太棒了,我明白這一點。因此,每次要訪問My_People.singles時都必須遍歷My_People列表,並且沒有直接用單一== True屬性調用這些對象的方法。 – user1083734

+0

我喜歡從列表中繼承的建議,非常方便 – user1083734

+0

@ user1083734您當然可以保存''.singles''返回的結果,以避免在每次訪問時遍歷列表。 – Fabian

1

怎麼樣:

class Attribute(list): 
    def __getattr__(self, attr): 
     if attr == 'single': 
      return [person for person in self if person.single] 
     raise AttributeError() 

class Person(object): 
    def __init__(self, name=None, gender=None, single=None): 
     self.name = name 
     self.gender = gender 
     self.single = single 

    def __repr__(self): 
     return 'Person({person.name}, {person.gender}, {person.single})'.format(person=self) 


class Dating(object): 
    members = Attribute() 


My_People = Dating() 

My_People.members.append(Person("Jack", "Male", False)) 
My_People.members.append(Person("Jill", "Female", True)) 
My_People.members.append(Person("George", "Male", True)) 
My_People.members.append(Person("Sandy", "Female", False)) 

>>> print My_People.members.single 
[Person(Jill, Female, True), Person(George, Male, True)] 
>>> print My_People.members 
[Person(Jack, Male, False), Person(Jill, Female, True), Person(George, Male, True), Person(Sandy, Female, False)] 
0

如果你不依賴於My_People.members.singles語法,你可以做得更簡單:

class Dating(object): 

    def __init__(self): 
     self.members = [] 

    @property 
    def single_members(self): 
     return [m for m in members if m.single] 

現在你訪問列表具有:

My_People.single_members