% string formatting - what special method is used for %d?

Veek M vek.m1234 at gmail.com
Sun Dec 11 01:40:37 EST 2016


Steve D'Aprano wrote:

> On Sat, 10 Dec 2016 06:06 pm, Veek M wrote:
> 
>> When we do:
>> 
>> print '%s %d' % ('hello', 10)
>> 
>> what special method is being invoked internally within the string-
>> format-specifier?
> 
> %d requires the argument to be an int, or able to be converted to int
> using the __int__ special method.
> 
> 
> py> class X(object):
> ...     def __int__(self):
> ...             return 42
> ...
> py> "%d" % X()
> '42'
> 
> 
> 
>> format() invokes format__
>> print invokes __str__
> 
> print actually invokes __str__ or __repr__, whichever is available.
> 
> 
> 
>> I'm basically trying to make sense of:
>> 
>> raise TypeError('urkle urkle %s' % list(dictionary))
>> <=> raise TypeError('urkle urkle %s' % [ key1, val1, key2, val2 ]
> 
> 
> The raise TypeError part of the code is irrelevant to your question.
> You should always simplify your code to only the part that is
> relevant.
> 
> raise TypeError(some_string)
> 
> behaves the same regardless of how some_string is made.
> 
> 
>> So, the % operator reads the format specifier and notices %s and
>> therefore calls __str__ in the list class to figure out how to
>> represent
>> [ key1, val1, key2, val2 ].
>> 
>> However what if I use %d? How do the other format specs work?
> 
> 
> The format specifiers are similar to these:
> 
> %s => str(obj), which ends up calling __str__ or __repr__
> 
> %r => repr(obj), which ends up calling __repr__ or __str__
> 
> %c => chr(obj), or obj must be a string of length 1
> 
> %d %i %u => int(obj), which ends up calling __int__
> 
> %x %X => int(obj), then convert to hexadecimal
> 
> %o => int(obj), then convert to octal
> 
> %e %E %f %g %G => float(obj), which ends up calling __float__
> 
> %% => a literal % sign
> 
> 
> 
> 
> 

Well take a look at this:
###########################################
#!/usr/bin/python

class Foo(int):
    def __init__(self, value):
        self.value = value
        
    def __str__(self):
        print '__str__'
        return str(self.value)
    
    def __int__(self):
        print '__int__'
        return self.value + 1
    

#'%s' % Foo(10) # %s is mapped to __str__
'%d' % Foo(20)
###########################################

here, '__str__' prints because when you do:
'%s' % x
the __str__ method is invoked. So internally %s invokes __str__ 
independent of print.

However the next line doesn't trigger any similar invocation with 
__int__ or__str__? (but int(Foo(10)) would invoked __int__)

Is there a way to trigger special methods using %d etc OR is this 
restricted to %s and why?










More information about the Python-list mailing list