2017-02-17 51 views
1

我来自Racket的Python。在拍,我会定义一个Point结构是这样的:现在如何定义基本的Python结构?

(struct Point (x y) #:transparent) 

的一点是与名为xy两个字段的结构。我可以通过调用equal?来比较两个结构(深层)的相等性。

Python中的等价物是什么?它看起来对我来说,我必须写线:

class Point(): 
    def __init__(self,x,y): 
     self.x = x; 
     self.y = y; 

    def __eq__(self, other): 
     return ((type(other) is Point) 
      and self.x == other.x 
      and self.y == other.y) 

    def __ne__(self, other): 
     return not(self == other) 

...但肯定有更简单的方法?

+2

鸡蛋里挑骨头,你需要一个'#:在你的'struct'定义'#lang racket' transparent'得到深平等,但是这并不会改变它所需的行数。 –

+0

@JohnClements,你可以定义__eq__和__lt__,你的对象可以使用'>,> =,<来比较。 <=,!='和'==' – lmiguelvargasf

+0

请注意,您的Python代码有很多自定义行为的空间,并非所有类都需要每个类。另外,你只需要写十行。 – TigerhawkT3

回答

6

是的,如果您需要整个班级来表示您的数据类型,那么您将不得不依赖__eq__和相关的dunder方法。然而,在这种特殊情况下,一个Pythonista将使用namedtuple

from collections import namedtuple 
Point = namedtuple('Point', ['x','y']) 

这将继承所有来自tuple

+0

呵呵。愚蠢的StackOverflow没有提醒我你的新答案,浪费了我在冗余信息上的时间。我只会因为它包含关于可变性和平等测试行为的额外信息而将其留在原地。 – ShadowRanger

+1

@ShadowRanger是的,你从我这里得到了一个满意的结果,其中包括'(Point(1,2)==(1,2)'评估为'True')的警告! –

+0

好!额外upvote为警告我的术语“ dunder方法“。这个价值64000美元的后续问题是,后期课程中的老师是否会担心我的所有学生都会使用命名的元组而不是课程,非常感谢 –

3

如果你不需要可变性,使这种基本类最简单的方法是collections.namedtuple

import collections 

Point = collections.namedtuple('Point', 'x y') 

就是这样。你可以制作Point对象pt = Point(1, 2)或类似的东西,它们像二元组一样工作,但它们也允许你通过命名属性来访问它们。 pt.xpt.y

的平等检查会有点宽松(Point(1, 2) == (1, 2)评估为True,因为所有namedtuple s为的tuple子类,并比较使用tuple规则,并在事实上,tuple不同的子类不覆盖比较方法会如果它们具有相同的值,则相互相等),但考虑到tuple通常用作匿名轻量级“类”,这通常是您想要的。

如果您需要自定义一些行为(添加功能或使类型比较更严格),您可以使用自定义类继承namedtuple以免费获得基本功能,然后自定义您关心的位,例如,以防止测试等于非Point类型,你可以这样做:

class Point(collections.namedtuple('PointBase', 'x y')): 
    def __eq__(self, other): 
     if not isinstance(other, Point): 
      return False 
     return super().__eq__(other) 

    # Sadly, tuple defines __ne__, so you must override it too to behave properly 
    # You don't need the canonical __ne__ implementation that handles NotImplemented 
    # though, since you're explicitly unfriendly to non-Point types 
    def __ne__(self, other): return not (self == other) 
+1

我怀疑一个球拍程序员会发现不变性是一个*功能* :) –

+0

@ juanpa.arrivillaga:直到今天我才听说过球拍;纯功能我拿?在这种情况下,是的,不变性是好的。 – ShadowRanger

+0

@ShadowRanger不,不是纯粹的功能。但绝对功能 - 除非你有一个好理由。 –