Jest to mniej więcej ten sam problem, co w przypadku this question about floats.Formatowanie ciągów z "{0: d}" nie konwertuje na liczbę całkowitą
Gdy masz wartość, która może zostać przekonwertowana na liczbę całkowitą, stara %d
dokona konwersji, ale format nie.
class MyIntegerTenClass:
def __int__(self):
return 10
def __str__(self):
return 'ten'
ten = MyIntegerTenClass()
print '%d, %02X, %s' % (ten, ten, ten) # ok
print '{0}'.format(ten) # ok
print '{0:d}, {0:02X}'.format(ten) # ValueError: Unknown format code 'd' for object of type 'str'
Czy istnieje sposób, aby zmodyfikować zachowanie formatu, bez dotykania klasę wartości mają być sformatowane (bez dodawania metody __format__
do tej klasy)?
Edytuj: Moim celem jest, aby formatowanie było zależne od łańcucha formatu, ale nie od wartości. Więc jeśli ciąg formatu mówi "d" lub "x", przekonwertuj wartość na int, a następnie na reprezentację dziesiętną lub szesnastkową. Jeśli ciąg formatu mówi "s", przekonwertuj go bezpośrednio na ciąg. Tak jak zrobił to stary %
.
Właściwie mógłbym dodać metodę do klasy wartości. Ale jak sprawdzić w tej metodzie, czy podana specyfikacja formatu jest specyfikacją formatu liczb całkowitych? Bez ponownego wdrażania parsera specyfikacji formatu wbudowanego formatu.
Edytuj: Oto rozwiązanie z __format__
i wyjątkami. Jakieś lepsze pomysły?
class MyIntegerTenClass:
def __int__(self):
return 10
def __str__(self):
return 'ten'
def __format__(self, spec):
fmt = '{0:%s}'%spec
try:
return fmt.format(str(self))
except:
return fmt.format(int(self))
ten = MyIntegerTenClass()
print '%d, %02X, %s' % (ten, ten, ten) # ok, prints "10, 0A, ten"
print '{0:d}, {0:02X}, {0}'.format(ten) # ok, prints "10, 0A, ten"
Mówi, że dziesięć jest ciągiem, próbujesz sformatować go jako liczbę. –