如何在Python中通过其属性调用实例?

时间:2016-02-02 02:48:10

标签: python

我已经定义了一个类,这个类中的对象有一些属性pp1pp2等。

class example(object):
   def __init__(self,pp1,pp2,...):
       self.pp1=pp1
       self.pp2=pp2
       ...

for x in range (0,100):
    ll[x]=example(pp1[x],pp2[x],...) # pp1[x] pp2[x] are defined somewhere else

ll[30]=example(30.0,40.0,...)

我已经定义了类ll[x]的许多实例example。这些属性p​​p1,pp2等对于每个实例都是唯一的。

通常,我们称之为:

ll[x].method()

如果我不知道实例的名称(例如,在这种情况下为ll[x]),是否可以确定具有一个或多个属性的实例?例如,我希望调用pp1为'30 .0'(且pp2为40.0)的实例,但我不知道它的名字。 (在这种情况下为ll[30]

在SQL中,它可能看起来像Select * from example where pp1=30.0 (and pp2=40.0),我们可以获得ll[30]的结果,然后我们可以让.method()做其他事情。

如果不可能,还有其他方法吗?

增加:
感谢Alik建议使用过滤器。我认为它可以用于这个例子。但是,如果我们不在列表中定义这些实例呢?

2 个答案:

答案 0 :(得分:2)

简单的方法是在内部简单地保留一个实例列表:

class example(object):
    instances = []

    def __init__(self, pp1, pp2, ...):
        self.pp1 = pp1
        self.pp2 = pp2
        ...

        example.instances.append(self)

然后,您只需过滤列表example.instances即可找到所需的实例。

或者,如果您需要更高性能的方法(查找时间更快),您可以将每个属性值的查找表保存到具有该值的实例,如下所示:

class example(object):
    pp1_lookup = {}
    pp2_lookup = {}
    ...

    def __init__(self,pp1,pp2,...):
        self.pp1=pp1
        self.pp2=pp2
        ...

        example.pp1_lookup.setdefault(pp1,[]).append(self)
        example.pp2_lookup.setdefault(pp2,[]).append(self)
        ...

这种方法的缺点是它假定您的example实例在实例化后是不可变的,并且属性值是可清除的(否则它们不能用作dict个键)。如果其中任何一个都不成立,事情就会变得更加困难(但并非不可能)。

要在此方案下查找实例,您只需要在相应的查找表中查找属性值:

examples = example.pp1_lookup.get(30.0, [])

这将返回examplepp1的所有30.0个实例的列表。如果没有这样的实例,则返回一个空列表。

答案 1 :(得分:0)

这听起来像是pandas DataFrames的一种可能用途。如果您喜欢这个解决方案,我可以向您展示一个适用于您的类的DataFrame包装器的示例。这种方法的优点是随着查询需求的增长,您可以使用pandas语法表达复杂的查询。

import pandas as pd

ll = [i for i in range(0,100)]
for i in range(0,100):
    ll[i]=[i,i,i,i,i]
s = pd.DataFrame(ll,columns=['pp1','pp2','pp3','pp4','pp5'])

print s[s['pp1']==30]