Text formatting error: '=' alignment not allowed in string format specifier

前端 未结 6 1423
庸人自扰
庸人自扰 2020-12-30 19:24

What does \'=\' alignment mean in the following error message, and why does this code cause it?

>&         


        
相关标签:
6条回答
  • 2020-12-30 19:52

    str.__format__ doesn't know what to do with your 03 part. That only works with numbers:

    >>> "{num:03}".format(num=1)
    '001'
    

    If you actually want to zero-pad a string, you can use rjust:

    >>> "1".rjust(3, "0")
    '001'
    
    0 讨论(0)
  • 2020-12-30 19:57

    The error message occurs because '=' alignment has been implied by the format specifier.

    The str.format format spec mini-language parser has decided on the alignment specifier “=” because:

    Preceding the width field by a zero ('0') character enables sign-aware zero-padding for numeric types. This is equivalent to a fill character of '0' with an alignment type of '='.

    So by specifying 0N as the “zero-padding to N width”, you have implied both “the input is a numeric type”, and “the zeros should go between the sign and the digits”. That latter implication is what is meant by '=' alignment.

    Since the value "1" is not numeric, the “=”-alignment handling code raises that exception. The message is written expecting you know what it's talking about because you requested (by implication) the “=” alignment.

    Yes, I think that error message needs to be improved. I've raised an issue for that.

    0 讨论(0)
  • 2020-12-30 19:57

    In my case, I was trying to zero-pad a string instead of a number.

    The solution was simply to convert the text to a number before applying the padding:

    num_as_text = '23'
    num_as_num = int(num_as_text)
    padded_text = f'{num_as_num:03}'
    
    0 讨论(0)
  • 2020-12-30 20:00

    A workaround is to use '>' (right justify) padding, which is with the syntax:

    [[fill]align][width]
    

    with align being >, fill being 0 and width being 3.

    >>> "{num:0>3}".format(num="1")
    '001'
    

    The problem was that there is a different 0 in the format specification:

    format_spec     ::=  [[fill]align][sign][#][0][width][grouping_option][.precision][type]
    #                                          ^^^ This one
    

    That zero just makes fill default to 0 and align to =.

    = alignment is specified as:

    Forces the padding to be placed after the sign (if any) but before the digits. This is used for printing fields in the form ‘+000000120’. This alignment option is only valid for numeric types. It becomes the default when ‘0’ immediately precedes the field width.

    Source (Python 3 docs)

    This expects the argument to be an int, as strings don't have signs. So we just manually set it to the normal default of > (right justify).

    Also note that 0 just specifies the default values for fill and align. You can change both or just the align.

    >>> # fill defaults to '0', align is '>', `0` is set, width is `3`
    >>> "{num:>03}".format(num=-1)
    '0-1'
    >>> # fill is `x`, align is '>', `0` is set (but does nothing), width is `"3"`
    >>> "{num:x>03}".format(num=-1)
    'x-1'
    >>> # fill is `x`, align is '>', `0` is set (but does nothing), width is `"03"` (3)
    >>> "{num:x>003}".format(num=-1)
    'x-1'
    
    0 讨论(0)
  • 2020-12-30 20:00

    You are trying to insert 'string->"1" where a float->3.44 is required. Remove the quotes "1", i.e. num=1, and it will work

    0 讨论(0)
  • 2020-12-30 20:04

    This format would be acceptable

    "{num}:03".format(num="1")
    

    but the way you have the placeholder specified {num:03} is not. That is an interesting ValueError though, if you remove the : the interesting error is replaced by a standard KeyError.

    0 讨论(0)
提交回复
热议问题