aminsadeghi
aminsadeghi

Reputation: 13

Initializing several instances of a class inside a list with the iterator index

I want to create a list containing instances of a class, and initialized with numbers 0 to 9. Here's what I do:

class Element(object):
    def __init__(self, elem_index=None):
        if elem_index:
            self._elem_index = elem_index
    def get_index(self):
        return self._elem_index

elements = [Element(elem_index=i) for i in range(10)]

print(elements[0].get_index())

Here's the error I get:

AttributeError: 'Element' object has no attribute '_elem_index'

Upvotes: 0

Views: 65

Answers (2)

Chris
Chris

Reputation: 22993

Look closer at the code in your __init__ function:

if elem_index:
    self._elem_index = elem_index

What your saying translated to english is, If the boolean value of elem_index is true, give this class instance an attribute called _elem_index. Otherwise, skip this code and never define _elem_index.

With that still in mind, understand that the default first value range() generates is zero

>>> list(range(1))
[0]
>>>

And in python zero evaluates to False

>>> bool(0)
False
>>> 

This means when you try to call get_index() on the first value in elements, Python raises an error because your condition in __init__ failed.

To fix this you need to more specific and tell Python exactly when you want to skip the definition of _elem_index. Instead of doing if elem_index, use this is not operator test explicitly test if elem_index is not equal toNone; if elem_index is not None. eg:

>>> var = 0
>>> if var:
    print("This will not run because zero evalutes to false")


>>> if var is not None:
    print("This will run because were testing if var is equal to None")


This will run because were testing if var is equal to None
>>> 

Upvotes: 0

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160657

You are conditionally setting _elem_index as an attribute of your instance based on the truthness of the argument elem_index you pass during initialization.

For i == 0, the first value produced by range(10), the attribute will not be set since 0 is False when evaluated in your conditional. As a result the look-up will fail when it is attempted.

Be explicit in your condition:

if elem_index is not None:
    self._elem_index = elem_index

Upvotes: 4

Related Questions