【发布时间】:2012-01-29 02:13:24
【问题描述】:
我知道编写关心参数类型的函数不是 Pythonic,但在某些情况下根本不可能忽略类型,因为它们的处理方式不同。
在你的函数中有一堆 isinstance 检查只是丑陋的;是否有任何可用的函数装饰器可以启用函数重载?像这样的:
@overload(str)
def func(val):
print('This is a string')
@overload(int)
def func(val):
print('This is an int')
更新:
这是我在David Zaslavsky's answer留下的一些cmets:
经过一些修改[s],这将非常适合我的目的。我在您的实现中注意到的另一个限制,因为您使用
func.__name__作为字典键,您很容易在模块之间发生名称冲突,这并不总是可取的。 [继续][cont.] 例如,如果我有一个模块重载
func,而另一个完全不相关的模块也重载func,这些重载将发生冲突,因为函数 dispatch dict 是全局的。该 dict 应该以某种方式对模块进行本地化。不仅如此,它还应该支持某种“继承”。 [继续][继续] '继承'我的意思是:假设我有一个模块
first有一些重载。然后是另外两个不相关但每个导入first的模块;这两个模块都为它们刚刚导入的现有模块添加了新的重载。这两个模块应该能够使用first中的重载,但是它们刚刚添加的新模块不应在模块之间相互冲突。 (现在想想,这实际上很难做到。)
其中一些问题可以通过稍微改变装饰器语法来解决:
first.py
@overload(str, str)
def concatenate(a, b):
return a + b
@concatenate.overload(int, int)
def concatenate(a, b):
return str(a) + str(b)
second.py
from first import concatenate
@concatenate.overload(float, str)
def concatenate(a, b):
return str(a) + b
【问题讨论】:
-
嗯...所以在您的编辑中,
contatenate.overload中的first.py到底是什么意思?如所写,这将尝试访问concatenate函数的overload属性,本示例中不存在该属性。 -
@DavidZaslavsky 函数的第一个重载应该用
@overload修饰,这将返回一个具有overload属性的可调用对象。所有后续的重载都应该用这个已经存在的对象@object.overload装饰,所以每个对象只有一个字典,而不是全局字典。 (它的工作方式类似于标准的@property。)我将编写一个实现并在发布时通知您。 -
这将背离传统的重载语法。但是,如果这就是您想要的,请查看overload package(我将在我的答案中进行编辑)。它基本上使用了这种方法。
标签: python overloading decorator