I am trying to print a list of python objects that contain a list as a property and i am having some unexpected results:
here is my code:
class video(object):
name = ''
url = ''
class topic(object):
topicName = ''
listOfVideo = []
def addVideo(self,videoToAdd):
self.listOfVideo.append(videoToAdd)
def getTopic(self):
return self.topicName
def getListOfVideo(self):
return self.listOfVideo
topic1 = topic()
topic1.topicName = 'topic1'
video1 = video()
video1.name = 'VideoName1'
video1.url = 'VideoURL1'
video2 = video()
video2.name = 'VideoName2'
video2.url = 'VideoURL2'
topic1.addVideo(video1)
topic1.addVideo(video2)
topic2 = topic()
topic2.topicName = 'topic2'
video3 = video()
video3.name = 'VideoName3'
video3.url = 'VideoURL3'
video4 = video()
video4.name = 'VideoName4'
video4.url = 'VideoURL4'
topic2.addVideo(video3)
topic2.addVideo(video4)
topicsList = []
topicsList.append(topic1)
topicsList.append(topic2)
for topicCurrent in topicsList:
print(topicCurrent.topicName)
for video in topicCurrent.getListOfVideo():
print(video.name)
print(video.url)
What I expect to get is this:
topic1
VideoName1
VideoURL1
VideoName2
VideoURL2
topic2
VideoName3
VideoURL3
VideoName4
VideoURL4
but what I actually get is this:
topic1
VideoName1
VideoURL1
VideoName2
VideoURL2
VideoName3
VideoURL3
VideoName4
VideoURL4
topic2
VideoName1
VideoURL1
VideoName2
VideoURL2
VideoName3
VideoURL3
VideoName4
VideoURL4
Why? I want to iterate over my list of topics and print out each video in each topic, but for each topic it prints out all videos???
What is going on here?
You have created class variables
instead of instance variables
, which are different for each instance object. Define your class as follows:
class topic(object):
def __init__(self):
self.topicName = ''
self.listOfVideo = []
def addVideo(self,videoToAdd):
self.listOfVideo.append(videoToAdd)
def getTopic(self):
return self.topicName
def getListOfVideo(self):
return self.listOfVideo
From Python Tutorial:
Instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class.
EDIT:
One more important thing to consider is that why only listOfVideo
was common for all instances but not topicName
. It is because list
's are mutable objects while string
's are immutable.
So any changes made to listOfVideo
are common for all instances, i.e., they still refer to listOfVideo
defined in the topic
namespace.
However when you do topic1.topicName = 'topic1'
, you create a new variable topicName
within topic1
namespace, which overrides the topicName
found in topic
(class) namespace. You can confirm it by printing the value topic.topicName
, which you will find to be an empty string, i.e., ''
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With