I know, that the purpose of str()
method is to return the string representation of an object, so I wanted to test what happens if I force it to make something else.
I've created a class and an object:
class MyClass(object):
def __str__(self, a=2, b=3):
return a + b
mc = MyClass()
When I call:
print(str(mc))
The interpreter complains:
TypeError: __str__ returned non-string (type int)
And this is fully understandable because the str() method is trying to return int .
But if I try:
print(mc.__str__())
I get the output: 5.
So why the interpreter allows me to return int when I call __str__
directly, but not when I'm using str(mc) which - as I understand - is also evaluated to mc.__str__()
.
str()
calls PyObject_Str()
. Here is the source code where PyObject_Str()
is defined. If you search this document for " __str__
", you will see where the function calls __str__
and makes sure the return type is actually a string.
The built-in str
function (and also repr
) do more than just calling .__str__
(or .__repr__
) – they also have defaults to cope with objects that don't have a __str__
or __repr__
method, and some cleverness to deal with objects whose string representation is recursive.
You can see the source (in C) for str
and repr
here and here . As you can see, they enforce the return type of __str__
and __repr__
:
if (!PyUnicode_Check(res)) {
PyErr_Format(PyExc_TypeError,
"__str__ returned non-string (type %.200s)",
Py_TYPE(res)->tp_name);
Py_DECREF(res);
return NULL;
}
If you just call the __str__
method on an object, Python itself doesn't enforce that any method called __str__
can only return a string – it's the str
function that enforces that restriction.
str
isn't just
def str(obj):
return obj.__str__()
I think very few of the standard functions or operators map directly to a magic method like that, although I'm not sure of the exact counts.
str
tries __str__
, but it also tries __repr__
if there's no __str__
, and it enforces the str
return type. (It also calls the return value's __init__
for technical reasons, which can get weird for str
subclasses .) +
tries __add__
, but it also tries __radd__
. iter
tries __iter__
, but it also tries __getitem__
. The list goes on and on.
__str__
provides a contract: you return a string, and the program won't break when it tries to use a non-string value when the program expects a string. Determining whether __str__
actually obeys that contract is uncomputable in general, so it is up to the programmer to enforce the contract.
As @Juanpa.arrivillaga points out, str
is simply stricter about the __str__
method returning what it should be. Your explicit call to __str__
doesn't actually invoke the protocol; it returns an int
value, but that value itself has a __str__
method which print
calls when it wants a str
value.
__str __与Java中的ToString方法类似,您将获得类对象的友好打印。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.