¿Funcionaría esto para su situación?
>>> s = '12abcd405'
>>> result = ''.join([i for i in s if not i.isdigit()])
>>> result
'abcd'
Esto hace uso de una lista de comprensión, y lo que está sucediendo aquí es similar a esta estructura:
no_digits = []
# Iterate through the string, adding non-numbers to the no_digits list
for i in s:
if not i.isdigit():
no_digits.append(i)
# Now join all elements of the list with '',
# which puts all of the characters together.
result = ''.join(no_digits)
Como señalan @AshwiniChaudhary y @KirkStrauser, en realidad no es necesario usar los corchetes en el one-liner, lo que hace que la pieza dentro del paréntesis sea una expresión generadora (más eficiente que una comprensión de lista). Incluso si esto no cumple con los requisitos de su tarea, es algo sobre lo que debería leer eventualmente :):
>>> s = '12abcd405'
>>> result = ''.join(i for i in s if not i.isdigit())
>>> result
'abcd'
re:result = re.sub(r'[0-9]+', '', s)