【问题标题】:Is this function overloading or something?这个函数是重载还是什么?
【发布时间】:2012-03-15 00:46:23
【问题描述】:
def func(a, b, c='four'):
    print 'a is %s, b is %s, c is %s' %(a, b ,c)

func('one','two','three')
func('one', 'two')

这段代码运行没有问题。但这叫什么? '重载'?

顺便说一句,这种风格是否仅在 Python 中可用?谢谢!

【问题讨论】:

    标签: python overloading


    【解决方案1】:

    Python 称它们为“default argument values”。这是一种非常简单的函数重载形式(在 'arity' 上重载(即函数有多少个参数))。不过,这与 Python 中的函数重载一样复杂。

    由于希望保持语言相当简单以及 Python 变量在运行时只有一个类型这一事实,Python 不能按类型重载。如果你愿意,你可以使用isinstance 来滚动你自己的重载,但是生成的代码很乱,我不推荐它。

    其他语言也有默认参数。例如,C++ 也允许使用默认参数,而 C++ 明确地将默认参数视为函数重载的一种形式。

    Python 默认参数与 C++ 的不同之处在于 Python 具有命名参数,这意味着您可以显式覆盖特定的默认值而不覆盖其他默认值。

    例如:

    def foo(bar, baz="A baz", qux=0):
        return "(%r, %r, %r)" % (bar, baz, qux)
    
    foo(5)
    (5, 'A baz', 0)
    foo(5, qux=2)
    (5, 'A baz', 2)
    

    还有其他语言也允许这样做。例如,我相信这是 Ruby 允许的,尽管我不确定语法是什么。

    最后,奇怪的是,Python 有运算符重载。这是通过作为类的一部分的functions with special reserved names 管理的。此类函数的格式始终为__name__。在任何单个运算符的情况下,运算符重载的确切规则可能有点奇怪,我通常建议不要在大多数情况下使用此功能,尤其是在重载数字或关系运算符时。

    【讨论】:

    • 总的来说这是一个很好的答案;我喜欢你对命名参数的讨论。但我不同意你的一些 cmets 关于运算符重载的观点。当您的类表示某种数字或一组数字时,运算符重载非常有用,并且如果数学运算定义明确,那么运算符重载是提供这些数学运算的最佳方式。如果尚未内置复数,我将重载+- 和其他运算符,以便可以在普通表达式中使用复数。同样,SciPy 重载了矩阵等的运算符。
    • @steveha - 我基本上同意这一点。尽管大多数人并不经常编写模拟数字的类。此外,它仍然很棘手,因为您必须重载正确的运算符组合才能获得每个人都期望的行为,如果不这样做,您会得到一些令人惊讶的结果。但是,运算符重载总是如此。至少 Python 有 containers 模块,它可以很容易地重载最少的运算符集以获得类似容器的行为。
    • @Omnifarious,我绝对同意必须小心地进行运算符重载。
    【解决方案2】:

    不,这是default argument values 的示例。

    many languages 中提供了默认参数值。

    【讨论】:

      【解决方案3】:

      正如其他人所指出的,这是默认参数,而不是运算符重载。

      Python 执行实际运算符重载的方式是具有特殊的方法函数,您可以选择在类中定义这些函数。因为 Python 是这样做的,所以不可能仅在内置类型上重载操作;您不能在表达式1 + 1 中重载+ 运算符。但是,您可以创建int 的子类并重载该子类以执行您想要的任何操作。 MyClass(1) + 1 可能有一个重载的 + 运算符。

      有关 Python 中运算符重载的更多信息:

      operator overloading in python

      【讨论】:

      • 我认为你的答案比我的好一点,尽管我认为默认参数是一种重载形式。 :-)
      【解决方案4】:

      它被称为默认参数值

      这不是 Python 独有的功能,C++ 就是一个例子,还有更多。

      Python 不支持函数重载(与 C++ 不同)。函数重载是指您有多个同名函数,编译器会根据传递的参数数量及其类型确定您正在调用的函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-10
        • 1970-01-01
        • 1970-01-01
        • 2020-03-08
        • 2019-06-30
        • 2015-03-20
        相关资源
        最近更新 更多