2013-03-31 19 views
5

Sono confuso dal seguente comportamento di Python 2.7 e Python 3.3 nella formattazione delle stringhe. Questa è una netta domanda particolare su come l'operatore virgola interagisce con i tipi di presentazione delle stringhe.Commas e stringhe in Python 2.7 string.format()

>>> format(10000, ",d") 
'10,000' 
>>> format(10000, ",") 
'10,000' 
>>> format(10000, ",s") 
ValueError: Cannot specify ',' with 's'. 

>>> "{:,}".format(10000) 
'10,000' 
>>> "{:,s}".format(10000) 
ValueError: Cannot specify ',' with 's'. 

Ciò che mi confonde è per questo che la variante , funziona, l'uno senza esplicito tipo di presentazione di stringa. Il docs dice che se si omette il tipo, è "Lo stesso di s". Eppure qui sta agendo in modo diverso da s.

Ignorerei questo come solo un caso di ruga/angolo, ma questa sintassi viene utilizzata come esempio nei documenti: '{:,}'.format(1234567890). Ci sono altri comportamenti "speciali" nascosti in Python quando il tipo di presentazione della stringa viene omesso? Forse invece di "same as s" cosa sta facendo realmente il codice è l'ispezione del tipo di cosa che viene formattata?

risposta

2

Nel tuo esempio, non interagisce con i tipi di presentazione della stringa; stai interagendo con i tipi di presentazione int. Gli oggetti possono fornire il proprio comportamento di formattazione definendo un metodo __format__. Come osservato in PEP 3101:

The new, global built-in function 'format' simply calls this special 
method, similar to how len() and str() simply call their respective 
special methods: 

    def format(value, format_spec): 
     return value.__format__(format_spec) 

Several built-in types, including 'str', 'int', 'float', and 'object' 
define __format__ methods. This means that if you derive from any of 
those types, your class will know how to format itself. 

Presentazione tipo s non è comprensibilmente implementato da int oggetti (vedere gli elenchi dei tipi di presentazione documentati per oggetto tipo here). Il messaggio di eccezione è in qualche modo fuorviante. Senza il ,, il problema è più chiaro:

>>> format(10000, "s") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: Unknown format code 's' for object of type 'int' 
+1

Ah, le scaglie sono cadute dai miei occhi! Ogni tipo in Python (potenzialmente) definisce il proprio linguaggio di tipo di presentazione tramite '__format __ (self, format_spec)'. Quindi potenzialmente ''d'' or '' 'potrebbe significare qualcosa per un tipo particolare, anche se c'è convenzione. Il bit nei documenti su nessun tipo che è "uguale a' s' "è per i tipi di presentazione stringa. Solo un po 'più in basso nella documentazione, per i tipi di presentazione interi, dice che None è "uguale a' d' ". Quindi ora tutto ha un senso. – Nelson

0

consultare PEP 378 -- Format Specifier for Thousands Separator

L' '' opzione è definito come sopra indicato per tipi 'd', 'e', ​​'f', 'g', 'E', 'G', ' % ',' F 'e' '. Per permettere future estensioni, non è definito per altri tipi: binario, ottale, esadecimale, carattere, ecc

+0

Ah, mi mancava l'inclusione di "" in questa descrizione; quella sarebbe la stringa vuota, nessun tipo? Se è così almeno qualcuno ha inteso il comportamento che sto vedendo, ma sono ancora curioso di sapere cosa sta succedendo e perché è incoerente con i documenti. – Nelson