Search code examples
pythonlistobjectlist-comprehensioninstantiation

Objects does not include methods in the list comprehension


This question is related to my previous question and Bill's response there.

I have a class named StrucData in subfile.py

class StrucData:  
    def __init__(self, name):
        self.name=name
    
    def loadData(self, size=1, cost=1):
        self.size=size  
        self.cost=cost
        return self

In the main file I:

  1. call the subfile,
  2. create a list of data names
  3. loop through the list to instantiate the objects; and
  4. load data using 'loadData' method for each object (I'm using the same 'size' and 'cost' to make this example easy.)

in one go using a list comprehension:

# in the main file

from subfile import StrucData 

listIndex=['data1','data2','data3']
listObjects = [StrucData(idx).loadData(size=3, cost=4) for idx in listIndex]

The output is

listObjects=[object1, object2, object3]

in which each object contains its attributes defined in the subfile.py (name, size, cost). enter image description here

What I wonder is when I define one object using the same code as

x=StrucData(listIndex[0]).loadData(size=3, cost=4) 

it contains the method 'loadData' too. enter image description here

Could anyone please explain to me why it happens?

I use anaconda3 distribution of Spyder, the version information is enter image description here


Solution

  • The inspector used when debugging your application inside Spyder treats objects inside lists differently from singular objects of the same type. It simply displays different things and - if in a list - omits function.

    You can easily check if both objects have this method by printing it:

    listIndex = ['data1','data2','data3']
    listObjects = [StrucData(idx).loadData(size=3, cost=4) for idx in listIndex]
    
    other = StrucData("other").loadData(size=3, cost=4) 
    
    print(listObjects[0].loadData)
    print(other.loadData)
    

    You can assign one of the list elements to a normal variable and check its inspector output to verify:

    lO = listObjects[1]
    

    Set a breakpoint and inspect it - now the method shows up.

    As to the why: ask the coders responsible for Spyder's debugging inspector code. As a hazarded guess: to save screen estate when displaying objects that are bundled inside a list.