【问题标题】:python - How the overloading methods get loadedpython - 如何加载重载方法
【发布时间】:2013-03-19 04:58:47
【问题描述】:

问题:

  1. python 是否以这种方式加载方法 - 谁最后谁赢?即使您有两个方法共享确切的名称,即使使用不同的参数(不同的签名),最后一个方法也会覆盖前面的所有方法而不会出现运行时错误?
  2. 如果python没有重载,那么python推荐的JAVA重载方式是什么?

下面的例子:

class Base(object):
    def __init__(self):
        print "Base created without args"
    def __init__(self, a):
        print "Base created " + a + "\n"

print Base("test") 给我:

Base created test

<__main__.Base object at 0x1090fff10>

虽然print Base() 给了我:

Traceback (most recent call last):
File "${path to super file}/super.py", line 27, in <module>
print Base()
TypeError: __init__() takes exactly 2 arguments (1 given)

【问题讨论】:

标签: python constructor


【解决方案1】:
  1. 基本上,您自己已经回答了这个问题。 Python 不关心方法签名,只关心名称。这也适用于模块级函数。
  2. 与 Java 不同,Python 允许您为方法参数指定默认值(我认为这更方便):

    class Base(object):
        def __init__(self, a=None):
            if a is None:
                print "Base created without args."
            else:
                print "Base created with %s" % a
    
    a = Base()    # prints "Base created without args."
    b = Base(123) # prints "Base created with 123."
    

【讨论】:

  • 此外,duck-typing 消除了在大多数其他情况下对方法重载的需要。
【解决方案2】:

您可以使用装饰器滚动您自己的方法重载:

class OverloadFunction(object):

    def __new__(cls, f):
        self = object.__new__(cls)
        setattr(self, "_dct", {})
        return self.overload(())(f)

    def overload(self, signature):
        def wrapper(f):
            self._dct[signature] = f
            return self
        return wrapper

    def __call__(self, *args, **kwargs):
        return self._dct[self._get_signature(args)](*args, **kwargs)

    def _get_signature(self, obj):
        return tuple(type(x) for x in obj)


@OverloadFunction
def hello():
    print "hello, no args"

@hello.overload((int,))
def hello(i):
    print "hello with an int argument:", i

@OverloadFunction
def add(): pass

@add.overload((int, int))
def add(a, b):
    print "integer addition, %d + %d = %d" % (a, b, a + b)

@add.overload((str, int))
def add(a, b):
    print "string concatentation, %r + %d = %r" % (a, b, a + str(b))

hello()
hello(1)
add(2, 3)
add("a", 3)

哪些输出:

hello, no args
hello with an int argument: 1
integer addition, 2 + 3 = 5
string concatentation, 'a' + 3 = 'a3'

【讨论】:

  • 虽然,作为helmbert said,您可能应该只使用默认参数。
猜你喜欢
  • 2012-02-13
  • 2012-04-29
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
相关资源
最近更新 更多