Na documentação são explicadas as diferenças, e basicamente tem a ver com propriedades do Unicode.
isdecimal
verifica se o caractere pertence à categoria Nd (Number, Decimal Digit). Basicamente, são todos desta lista.
Na verdade pode ter alguma diferença, pois o Unicode tem versões, e a cada versão são adicionados novos caracteres. Além disso, cada versão do Python pode usar uma versão diferente do Unicode, então a lista exata pode variar.
Já isdigit
verifica se o caractere tem a propriedade Numeric_Type=Digit ou Numeric_Type=Decimal. E isnumeric
verifica se o caractere tem a propriedade Numeric_Type=Digit, Numeric_Type=Decimal ou Numeric_Type=Numeric.
Repare que isnumeric
acaba sendo mais abrangente, pois testa um valor a mais.
Sobre os diferentes valores da propriedade Numeric_Type, a definição deles está aqui, inclusive com alguns exemplos.
Você pode verificar todos os caracteres com esse código:
for i in range(0x10ffff + 1):
s = chr(i)
dig, dec, num = s.isdigit(), s.isdecimal(), s.isnumeric()
if dig or dec or num:
print(s, dig, dec, num)
Assim você vai ver que para alguns caracteres, todos os métodos retornam True
, enquanto para outros, um ou dois dos métodos retornam False
.
No link já citado tem a explicação dos motivos para cada caractere ter determinado valor para a propriedade Numeric_Type. E vale também ler aqui e aqui para complementar.