将属性添加到类列表以返回具有特定属性的所有对象

use*_*734 3 python attributes class list filter

我有以下问题:

让我们来设置场景!

假设我有一个具有一些基本属性的类 Person:

class Person(object):
    def __init__(self, name=None, gender=None, single=None):
        self.name=name
        self.gender=gender
        self.single=single
Run Code Online (Sandbox Code Playgroud)

我创建了一个名为 Dating 的列表类,它将保存所有 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))
Run Code Online (Sandbox Code Playgroud)

是的,那么问题是什么?

是否可以通过创建某种属性来为列表类分配属性以访问 My_People 列表的单个成员,例如:

My_People.members.singles
Run Code Online (Sandbox Code Playgroud)

所以这将返回具有单个 == True属性的 Person 对象列表?

感谢所有的帮助。(顺便说一句,我以前对 Python 的经验很少)

Mar*_*ers 7

要添加这样的属性,您必须对列表类型进行类化:

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

请注意,这并不是那么灵活。只能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)]
Run Code Online (Sandbox Code Playgroud)