我知道编写在意参数类型的函数不符合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上留下的一些评论:
稍作修改后,这将非常适合我的用途。我注意到你的实现有一个限制,因为你使用
func.__name__
作为字典键,所以容易出现模块之间的名称冲突,这并不总是理想的。[续][续] 例如,如果我有一个模块重载
func
,而另一个完全不相关的模块也重载了func
,这些重载将会发生冲突,因为函数分派字典是全局的。该字典应该变成局部的,以某种方式。而且不仅如此,它还应该支持某种形式的“继承”。[续][续] 所谓“继承”,是指:假设我有一个名为
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
first.py
文件中的contatenate.overload
是什么意思?按照现有的写法,这会尝试访问concatenate
函数的overload
属性,但在这个例子中该属性并不存在。 - David Z@overload
进行修饰,这将返回一个可调用对象,该对象具有属性overload
。所有后续的重载都应该使用已经存在的对象@object.overload
进行修饰,这样每个对象只有一个字典,而不是全局字典。(它的工作方式类似于标准的@property
。)我会编写一个实现,并在发布时通知您。 - Paul Manta