Python调整返回类型以考虑输入类型 在C++和C等中,可以重载或调整返回类型以匹配输入类型。使用Python,我发现引用的返回类型应该是一致的
现在来看我的代码,它希望将返回类型与参数类型相匹配Python调整返回类型以考虑输入类型 在C++和C等中,可以重载或调整返回类型以匹配输入类型。使用Python,我发现引用的返回类型应该是一致的,python,return-type,Python,Return Type,现在来看我的代码,它希望将返回类型与参数类型相匹配 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
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有类型提示,需要等到夏天晚些时候再学习
任何人都有一种不那么罪恶的方式来获得大部分好处?或者一个连贯的论点,为什么不应该这样做
附录:除了我喜欢的蟒蛇摩西。我觉得有必要找出这个问题是否最好用Python2.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返回类型的不成文规则 您实际上可以检查类型,而不是依赖异常
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
您可以使用
isinstance
——将dict的键/值以及列表项递归传递给函数将处理更多类型:
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
如果您希望返回类型与参数(确切地说,是第一个参数)具有某种一致性,则可以使用创建函数的重载实现;我要说的一个原因是您开始使用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
把我的五分钱放在那里:
hanlders = {
str: (lambda what_is_this_thing: what_is_this_thing.upper()),
dict: (lambda what_is_this_thing: {k:what_is_this_thing[k].upper() for k in what_is_this_thing}),
list: (lambda what_is_this_thing: [x.upper() for x in what_is_this_thing]),
}
print handlers[type(what_is_this_thing)](what_is_this_thing)
可以,但在python中这不是首选。我的问题是关于返回类型。您应该使用
isinstance
进行类型嗅探,而不是比较类型对象<代码>如果存在(v,str)等再次。。。不是我的问题。如果我以这种方式调整我的返回类型,考虑到返回类型通常是一致的类型,那么它有多大,这在很大程度上取决于您将如何使用它。这并不是一个“罪过有多严重”的问题,更像是“这会在将来引起麻烦吗?”之类的问题。如果你只想把它用于另一个函数的内部函数,那么没问题。如果它将被许多人广泛使用,那么你应该力求清晰;在这种情况下,有必要对导致您首先将不同类型传递给同一函数的情况提出质疑。好的,考虑到该函数旨在广泛使用许多源数据类型,因此,在公司内部的通用库中使用该函数似乎是合理的。你明白了吗?我可以用不同的名字写3个函数。有人能为这种重载提供更多名称空间的参数吗?如果您对该参数了解不够,不知道是否要将其传递给strUpper
、listUpper
、或dictUpper
,那么您就不知道从myUpper
得到了什么。这是真的。为了突出重点,我知道所有我可以测试输入类型的方法。我选择得到宽恕而不是允许。我猜字符串更常见,而dicts和list是最不常见的。我的问题是针对公共库内部函数。我甚至可以使用一个类来隐藏类型特定的版本,这对我来说并不重要。问题是一个函数应该只有一个返回类型的论点有多强。在本例中,您将返回与传入内容相关的内容。有些Python函数可以返回多种类型的值,但它们往往分为两类。1) f
将返回类型为t
的值,或者返回None
。2) 函数将返回类型为t
的值,但任何此类类型都将支持迭代/映射等。返回一个唯一标识特征是匹配输入类型的值只是推迟了最终确定返回的值类型的需要。。。。。。。也就是说,你的例子可以理解为遵循我的第二点;由于将每个值用作打印的参数,因此可以假定myUpper
返回一个支持\uuuu str\uuuuuuu
(或至少\uuu repr\uuuu
)的值。但是为了清楚起见,我强烈主张函数应该有一个独立于输入类型的、定义良好的返回类型?这就是重点。我认为这还不够清楚。或者说它太不一样了,不需要使用\uuuu name\uuuu
;您可以使用类型对象作为处理程序
的键。这根本不处理子类。我对case语句使用处理程序模式,类似于它。在这种情况下,我同意子类的问题使它太局限了+这不是主要问题。这个后端口会吗?我一直在检查,还没有找到解决办法。我想我找到了一个源代码,我将通过后端口尝试解决这个问题。谢谢大家!