-2

I have a class that contains an __init__ method, a method which changes the init value and a __repr__ function that wants to print out the adjusted value

The draft of the code is as follows

class Workflow: 
    def __init__(self, a): 
        self.a = a 
    
    def build(self):
        self.a += 1
        
    def __repr__(self): 
        value = self.build()
        return value

# Driver Code         
t = Workflow(1234) 
print(t)

And I got an error as follows

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[71], line 3
      1 # Driver Code         
      2 t = Workflow(1234) 
----> 3 print(t)

TypeError: __str__ returned non-string (type NoneType)

What's the mistake that I have made? In this case, if I want to print out the value that has beed changed by a method, how should I do that?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Pak Hang Leung
  • 389
  • 5
  • 15
  • 1
    As it mentions, you are returning None from __repr__, which needs to return a string. So you should back track to see why the value would None. Think about what `build()` is doing and you might see the problem. – saquintes Jan 13 '23 at 09:50
  • Hint: try to **read** the error message. Notice how it says that `__str__` returned something that was not a string? Did you try to define `__str__`, or `__repr__`? Which one do you suppose needs to be defined, in order for this to work? Why? – Karl Knechtel Jan 13 '23 at 09:53
  • 1
    Second hint: it seems like your intent, was to call `build`, and then make `__repr__` return the value from the `build` call... right? So... what does `build` return, when it is called? (Do you see a `return` anywhere in that method?) Or, another way: "if I want to print out the value that has beed changed by a method" - well, **what did you change**? `self.a`, right? So.... – Karl Knechtel Jan 13 '23 at 09:58

3 Answers3

1

build does not return anything so the value variable will be None

For example you do it like this:

    def build(self):
        self.a += 1
        
    def __repr__(self): 
        self.build()
        return str(self.a)

BUT

it is better - and convention - that you use the __str__ method here for readability:

    def __str__(self): 
        self.build()
        return str(self.a)

    def __repr__(self): 
        return "Workflow(" + str(self.a) + ")"

__repr__ should be associated with how you construct an object in the init and you can use it for copy paste to create new objects.

Daraan
  • 1,797
  • 13
  • 24
1
  1. Function build doesn't return anything thats why you got None in value

  2. It is a bad idea to modify value of attribute a with build function in __repr__ if you want to show current state.

    def __repr__(self):
        return f"{self.__class__.__name__}({self.a})"
    

    output

    Workflow(1234)
    
Ronin
  • 1,811
  • 1
  • 16
  • 17
0

Hwow abouit this:

class Workflow:
def __init__(self, a):
    self.a = a

def build(self):
    self.a += 1
    return self.a

def __repr__(self):
    value = self.build()
    return str(value)

Driver Code

t = Workflow(1234) print(t)

CNGF
  • 56
  • 4