2017-02-17 52 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不,不是純粹的功能。但絕對功能 - 除非你有一個好理由。 –