我試圖做一個函數,當在不同的參數類型上調用時做不同的事情。具體而言,該功能一應具備簽名如何在Python中重載?
def myFunc(string, string):
和其他應具備的簽名
def myFunc(list):
我怎麼能做到這一點,因爲我不能指定參數是否字符串或列表?
我試圖做一個函數,當在不同的參數類型上調用時做不同的事情。具體而言,該功能一應具備簽名如何在Python中重載?
def myFunc(string, string):
和其他應具備的簽名
def myFunc(list):
我怎麼能做到這一點,因爲我不能指定參數是否字符串或列表?
*args
可能是更好的辦法,但你可以這樣做:
def myFunc(arg1, arg2=None):
if arg2 is not None:
#do this
else:
#do that
但是,這可能是做這件事的可怕方式。
把它定義爲以可變參數:
def myFunc(*args):
然後你就可以通過len
和isinstance
,並將呼叫路由到適當的特定情況下,功能檢查的數量和參數類型。
但是,如果使用可選的命名參數,它可能會使代碼更清晰。如果你根本沒有使用超載,那會更好,但這不是python的方式。
即使通過參數計數,Python也不支持重載。你需要做的:
def foo(string_or_list, string = None):
if isinstance(string_or_list, list):
...
else:
...
這是非常愚蠢的,或者只是重新考慮你的設計,不必過載。
有一個食譜在http://code.activestate.com/recipes/577065-type-checking-function-overloading-decorator/這是做你想做的;
基本上,你用@takes和@returns類型聲明包裝你的函數的每個版本;當你調用函數時,它會嘗試每個版本,直到找到一個不會引發類型錯誤的版本。
編輯:這裏是一個精簡版;它可能不是做一件好事,但如果你得,方法如下:
from collections import defaultdict
def overloaded_function(overloads):
"""
Accepts a sequence of ((arg_types,), fn) pairs
Creates a dispatcher function
"""
dispatch_table = defaultdict(list)
for arg_types,fn in overloads:
dispatch_table[len(arg_types)].append([list(arg_types),fn])
def dispatch(*args):
for arg_types,fn in dispatch_table[len(args)]:
if all(isinstance(arg, arg_type) for arg,arg_type in zip(args,arg_types)):
return fn(*args)
raise TypeError("could not find an overloaded function to match this argument list")
return dispatch
和這裏的工作原理是:
def myfn_string_string(s1, s2):
print("Got the strings {} and {}".format(s1, s2))
def myfn_list(lst):
print("Got the list {}".format(lst))
myfn = overloaded_function([
((basestring, basestring), myfn_string_string),
((list,), myfn_list)
])
myfn("abcd", "efg") # prints "Got the strings abcd and efg"
myfn(["abc", "def"]) # prints "Got the list ['abc', 'def']"
myfn(123) # raises TypeError
不能 - 例如一個類的實例方法可在運行時插入。
如果你有多個__init__
爲實例類,你會與多個@classmethod
的如from_strings
或from_sequence
不是一個完美的解決方案更好,但如果第二個字符串參數絕不會順理成章None
,你可以試試:
def myFunc(firstArg, secondArg = None):
if secondArg is None:
# only one arg provided, try treating firstArg as a list
else:
# two args provided, try treating them both as strings
簡而言之:Python語言中基本上沒有函數參數重載。這不是一個缺失的功能 - 這是一個語言概念。 – dajood
IMO這就是爲什麼一個模式匹配庫(如球拍匹配)對Python很好 – Wes
由於下面的答案應該建議,你必須開始考慮你的問題有點不同 - python有動態類型,這將使其解決問題的風格不同。在運行時可以進行一些類型檢查,但是如果沒有像Java這樣的靜態類型語言的動態分派,這將是一場艱苦的戰鬥。 – Ben