+ 12
Why is this code unexplained and why does it not work after a minimum change?
3 Answers
+ 4
print(spam / hello /foo)
Your spam / hello works fine, but it returns a string. string doesn't support / with SpecialString so you get your exception. One possible change would be to provide a __str__ method to return the self.cont and return SpecialString() of your current __truediv__ return. That way you second / has two SpecialString objects and print has access to your string.
+ 3
"""
We can't say why this code is unexplained, as you didn't say from where you get it, and what you've done as "minimum change" ^^
Anyway, you need to good understand how the initial code is working.
However, I guess that your initial code was something like:
"""
class SpecialString:
def __init__(self, cont):
self.cont = cont
def __truediv__(self, other):
line = "=" * len(other.cont)
return "\n".join([self.cont, line, other.cont])
spam = SpecialString("spam")
foo = SpecialString("foo")
print(spam / foo)
"""output:
spam
===
foo
... by overiding magical function __truediv__, hidden called when using '/' operator:
doing: spam / foo will do: spam.__truediv__(spam,foo) and expect 2 'SpecialString' objects and return a String.
Your "minimal change" require at least a little more change to be working (else you doesn't get expected result, and even a runtime error).
The real "minimal change" should be to write print(SpecialString(spam/hello)/foo), because the hidden call to the magical function (use of '/' operator) is decomposed in temp = spam / hello, wich is a String object, and then result = temp / foo, wich cannot work as the magical method now called is the one of a String object wich doesn't have such magical method by default (strings are not intented to be divided).
Else, another fix would be to return a SpecialString object instead of a String, and define (overide) another magical method called when trying to use an object where a String is expected: __str__:
"""
class SpecialString:
def __init__(self, cont):
self.cont = cont
def __truediv__(self, other):
line = "=" * len(other.cont)
return SpecialString("\n".join([self.cont, line, other.cont]))
def __str__(self):
return self.cont
spam = SpecialString("spam")
hello = SpecialString("Hello world!")
foo = SpecialString("foo")
print(spam / hello /foo)
"""
The the output is more or less what you expect, but at least
+ 2
If you implement __truediv__ function it overrides default behaviour of division sign - "/". In the example it puts line of "=" between two strings. The problem why "spam/hello/foo" not working is that "spam/hello" return string and you cannot divide string by SpecialString, you only imlement for SpecialString/SpeacialString. So you can do something like this:
print(SpecialString(spam/hello)/foo)