Способы есть стандартные и велосипедные.
Например стандартная функция питона int, принимающая строковый аргумент, в качестве второго, необязательного, может принимать основание:
print(int('FF', 16))
Велосипедный способ также прост:
def to_str(n, radix):
l = []
while n:
n, d = divmod(n, radix)
l.append("0123456789ABC...Z"[d])
return ''.join(reversed(l))
print(to_str(12345, 10))
Какой из них универсальный, какой - лёгкий - реши для себя сам.