Python string format: When to use !s conversion flag - python

What's the difference between these 2 string format statements in Python:
'{0}'.format(a)
'{0!s}'.format(a)
Both have the same output if a is an integer, list or dictionary. Is the first one {0} doing an implicit str() call?
Source
PS: keywords: exclamation / bang "!s" formatting

It is mentioned in the documentation:
The conversion field causes a type coercion before formatting.
Normally, the job of formatting a value is done by the __format__()
method of the value itself. However, in some cases it is desirable to
force a type to be formatted as a string, overriding its own
definition of formatting. By converting the value to a string before
calling __format__(), the normal formatting logic is bypassed.
Two conversion flags are currently supported: '!s' which calls
str() on the value, and '!r' which calls repr().
An example can be taken (again from the documentation) to show the difference:
>>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
"repr() shows quotes: 'test1'; str() doesn't: test2"

Simply said:
'{0}'.format(a) will use the result of a.__format__() to display the value
'{0!s}'.format(a) will use the result of a.__str__() to display the value
'{0!r}'.format(a) will use the result of a.__repr__() to display the value
>>> class C:
... def __str__(self): return "str"
... def __repr__(self): return "repr"
... def __format__(self, format_spec): return "format as " + str(type(format_spec))
...
>>> c = C()
>>> print "{0}".format(c)
format as <type 'str'>
>>> print u"{0}".format(c)
format as <type 'unicode'>
>>> print "{0!s}".format(c)
str
>>> print "{0!r}".format(c)
repr
Concerning the second argument of __format__, to quote PEP 3101 "Controlling Formatting on a Per-Type Basis":
The 'format_spec' argument will be either
a string object or a unicode object, depending on the type of the
original format string. The __format__ method should test the type
of the specifiers parameter to determine whether to return a string or
unicode object. It is the responsibility of the __format__ method
to return an object of the proper type.

Thanks to the comment & answer from #hjpotter92 for explanation:
Here's an example that shows the difference (it's when you override the __format__ method)
class MyClass:
i = 12345
def __format__(self, i):
return 'I Override'
>>> obj = MyClass()
>>> '{0}'.format(obj)
'I Override'
>>> '{0!s}'.format(obj)
'<__main__.MyClass instance at 0x021AA6C0>'

Related

What to do with the error [<__main__.Student object at 0x000001E84D968090>, <__main__.Student object at 0x000001E84D95E750>] [duplicate]

This question already has answers here:
How to print instances of a class using print()?
(12 answers)
Closed 7 months ago.
Well this interactive python console snippet will tell everything:
>>> class Test:
... def __str__(self):
... return 'asd'
...
>>> t = Test()
>>> print(t)
asd
>>> l = [Test(), Test(), Test()]
>>> print(l)
[__main__.Test instance at 0x00CBC1E8, __main__.Test instance at 0x00CBC260,
__main__.Test instance at 0x00CBC238]
Basically I would like to get three asd string printed when I print the list. I have also tried pprint but it gives the same results.
Try:
class Test:
def __repr__(self):
return 'asd'
And read this documentation link:
The suggestion in other answers to implement __repr__ is definitely one possibility. If that's unfeasible for whatever reason (existing type, __repr__ needed for reasons other than aesthetic, etc), then just do
print [str(x) for x in l]
or, as some are sure to suggest, map(str, l) (just a bit more compact).
You need to make a __repr__ method:
>>> class Test:
def __str__(self):
return 'asd'
def __repr__(self):
return 'zxcv'
>>> [Test(), Test()]
[zxcv, zxcv]
>>> print _
[zxcv, zxcv]
Refer to the docs:
object.__repr__(self)
Called by the repr() built-in function and by string conversions (reverse quotes) to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required.
This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.

why formatted strings do not need to have type conversion before including the variable or operation in the {curly brackets}?

as you know , python is a strongly typed language that does not allow concatenation of type int with str.
As you can see below; As I stated above python does not allow for such operations(concatenation of str with int due to the language's features).
a = 10
b = '20'
print(a + b)
#throws the error **TypeError: unsupported operand type(s) for +: 'int' and 'str'**
But Look into this too:
a = 1
b = '2'
print(f"{a} and {b}")
print("{} and {}".format(a, b))#or this for example
Here I did not converted variable a which has an int type assigned to ; into string, but I can include it in the formatted string
My question is ... what happens under the curtains when python interpreter encounters with this expression print(f"{a} and {b}")
what happens under the curtains when python interpreter encounters with this expression print(f"{a} and {b}")
What happens is that before a and b are built into the string, str(a) and str(b) are called. You can see this yourself when you build 2 classes like this:
class Test1(object):
pass
class Test2(object):
def __str__(self):
return "surprise"
which do the same (nothing) but Test2 returns "surprise" when str(Test2()) is called.
When you want to convince yourself try this:
t1 = Test1()
t2 = Test2()
print(t1)
print(t2)
print(f"{t1}")
print(f"{t2}")
print("{}".format(t1))
print("{}".format(t2))
Each time the same two lines are printed.
This is documented in chapter 2 of Python's documentation:
If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion '!s' calls str() on the result, '!r' calls repr(), and '!a' calls ascii().
If no conversion is specified, it immediately continues to the following step:
The result is then formatted using the format() protocol. The format specifier is passed to the __format__() method of the expression or conversion result. An empty string is passed when the format specifier is omitted. The formatted result is then included in the final value of the whole string.
The __format__() method then follows the format specifier mini-language syntax to determine the resulting string representation.
In your case the result is the same as calling str() on the variables, but this does not apply to all variables. Based on #Marv's answer, here is a little demonstration to show the difference:
class Test:
def __str__(self):
return "surprise"
def __format__(self, format_spec):
return "test"
t1 = Test()
print(t1)
print(str(t1))
print(f"{t1}")
print("{}".format(t1))
>>> surprise
>>> surprise
>>> test
>>> test

Str is already defined as a global variable

I noticed something really strange while working with functions. It looks like the variable name 'str' is already defined as a global variable. Take a look:
def Example(x):
str = input()
return str
print (Example(str))
#When typing 'Hello!' Output --> Hello!
The variable str is defined in the function Example. So why is there no NameError: name 'str' is not defined?
When I call the variable x or something else ( In this case 'bar'):
def Example(x):
bar = input()
return bar
print (Example(bar))
#Output: NameError: name 'bar'is not defined
Why does a variable with the name 'str' act as a global variable?
In python, str() is the string constructor. It is used to cast an object to a string.
You can use it locally, but it will override the access to the function. You will not be able to use str() anymore.
for reference:
https://docs.python.org/2/library/functions.html#str
class str(object='')
Return a string containing a nicely printable representation of an
object. For strings, this returns the string itself. The difference
with repr(object) is that str(object) does not always attempt to
return a string that is acceptable to eval(); its goal is to return a
printable string. If no argument is given, returns the empty string,
''.
For general knowledge purpose, you can get back you constructor if you delete your variable. For example:
test = 1
str(test)
>>>'1'
str = 2
str(test)
>>>TypeError: 'int' object is not callable
del str
str(test)
>>>'1'
The reason this fails:
def Example(x):
bar = input()
return bar
print (Example(bar))
#Output: NameError: name 'bar'is not defined
Is because you're attempting to pass the variable bar to the Example() method, but bar was never defined anywhere prior to the call.
I'm not really sure what it is you want to accomplish with this method anyhow, since you pass a variable but don't use it at all.
Comment Response:
str is not a built-in function (albeit listed on the page), but rather it is the constructor for the built-in type str. To show that you are simply reassigning the method associated with the keyword (not necessarily reserved, but it is a keyword nonetheless), consider the following:
>>> str
<class 'str'>
>>> abs
<built-in function abs>
>>> str = abs
>>> str
<built-in function abs>
Thus you've essentially overwritten the assignment to the str class constructor. I used abs in this example, but the same applies (with a twist) for input:
>>> str
<class 'str'>
>>> input
<built-in function input>
>>> str = input
>>> str
<built-in function input>
>>> str = input()
hello world
>>> str
'hello world'
Difference here is you assign a string (of type str) to the keyword str. So you can never use str(10) to get '10' because that would now be like calling hello world(10) which fails.
If you want to use a keyword as a variable name, by convention a single trailing underscore is used to avoid conflicts with Python keywords, like so:
single_trailing_underscore_
Cf. PEP 8 -- Style Guide for Python Codes

what is the significance of `__repr__` function over normal function [duplicate]

This question already has answers here:
Purpose of __repr__ method?
(6 answers)
Closed 5 years ago.
I am trying to learn python with my own and i stucked at __repr__ function. Though i have read lots of post on __repr__ along with the python document. so i have decided to ask this Question here. The code bellow explains my confusion.
class Point:
def __init__(self,x,y):
self.x, self.y = x,y
def __repr__(self):
return 'Point(x=%s, y=%s)'%(self.x, self.y)
def print_class(self):
return 'Point(x=%s, y=%s)'%(self.x, self.y)
p = Point(1,2)
print p
print p.print_class()
Point(x=1, y=2)
Point(x=1, y=2)
If a normal function can also perform similar task then what is the extra advantage of __repr__ over print_class() (in my case a normal function) function.
The __repr__ function is called by repr() internally. repr() is called when you are printing the object directly , and the class does not define a __str__() . From documentation -
object.__repr__(self)
Called by the repr() built-in function and by string conversions (reverse quotes) to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an “informal” string representation of instances of that class is required.
In your case for print_class() , you have to specifically call the method when printing the object. But in case of __repr__() , it gets internally called by print .
This is especially useful, when you are mixing different classes/types . For Example lets take a list which can have numbers and objects of your point class, now you want to print the elements of the list.
If you do not define the __repr__() or __str__() , you would have to first check the instance , whether its of type Point if so call print_class() , or if not directly print the number.
But when your class defines the __repr__() or __str__() , you can just directly call print on all the elements of the list, print statement would internally take care of printing the correct values.
Example , Lets assume a class which has print_class() method, but no __repr__() or __str__() , code -
>>> class CA:
... def __init__(self,x):
... self.x = x
... def print_class(self):
... return self.x
...
>>> l = [1,2,3,CA(4),CA(5)]
>>> for i in l:
... print(i)
...
1
2
3
<__main__.CA object at 0x00590F10>
<__main__.CA object at 0x005A5070>
SyntaxError: invalid syntax
>>> for i in l:
... if isinstance(i, CA):
... print(i.print_class())
... else:
... print(i)
...
1
2
3
4
5
As you can see, when we mix numbers and objects of type CA in the list, and then when we just did print(i) , it did not print what we wanted. For this to work correctly, we had to check the type of i and call the appropriate method (as done in second case).
Now lets assume a class that implements __repr__() instead of print_class() -
>>> class CA:
... def __init__(self,x):
... self.x = x
... def __repr__(self):
... return str(self.x)
...
>>>
>>> l = [1,2,3,CA(4),CA(5)]
>>> for i in l:
... print(i)
...
1
2
3
4
5
As you can see in second case, simply printing worked, since print internally calls __str__() first, and as that did not exist fell back to __repr__() .
And not just this, when we do str(list) , internally each list's element's __repr__() is called. Example -
First case (without __repr__() ) -
>>> str(l)
'[1, 2, 3, <__main__.CA object at 0x005AB3D0>, <__main__.CA object at 0x005AB410>]'
Second case (with __repr__() ) -
>>> str(l)
'[1, 2, 3, 4, 5]'
Also, in interactive interpreter, when you are directly using the object, it shows you the output of repr() function, Example -
>>> class CA:
... def __repr__(self):
... return "CA instance"
...
>>>
>>> c = CA()
>>> c
CA instance
The difference is that the __repr__ function is automatically called by Python in certain contexts, and is part of a predefined API with specific requirements. For instance, if you enter p by itself(not print p) in the interactive shell after creating your p object, its __repr__ will be called. It will also be used for print p if you don't define a __str__on p. (That is, you had to write print p.print_class(), but you didn't have to write print p.__repr__(); Python called __repr__ automatically for you.) The requirements for __repr__ are described in the documentation:
Called by the repr() built-in function and by string conversions (reverse quotes) to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned.
In short, if you write your own method called print_class you can make it do whatever you want and tell people how to use it, because it's your API. If you use __repr__ you're supposed to follow the conventions of Python's API. Either one may make sense depending on the context.
It helps you do more efficient coding work. even though you get same result using user define method like 'print_class()' as repr, but you don't need to type in '.print_class()' by repr method.

Python function arguments and documentation confusion

Here is a string in python:
a = "asdf as df adsf as df asdf asd f"
Lets say that I want to replace all " " with "||", so I do:
>>> a.replace(" ", "||")
'asdf||as||df||adsf||as||df||asdf||asd||f'
My confusion is info from the documentation as below:
string.replace(s, old, new[, maxreplace])
Return a copy of string s with all occurrences...
I can "omit" s, but based on the documentation I need s; however, I only provide old, and new. I noticed that it's like this with a lot of the python documentation; what am I missing?
You are mixing up str object methods with the string module functions.
The documentation you are referring to is the string module documentation. Indeed, there is a function in the string module called replace which takes 3 (or optionally, 4) arguments:
In [9]: string
Out[9]: <module 'string' from '/usr/lib/python2.7/string.pyc'>
In [11]: string.replace(a, ' ', '||')
Out[11]: 'asdf||as||df||adsf||as||df||asdf||asd||f'
a is a str object -- (str is a type, string is a module):
In [15]: type(a)
Out[15]: str
And str objects have a replace method. The documentation for the str methods is here.
The first parameter of a method is a reference to the object (usually called self) being modified and is implicitly passed when you use the object.method(...) notation. So this:
a = "asdf as df adsf as df asdf asd f"
print a.replace(" ", "||")
is equivalent to this:
a = "asdf as df adsf as df asdf asd f"
print str.replace(a, " ", "||")
str being the class of the a object. It's just syntactical sugar.
When you call a method of an object, the object is supplied automatically as the first parameter. Generally within the method this is referred to as self.
So you can call the function passing in the object:
string.replace(s, old, new)
or you can call the method of the object:
s.replace(old, new)
Both are functionally identical.

Categories

Resources