I'm new to creating classes and try to solve a problem/exercise.
When I try to instantiate the toolbox, I try to add some tools to it. My approach is to create it as a list, and append new elements to it. It returns a "None" type attribute, and I don't know how to fix it.
class Toolbox:
def __init__(self):
self.toolbox = []
def add_tool(self, tool):
self.toolbox.append(tool)
def remove_tool(self, tool):
self.toolbox.remove(tool)
class Hammers:
color = ""
def __init__(self, color=''):
pass
def hammer_in(self, nail):
pass
def remove(self, nail):
pass
def paint(self, color):
pass
class Screwdrivers:
size = 10
def __init__(self, size=''):
pass
def tighten(self, screw):
pass
def loosen(self, screw):
pass
toolbox = Toolbox()
hammer = Hammers()
screwdriver = Screwdrivers()
toolbox = toolbox.add_tool(hammer)
toolbox = toolbox.add_tool(screwdriver)
Output :
Traceback (most recent call last):
File "C:Create Classes.py", line 133, in <module>
toolbox = toolbox.add_tool(screwdriver)
AttributeError: 'NoneType' object has no attribute 'add_tool'
I'm trying to : Instantiate a toolbox, a screwdriver, and a hammer.
Put the hammer and screwdriver in the toolbox.
Thank you,
3 Answers 3
As Arseniy says, your problem comes from reassigning toolbox to a new object:
First, a Toolbox object is assigned to the toolbox reference
toolbox = Toolbox()
Then, the result of toolbox.add_tool, which is the object None is assigned to the toolbox reference, thus toolbox now no longer points to a instantiated Toolbox object:
toolbox = toolbox.add_tool(hammer)
So, what you should do instead is simply remove the re-assignment:
toolbox.add_tool(hammer)
toolbox.add_tool(screwdriver)
And this should result in:
>>> print (toolbox.toolbox)
[<__main__.Hammers object at 0x...>, <__main__.Screwdrivers object at 0x...>]
6 Comments
None? And I don't understand the result... Why does it not just result in a simple list?object (including non instantiated classes). So when you make reference assignments to a variable, what you are doing is assigning it an object. Thus, this assignment must always be possible. But what happens when you are not assigning anything in a variable assignment? Well, in fact that variable will reference the object None. Since the method toolbox.add_tool(hammer) does not have any return value, assigning it to toolbox will make toolbox reference the object None.add.tool() method has a function to append an element...doesn't it? Why would it return nothing? Or should I write return self.toolbox.append()instead?return [object] ([object] is a placeholder for the object you want to return) your method will return None. It might be useful for you to also take a look at the Python Typing module. Adding type hints to your functions, will help you keep track of what Python is (or should be) doing.>>> toolbox = Toolbox() >>> toolbox <__main__.Toolbox object at 0x0000025831C3DF70> . I do not understand this line : why does it not show me an empty list at this point?add_tool return nothing (None), and you assign it to toolbox
toolbox = toolbox.add_tool(hammer) <--- problem here
toolbox = toolbox.add_tool(screwdriver)
So, toolbox become None and 'NoneType' object has no attribute 'add_tool'
Comments
add_tool and remove_tool return implicitly None. You should not assign this return value to toolbox.
You are using class-Attributes wrongly. color should be a instance attribute.
The default value of size is wrong, since size is not a empty string.
The class Hammers represent one Hammer. Why can you paint with a hammer?
class Toolbox:
def __init__(self):
self.toolbox = []
def add_tool(self, tool):
self.toolbox.append(tool)
def remove_tool(self, tool):
self.toolbox.remove(tool)
class Hammer:
def __init__(self, color=''):
self.color = color
def hammer_in(self, nail):
pass
def remove(self, nail):
pass
def paint(self, color):
pass
class Screwdriver:
def __init__(self, size=10):
self.size = size
def tighten(self, screw):
pass
def loosen(self, screw):
pass
toolbox = Toolbox()
hammer = Hammer()
screwdriver = Screwdriver()
toolbox.add_tool(hammer)
toolbox.add_tool(screwdriver)
toolbox.add_toolreturnsNone. You assign that totoolbox. Hence the error when you try to dotoolbox.add_toolagain. Just don't assign totoolbox