Python面向对象模型

时间:2010-07-18 21:52:23

标签: python oop class-design

我有类似的事情。

属于某种状态的同一型号汽车颜色多的人。

我将人员类设计为具有属性person namecar modelcar yearcar statecar color作为属性。颜色应该是一个列表,因为一个人可以拥有许多不同颜色但具有相同型号的汽车。

现在我如何找到和打印2个不同的人,他们拥有相同型号的汽车和相同颜色的汽车但是在面向对象的术语中属于不同的状态?

我是Python的新手。

在人物对象中插入颜色时如何插入列表以及如何从列表中检索?我知道如何为属性执行此操作,但我对列表操作有点困惑。

数据可以是这样的:

person1 ford   [red,blue,yellow] new-york
person2 honda  [red,blue]        new-york
person3 ford   [red,grey]        california
person4 ford   [red]             california
person5 honda  [red]             new-york

现在我的结果应该是:

[(person1,person5)]    (same model car,same color, different state)

3 个答案:

答案 0 :(得分:2)

您可能希望与state分开建模carperson。然后,每个人都可以拥有汽车列表,并且实时处于某种状态(甚至状态列表,具体取决于您的型号)。这些是 has-a 关系。如果您愿意,它还允许您稍后继承car并稍后生成sportsCar

答案 1 :(得分:2)

您想了解一下列表操作:

$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> l=[]
>>> l.append("honda")
>>> l.append("ford")
>>> l
['honda', 'ford']
>>> l[0]
'honda'
>>> l.pop(0)
'honda'
>>> l.pop(0)
'ford'
>>> l.pop(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: pop from empty list

如果您想找到几个具有匹配属性的人,您可以做一些 迭代(在这里用一些伪代码表示,因为我认为是专注于 该算法比聚焦python更有用,以实现它:)

results = []
foreach p1 in [list of people]
    foreach p2 in [list of people]
        next if p1 == p2
        next if p1.state == p2.state
        next unless p1.car == p2.car
        foreach c1 in p1.colors
            foreach c2 in p2.colors
                results.append((p1,p2)) if c1 == c2

此代码比较一对人。它没有比较一个人 自理。它并不能比较生活在同一州的人 要求“......但属于不同的国家”。所以让我们过滤那些相同的状态 人们出去了。它只比较拥有相同类型汽车的人。 (如果 人们拥有不同类型的汽车,那么你只需添加两个嵌套的汽车 循环。)然后它注意到那些具有相同颜色汽车的人。

此算法存在潜在错误:它会报告[(person1, person2), (person2, person1)]。所以条目是重复的。可以修改 算法只搜索人的上三角或下三角 想要这个重复:

results = []
for i=0; i<people.last_index-1; i++
    for j=i+1; j<people.last_index ; j++
        p1 = people[i] ; p2 = people[j]
        next if p1.state == p2.state
        next unless p1.car == p2.car
        foreach c1 in p1.colors
            foreach c2 in p2.colors
                results.append((p1,p2)) if c1 == c2

注意我们可以删除next if p1 == p2检查,因为我们明确不能 得到i == jj定义为以i+1开头。

答案 2 :(得分:2)

有很多方法可以做到这一点。如果您有大量数据,那么我建议您继续使用python的内置sqlite支持来解决基于数据库的实现(实际上并不那么难)。数据库引擎专门用于搜索。您需要两张桌子,因为每人可以有多种颜色。 person表将包含以下列:id,name,model,state。颜色表将具有:personid,color。 personid列将包含颜色表中的行对应的id号。然后,您可以在颜色表中使用相同的personid值(这是列表的数据库版本)中有多行。 sqlAlchemy是一个帮助使用python对象实现数据库的库,您可能会发现它更适合您尝试的操作。 sqlAlchemy ORM Tutorial引导您使用sqlite数据库,其中包含两个与您需要的表非常相似的表(用户,地址)。

现在,如果你想单独使用python类,你将需要有一个人员实例列表并遍历它们所有寻找匹配项。方便的颜色匹配简化是将颜色列表转换为集合并进行交集。

>>> s1 = set(['red','blue','yellow'])
>>> s2 = set(['red','blue'])
>>> s1.intersection(s2)
set(['blue', 'red'])

迭代人员实例列表的快捷方式是使用python的itertools库并使用置换生成器。

from itertools import permutations
people = ['p1', 'p2', 'p3']
for p1, p2 in itertools.permutations(people,2):
    print p1, p2

p1 p2
p1 p3
p2 p1
p2 p3
p3 p1
p3 p2

希望这足以帮助您一路走来。重读你的问题看起来你可能需要在python中进行更多关于编程的阅读。但是要解决关于列表的问题,这里有一些代码可以帮助你。

class Person(object):
    def __init__(self, name, model, colors, state):
        self.name = name
        self.model = model
        self.colors = colors
        self.state = state

p1 = Person('p1', 'ford', ['red', 'blue'], 'new-york')
p2 = Person('p2', 'honda', ['red', 'blue'], 'new-york')

persons = [p1, p2]
  # or
persons = []
persons.append(p1)
persons.append(p2)

p1.color.append('yellow')
  # or
persons[0].color.append('yellow')