![](/img/trans.png)
[英]Python function "sum" with syntax like: sum() -> 0 sum(1)(2)(3) -> 6
[英]how to implement a function like sum(2)(3)(4)…(n) in python?
如何實現將以以下方式在python中調用sum_numbers(2)(3)(4)......(n)
?
結果應該是2+3+4+.....+n
我的提示是,由於函數是python中的對象,因此可以使用嵌套函數來實現這些功能,但我不確定。
def sum_number(x):
def sum_number_2(y):
def sum_number_3(z):
....................
def sum_number_n(n)
return n
return sum_number_n
return sum_number_3
return sum_number_2
return sum_number
但是,與其編寫太多嵌套函數, sum_numbers(2)(3)(4)......(n)
以如下方式調用sum_numbers(2)(3)(4)......(n)
調用兩個嵌套函數來計算n個值的總和
使用Python的數據模型功能將結果轉換為所需的類型。
class sum_number(object):
def __init__(self, val):
self.val = val
def __call__(self, val):
self.val += val
return self
def __float__(self):
return float(self.val)
def __int__(self):
return int(self.val)
print '{}'.format(int(sum_number(2)(3)(8)))
print '{}'.format(float(sum_number(2)(3)(8)))
您可以創建一個可調用的int
子類:
class sum_numbers (int):
def __new__ (cls, *args, **kwargs):
return super().__new__(cls, *args, **kwargs)
def __call__ (self, val):
return sum_numbers(self + val)
這樣,您就可以與普通整數完全兼容(因為該類型的對象是普通整數),因此以下示例適用:
>>> sum_numbers(2)(3)(4)(5)
14
>>> isinstance(sum_numbers(2)(3), int)
True
>>> sum_numbers(2)(3) + 4
9
當然,您可能想覆蓋其他方法,例如__add__
以便添加普通整數仍會返回您類型的對象。 否則,您將不得不使用結果調用類型,例如:
>>> sum_numbers(sum_numbers(2)(3) + 5)(6)
16
如果您的函數正在返回另一個函數,則不能僅將調用鏈接在一起並期望得到人類可讀的結果。 如果您想要一個可以在沒有最終結果的情況下實現所需功能的函數,則可以這樣做:
def sum(x):
def f(y):
return sum(x+y)
return f
如果您適合打印操作,可以嘗試以下操作:
def sum(x):
print(x)
def f(y):
return sum(x+y)
return f
如果您絕對需要返回值,那么可以嘗試以下方法:
def sum(x, v):
v[0] = x
def f(y, v):
return sum(x+y, v)
return f
v = [0]
sum(1,v)(2,v)(3,v)
print(v[0]) # Should return 6
這是另一個使用類的解決方案:
class sum(object):
def __init__(self, x=0):
self.x=x
def __call__(self, *y):
if len(y) > 0:
self.x += y[0]
return self
return self.x
print(sum(1)(2)(3)()) # Prints 6
正如cricket_007在評論中提到的那樣,您要的內容在Python中是不可能的,因為您沒有提供確定調用鏈結束的方法。 但是,如果您確實提供了一種指示不再有調用的方式,則該函數很容易編寫代碼。 指示鏈結束的一種方法是不帶參數地進行最后一次調用。
我在我的代碼中使用rsum
(遞歸和)作為函數的名稱,因為sum
是一個內置函數,不必要地遮蓋Python內置不是一個好的編碼習慣:它會使代碼潛在地引起混亂,或者最不容易閱讀的原因是,您必須記住該名稱未指向您通常期望的名稱,並且可能導致細微的錯誤。
def rsum(val=None, tot=0):
if val is None:
return tot
tot += val
return lambda val=None, tot=tot: rsum(val, tot)
print rsum(42)()
print rsum(1)(2)()
print rsum(4)(3)(2)(1)()
print rsum(4100)(310000)(9)(50)()
輸出
42
3
10
314159
class MetaSum(type):
def __repr__(cls):
sum_str = str(cls.sum)
cls.sum = 0
return sum_str
def __call__(cls, *args):
for arg in args:
cls.sum += arg
return cls
class sum_numbers(object, metaclass = MetaSum):
sum = 0
print (sum_numbers(2)(3)(4)) # this only works in python 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.