2017-06-17 30 views
2

在C++和C#等中,可以重載或調整返回類型以匹配輸入類型。使用Python我發現引用返回類型應該是一致的,無論。 Like in this questionPython調整返回類型以考慮輸入類型

現在我的代碼,想要返回類型匹配參數類型

def myUpper(what_is_this_thing): 
    try: 
     return what_is_this_thing.upper() 
    except AttributeError: 
     try: 
      return {k:what_is_this_thing[k].upper() for k in what_is_this_thing} 
     except TypeError: 
     return [x.upper() for x in what_is_this_thing] 

print myUpper('test') 
print myUpper(['test', 'and more']) 
print myUpper({'one':'test', 'two': 'and more'}) 
print myUpper(['test', 1000]) 

輸出

TEST 
['TEST', 'AND MORE'] 
{'two': 'AND MORE', 'one': 'TEST'} 
An exception is rased because the payload does not have a upper method 

那麼如何壞這條巨蟒的罪?我大多仍然在2.7的工作我知道3.3有類型提示,學習需要等待在夏天晚些時候。

任何人都有一個沒有罪惡的方式來實現大部分好處?或爲什麼不應該這樣做的一個連貫的論點?

附錄:
除了我喜歡的Python3摩西。我覺得有必要找,如果這個問題最好的東西在Python 2.7

def myUpper(s): 
    return s.upper() 
print myUpper('test') 
print [s.myUpper() for s in 'test', 'and more'] d = { 'one':'test', 'two': 'and more'} 
print {k:d[k].myUpper() for k in d} 

總之蔓延理解的東西回答像在守則中規定,即使是很常見的。選擇模糊返回數據類型的理解擴散?

我懷疑我會在最終代碼中刪除400多個理解行,如果我是通過調整返回類型來完成的話。但如果這太奇怪,那就這樣吧。

歸結爲可讀性侵犯了關於1函數1返回類型的不成文規則。

+0

如果你不夠了解的說法知道是否將它傳遞到'strUpper','listUpper'或'dictUpper',無論如何你都不知道你從myUpper獲得什麼。 – chepner

+0

這是真的。爲了突出重點,我知道他們可以測試輸入類型的所有方法。我選擇得到原諒而不是允許。我可以猜測字符串更常見,字典和列表是最不可預期的。我的問題是針對通用庫內部函數。我甚至可能使用一個類來隱藏類型特定的版本,這對我來說並不重要。問題是一個函數應該只有一種返回類型的說法有多強烈。在這種情況下,你可以找回與你傳入的東西有關的東西。 – user2315423

+0

有一些Python函數可以返回多種類型的值,但它們往往分爲兩類。 1)'f'將返回一個't'類型的值,否則它將返回'None'。2)一個函數將返回一個't'類型的值,但是任何這樣的類型都會支持迭代/映射/等等。返回一個唯一的識別特徵是匹配輸入類型的值只是推遲最終需要找出你回來的是什麼類型的值...... – chepner

回答

3

如果你正在尋找爲了使返回類型與參數保持一致性(確切地說,第一個參數),您可以使用functools.singledispatch創建函數的重載實現;原因之一,我會說你開始移動到Python 3:

from functools import singledispatch 

@singledispatch 
def my_upper(what_is_this_thing): 
    return what_is_this_thing.upper() 

@my_upper.register(list) 
def _(this_is_a_list): 
    ... 
    return this_is_also_a_list 

@my_upper.register(dict) 
def _(this_is_a_dict): 
    ... 
    return this_is_also_a_dict 
+0

這個backport嗎?我一直在檢查,還沒有看到一種方式。 – user2315423

+0

我想我找到了一個源代碼,我將嘗試這個[backport](https://pkgs.org/download/python2.7(singledispatch)) – user2315423

+0

通過後端口工作。謝謝大家! – user2315423

0

您實際上可以檢查類型而不是依賴於例外。

v = 'one' 
if type(v) == str: 
    # Treat it as a string 
elif type(v) == list: 
    # Treat it as a list 
elif type(v) == dict: 
    # Treat is as a dict 
+0

print {k:d [k] .upper()for k in d}但是這在Python中不是首選。我的問題是關於返回類型。 – user2315423

+1

您應該使用'isinstance'來進行類型嗅探,而不是比較類型對象。 '如果是isinstance(v,str)'等等 – chepner

+0

......不是我的問題。如果我以這種方式調整我的返回類型,考慮到返回類型通常是一致的類型,它有多大的pythonic罪。 – user2315423

0

你可以使用isinstance - 並通過一個字典的鍵/值以及遞歸的功能列表中的項目將處理更多類型:

def myUpper(o): 
    if(isinstance(o, str)): 
     return o.upper() 
    elif(isinstance(o, list)): 
     return [myUpper(x) for x in o] 
    elif(isinstance(o, dict)): 
     return {myUpper(k):myUpper(v) for k,v in o.items()} 
    else: 
     return o