繁体   English   中英

如果 Python 函数根据参数返回不同的类型,这是好的代码风格吗

[英]Is it good code style if a Python function returns different types depending on the arguments

如果 Python 函数根据提供的参数返回不同的类型,它是否是好的代码风格?

def foo(bar):
  if bar is None:
    return None
  elif bar == 1:
    return 1*1
  else:
    return [b*b for b in bar]

foo返回None如果酒吧是无

foo返回1如果bar == 1

如果 bar 是一个元组/整数列表,则foo返回一个int列表

例子:

>> foo(None)
None
>> foo(1)
1
>> foo(1, 2, 3, 4)
[1, 4, 9, 16]

返回Noneint应该没问题,但是根据函数参数返回intint列表是否可以? 您可能会争辩说这没问题,因为用户知道期望的返回类型并且不需要类型检查(在这种情况下我会说这不行),但有人可能会争辩说最好将函数拆分为两个函数,一个期望一个int并返回一个int ,一个期望一个int列表并返回一个int列表。

这完全取决于您的用例。 这是标准库中的一个示例,其中结果的类型取决于输入的类型

>>> import operator
>>> operator.add(1, 2)
3
>>> operator.add(1.0, 2.0)
3.0

这种类型的行为通常是可以的,可以用@typing.overload


这是一个示例,其中结果的类型取决于输入的

>>> import json
>>> json.loads('1')
1
>>> json.loads('[1]')
[1]

这种类型的行为通常保留给序列化和反序列化,或模糊类型/值边界诸如API的astypenp.int_(3).astype(bool)


另一方面,这是一个明显设计不佳的函数示例:

from typing import Union  # make sure to document the mixed return type

def is_even(x: int) -> Union[bool, str]:
    if x % 2 == 0:
        return True
    else:
        return "no"

在不知道您的具体用例的情况下,很难在这里提供建议。

这个问题没有明确的答案,因此很难制定一个清晰、全面的答案,正如在这个非常相似的问题中所见。

通常,您应该避免从函数返回不同的类型。 例如,我曾经参与过一个项目,其中一个函数看起来像这样:

def get_df(url):
    data = get_data(url)
    df = reformat_data(data)

    if df_is_empty(df):
        return 'Empty dataframe'

    df_interp = interpolate_df(df)
    return df_interp

你可以想象当我得到错误时

AttributeError: 'str' object has no attribute 'iloc'

这让我很困惑,花了大约半天时间才弄清楚这个错误是从哪里来的。 更好的解决方案是引发ValueError

现在,总会有一些奇怪的情况,这个经验法则可能是不正确的。 例如,在抓取网站时,有时也能够检索图像可能很有用。 在这种情况下,我会在您的函数中包含一个标志:

def scrape_website(url, get_images=False):
    data = do_stuff(url)
    ordered_data = order_data(data, get_images)
    return ordered_data

但是,我宁愿将其拆分为两个函数,一个返回非图像数据,一个仅返回图像数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM