【问题标题】:C++ methods overload in pythonpython中的C++方法重载
【发布时间】:2010-08-13 11:35:02
【问题描述】:

假设一个C++类有几个构造函数,它们根据各自参数的个数、类型和顺序被重载,例如constructor(int x, int y)constructor(float x, float y, float z),我认为这两个是重载方法,使用哪个取决于参数,对吧?那么在python中,我怎么能创建一个可以像这样工作的构造函数呢?我注意到python有def method(self, *args, **kwargs):,所以我可以这样使用:def __init__(self, *args),然后我检查*args的长度,如if len(args) == 2:,然后根据2参数构造函数,if len(args) == 3,然后使用 3 参数构造函数等。那么,这行得通吗?或者有没有更好的方法来用python做到这一点?或者我应该以其他方式思考可以利用 python 特性本身的优势吗?谢谢~

【问题讨论】:

    标签: c++ python constructor overloading


    【解决方案1】:

    通常,您可以使用任何组合

    • 设计略有改动
    • 默认参数 (def __init__(self, x = 0.0, y = 0.0, z = 0.0))
    • 使用多态性(在鸭子类型的语言中,如果 SomeThing 和 SomeSlightlyDifferentThing 都没有从另一个继承,则不需要重载,只要它们的接口足够相似)。

    如果这似乎不可行,请加倍努力;)如果仍然不可行,请查看 David 的链接。

    【讨论】:

      【解决方案2】:

      这真的取决于你想做什么。 *args/**kwargs 方法运行良好,delnan 建议的默认参数也是如此。

      在这种情况下,C++ 和 Python 之间的主要区别在于您尝试做什么的whatwhy。如果您有一个需要浮点数的类,只需尝试将参数转换为浮点数。您还可以依靠默认参数来分支您的逻辑:

      class Point(object):
          def __init__(self, x=0.0, y=0.0, z=None):
              # Because None is a singleton, 
              # it's like Highlander - there can be only one! So use 'is'
              # for identity comparison
              if z is None:
                  self.x = int(x)
                  self.y = int(y)
                  self.z = None
              else:
                  self.x = float(x)
                  self.y = float(y)
                  self.z = float(z)
      
      p1 = Point(3, 5)
      p2 = Point(1.0, 3.3, 4.2)
      p3 = Point('3', '4', '5')
      points = [p1, p2, p3]
      for p in points:
          print p.x, p.y, p.z
      

      当然,您不必指定self.z = None,这只是为了方便我的示例。

      关于使用哪种模式的最佳建议,

      在 [17] 中:导入此
      Python 之禅,蒂姆·彼得斯(Tim Peters)

      美丽胜于丑陋。
      显式优于隐式。
      简单胜于复杂。
      ...

      如果您的模式美观、明确且简单,那么它可能是正确的选择。

      【讨论】:

        【解决方案3】:
        I think these two are overloaded methods, which one to use depends on the parameters, right? 
        

        对不起,如果我似乎在吹毛求疵,但只是想清楚地指出这种差异。

        术语参数和实参在 C++ 中具有非常特殊的含义

        参数:函数调用表达式中由括号包围的逗号分隔列表中的表达式,类函数宏调用中由括号包围的逗号分隔列表中的一系列预处理标记, throw 的操作数, 或模板实例化中由尖括号包围的逗号分隔列表中的表达式、类型 ID 或模板名称。也称为实参或实参。

        参数:作为函数声明或定义的一部分或在异常处理程序的 catch 子句中声明的对象或引用,它在进入函数或处理程序时获取值;逗号分隔列表中的标识符,由括号包围,紧跟在类似函数的宏定义中的宏名称之后;或模板参数。形参也称为形参或形参

        【讨论】:

        • -1 表示未回答问题,+0.1 表示正确 = -0.9 舍入为 -1 ;)
        • 顺便说一句,C++ 支持向 0 舍入 :) int main(){ double d = -1 + 0.1;诠释 x = d; cout
        • @chubsdad,输出是什么? :D
        • @delnan:我还应该得到-1吗?
        • 虽然我是新来的,但我发现这非常有趣
        【解决方案4】:

        This article 讨论如何在 Python 中创建多方法装饰器。我还没有尝试过他们提供的代码,但它定义的语法看起来相当不错。这是文章中的一个示例:

        from mm import multimethod
        
        @multimethod(int, int)
        def foo(a, b):
            ...code for two ints...
        
        @multimethod(float, float):
        def foo(a, b):
            ...code for two floats...
        
        @multimethod(str, str):
        def foo(a, b):
            ...code for two strings...
        

        【讨论】:

        • 是的,这对于一些类似的问题可能是一个很好的解决方案,我担心的是如果构造函数中的参数数量彼此不同,而不仅仅是类型?正如那篇文章中所说的“那么什么是多方法?我会给你我自己的定义,因为我已经理解了它们:一个有多个版本的函数,由参数的类型来区分。”
        • @ladyfafa:从外观上看,您也可以拥有具有不同数量参数的函数版本。他们提供的装饰器似乎只是将给定的类型元组(例如(int, int))映射到*args,以便决定调用哪个版本的方法。
        • python中有没有叫mm的模块?
        • @ladyfafa:不,我链接的文章提供了该模块中的代码。它没有随 Python 一起提供,而且我还没有看足够多的代码来知道它是否有任何好处。不过,他们使用的方法(装饰器)似乎不错。
        • 即使这是由 GvR 编写的,也是可怕的代码。根据你给出的论点的类型做不同的事情违背了 Python 哲学的一大块。你应该知道你的参数实现了什么接口;调用者知道,当他们可以选择适当的函数时,他们不应该丢弃该信息。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-07
        相关资源
        最近更新 更多