【问题标题】:Comparing class instances and attaining cumulative "score"比较类实例并获得累积“分数”
【发布时间】:2014-01-08 02:48:10
【问题描述】:

所以,我有两个 Person 类的实例,我正在尝试进行一些比较。 sun是每个实例的几个属性之一,由两个随机生成的数字定义。我有以下问题......创建像Match 这样的子类是建立这种比较的正确方法吗?我想要一个在比较结束时编译的overall“分数”,我可以在没有for循环的情况下这样做吗?

Person1 = Person("Person1")
Person2 = Person("Person2")


class Match(Person):

    overall = 0

    def __init__(self, Person1, Person2):
        self.Person1 = Person1
        self.Person2 = Person2

    def suns (self): 
        if abs(Person1.sun - Person2.sun) == 2 or 4 or 8 or 10:
            overall += 4

        elif abs(Person1.sun - Person2.sun) == 3 or 9: 
            overall -= 6

        elif abs(Person1.sun - Person2.sun) == 6:
            overall += 3

        else:
            overall += 0

print Match.overall

编辑 为了澄清我正在尝试做的事情......我对占星术出生图兼容性服务的工作原理有一些基本的了解,只是为了好玩和练习,我想运行该程序的一个非常基本的版本。目前,所有数据都是随机生成的,不需要用户输入。这是 Person 类的样子

from random import randint
from decimal import Decimal

def randomDecimal(a,b):
    return (randint(int(a), int(100.0 * b)))/100.0

class Person:

    def __init__(self, name):
        self.name=name
        self.sun = (randomDecimal(1, 12), randomDecimal(0, 30)) 
        self.moon = (randomDecimal(1, 12), randomDecimal(0, 30)) 
        self.mercury = (randomDecimal(1, 12), randomDecimal(0, 30))
        self.venus = (randomDecimal(1, 12), randomDecimal(0, 30))
        self.mars = (randomDecimal(1, 12), randomDecimal(0, 30))

    def printer(self):
        print "your Sun is in %f, at %f degrees" % (self.sun[0], self.sun[1])
        print "your Moon is in %f, at %f degrees" % (self.moon[0], self.moon[1])
            #and so on and so forth for the printer

【问题讨论】:

  • 你的问题是非常开放的,有很多不同的方法。 IMO,我会使用一个需要两个人的简单函数。
  • 为什么MatchPerson 的子类?
  • 是在“足球比赛”的上下文中使用的“比赛”,其中两个人互相比赛,还是比较两个人的“约会比赛”?您需要添加更多上下文来解释您在此处尝试执行的操作。
  • @LegoStormtroopr 认为“约会匹配”。
  • @alKid 我想比较两个实例的属性,但不知道该怎么做。

标签: python class comparison subclassing


【解决方案1】:

如果你想比较两个人,那么比较本身就不是一个人。

Python classes have special methods you can overide that allow inbuilt python equalities 上班。

例如:

class Person():
    __init__(self, name="Sinead OConnor", etc...):
        # boiler plate goes here
        self.name = name

    __eq__(self, anotherPerson):
        return False # Perople are wonderful and unique and have no equal

    __cmp__(self,anotherPerson):
        return anotherPerson == "You" # Nothing compares too you!

这些将允许您执行以下操作:

> a = Person(a)
> b = Person(b)
> a == b
False

显然,如何比较人是困难的,而且是特定于应用程序的,但是一旦有了逻辑,它就有意义了。

对于您的工作,您需要与抽象的“他们是否适合”句子中的人进行比较,`cmp 行不通,因为那只是大于,小于或等于另一个。

在这些情况下,您可以执行以下操作

class Person():
    delta = 100 # How close do 2 things need to be to be a good match
    __init__(self, name="Sinead OConnor", etc...):
        # boiler plate goes here
        self.name = name

    def loveOfPowerBallads(self,myRank):
        if 0<myRank<100:
            raise OutOfRange # Or whatever
        self.rankPowerBallads = myRank

    def isGoodMatch(self,otherPerson):
        return (self.rankPowerBallads - other.rankPowerBallads) ^ 2 < Person.delta

然后:

> ls = Person("legoStormtrooper")
> ls.loveOfPowerBallads(95)
> lp = Person("Lame Person")
> ls.loveOfPowerBallads(30)
> ls.isGoodMatch(lp)
False

编辑:让你更具体(虽然原理是一样的):

class Person:

    def __init__(self, name):
        self.name=name
        self.sun = (randomDecimal(1, 12), randomDecimal(0, 30)) 
        self.moon = (randomDecimal(1, 12), randomDecimal(0, 30)) 
        # etc...

    def compare(self,other):
        overall = 0
        if abs(self.sun - other.sun) in [2,4,8,10]:
            overall += 4
        elif abs(self.sun - other.sun) in [3,9]: 
            overall -= 6
        elif abs(self.sun - other.sun) == 6:
            overall += 3
        else:
            overall += 0
        return overall

【讨论】:

  • 谢谢。我明白您要向我展示的内容,但我认为它不适用于我正在尝试做的事情。我已经更新了第一条更详细地解释它的消息
  • @sivanes 我已经更新它以更接近您的代码,但原理基本相同。在比较两个事物时,比较器通常不是一个新对象,并且不能通过调用一个对象方法和另一个对象作为参数来实现。
  • @LegoStormtroopr 我很好奇 - 你有没有注意到这一行 if abs(self.sun - other.sun) == 2 or 4 or 8 or 10:
【解决方案2】:

在 Python 中,这一行

if abs(self.sun - other.sun) == 2 or 4 or 8 or 10:

其实就是

if (abs(self.sun - other.sun) == 2) or 4 or 8 or 10:

任何非空值都被视为。所以这个表达式总是True。正确的形式

if abs(self.sun - other.sun) in (2, 4, 8, 10):

第二个如果也是如此

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 2012-05-25
    • 1970-01-01
    • 2018-05-13
    • 2022-01-17
    • 2019-09-06
    • 2018-09-08
    相关资源
    最近更新 更多