2017-06-17 79 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