Decorator para sobrecarga em Python
Eu sei que não é Pythonic escrever funções que se importam com o tipo dos argumentos, mas há casos em que é simplesmente impossível ignorar tipos porque eles são tratados de maneira diferent
Tendo um monte deisinstance
verifica sua função é simplesmente feia; existe algum decorador de funções disponível que permita sobrecargas de funções? Algo assim
@overload(str)
def func(val):
print('This is a string')
@overload(int)
def func(val):
print('This is an int')
Atualizar
Aqui estão alguns comentários que deixei emDavid Zaslavsky's answer:
Com algumas modificações, isso atenderá muito bem aos meus objetivos. Outra limitação que notei na sua implementação, já que você usafunc.__name__
como chave do dicionário, você costuma nomear colisões entre módulos, o que nem sempre é desejável. [continua]
[cont.] Por exemplo, se eu tiver um módulo que sobrecarregafunc
e outro módulo completamente independente que também sobrecarregafunc
, essas sobrecargas colidirão porque o ditado de despacho da função é global. Esse ditado deve ser tornado local para o módulo, de alguma forma. E não apenas isso, também deve apoiar algum tipo de 'herança'. [continua]
[cont.] Por 'herança' quero dizer o seguinte: digamos que eu tenho um módulofirst
com algumas sobrecargas. Em seguida, mais dois módulos não relacionados, mas cada um importfirst
; esses dois módulos adicionam novas sobrecargas às já existentes que eles acabaram de importar. Esses dois módulos devem poder usar as sobrecargas emfirst
, mas os novos que eles acabaram de adicionar não devem colidir entre si entre os módulos. (Isso é realmente muito difícil de fazer, agora que penso nisso.)
Alguns desses problemas podem ser resolvidos alterando um pouco a sintaxe do decorador:
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