我在寫一個python程序,我需要重載>>操作符。我面臨的問題是這個操作符需要正確的關聯。所以,如果我做了以下Python操作符重載和操作符關聯
A >> B >> C >> D >> E
我想這被解析爲
(A >> (B >> (C >> (D >> E))))
據我瞭解,在python這個操作符是左關聯的,所以我會得到,
((((A >> B) >> C) >> D) >> E)
有沒有辦法在運算符重載時改變python中運算符的默認關聯性?
我在寫一個python程序,我需要重載>>操作符。我面臨的問題是這個操作符需要正確的關聯。所以,如果我做了以下Python操作符重載和操作符關聯
A >> B >> C >> D >> E
我想這被解析爲
(A >> (B >> (C >> (D >> E))))
據我瞭解,在python這個操作符是左關聯的,所以我會得到,
((((A >> B) >> C) >> D) >> E)
有沒有辦法在運算符重載時改變python中運算符的默認關聯性?
這可以做...但它需要一點努力。基本思想是使用右移運算符來創建和更新一個新類型的對象,這個對象將延遲實際的計算。例如,假設上面的變量:A,B,C,D和E都是Actual類型的對象。我們將介紹一個由實例的實例上的rshift操作產生的新類Deferred。延遲還實現了rshift運算符,該運算符更新對象並返回自身。
(順便說一句,對於本答案的其餘部分,我假設A,B,C,d,和E是不可變的,並且所述RSHIFT操作產生一個新的對象。)
F = A >> B >> C >> D >> E
將計算像...
F = Deferred(A,B) >> C >> D >> E
F = Deferred(A,B,C) >> D >> E
F = Deferred(A,B,C,D) >> E
F = Deferred(A,B,C,D,E)
F維護一個實際的緩存實例,它是從反向序列計算出來的。此外,F實現與Actual相同的接口,以便在Deferred實例上調用的方法被委派給Actual的緩存實例。
我不知道你在做什麼樣的計算,所以在下面的例子中,我構成了一些微不足道的事情,只是爲了說明延遲計算實際執行的時間,它們是相反的。
class Var(object):
def __init__(self):
pass
@property
def name(self):
return self._name()
@property
def length(self):
return len(self.name)
class Actual(Var):
def __init__(self, name):
Var.__init__(self)
self._text = name
def _name(self):
return self._text
def __rshift__(self, other):
if isinstance(other, Actual):
return Deferred(self, other)
return len(self.name)
@staticmethod
def NewFromShiftComputation(sequence):
x = ' >> '.join(reversed(map(lambda actual: actual.name, sequence)))
return Actual(x)
class Deferred(Var):
def __init__(self, *args):
Var.__init__(self)
self._items = [ ]
self._actual = None #-- cached "actual"
for item in args:
self._items.append(item)
def _name(self):
self._assure_actual()
return self._actual.name
def __rshift__(self, other):
self._actual = None #-- Invalidate the cached "actual"
self._items.append(other)
return self
def _assure_actual(self):
if self._actual is None:
self._actual = Actual.NewFromShiftComputation(self._items)
A = Actual('A')
B = Actual('B')
C = Actual('C')
D = Actual('D')
E = Actual('E')
F = A >> B >> C >> D >> E
print F.name
print F.length
這不是操作員的問題。 Python從左到右評估:
http://docs.python.org/reference/expressions.html#evaluation-order
因此,在這種情況下,因爲它的所有操作符都是括號的,所以需要括號。
我可能是錯的,但是這不是一個運算符重載的問題,但更多隻是標準的「操作順序」?如果他們都是相同的運營商,那麼它會從左到右評估從左到右 – jdi
重載<<運營商intead;) – wim
@wim我想到了,哈哈。對於習慣於從左向右閱讀的人來說,這樣做會更自然。我也想過重=運算符,因爲我認爲這是正確的聯想,但這隻會是非常難看。 – martega