0

I am trying to create a list of N instances of class Name and then call back a parameter of that instance. My code is below.

I get an error: Exception has occurred: AttributeError 'str' object has no attribute 'get_name'

and am not sure how to fix it. Any ideas? Thank you

class Name:
    global listName 
    listName = []

    def __init__(self,name):
        self.name = name
        listName.append (self.name)

    @property
    def get_name (self):
        print  (self.name)


for i in range (10):
    Name(f"Name{i}")

for i in range (10):
    listName[i].get_name
EML
  • 395
  • 1
  • 6
  • 15
  • 1
    `Name.listName` ... if you want to use your class variable. And you store strings in it - not the instances of Name (aka `self` - wich you could store instead). Strings do not have any `get_name` function - and lastly: ` listName[i].get_name` dos not call a function. Please look into basics: https://docs.python.org/3/tutorial/ for classes and functions and how to call them – Patrick Artner Apr 26 '19 at 16:57
  • 1
    Replace `listName.append (self.name)` with `listName.append(self)` – jdehesa Apr 26 '19 at 16:57
  • Btw you may be interested in [Printing all instances of a class](https://stackoverflow.com/q/328851/1782792). – jdehesa Apr 26 '19 at 16:59
  • @PatrickArtner but `listName` is a global variable. So it's not part of the class, right? – theblackips Apr 26 '19 at 16:59
  • It is a class variable if you indent it under the class - making it `global` as well is ... not needed at all: read [instance-variables-vs-class-variables-in-python](https://stackoverflow.com/questions/2714573/instance-variables-vs-class-variables-in-python) – Patrick Artner Apr 26 '19 at 17:01
  • If you want `listName` to be global, then don't define it inside the `class` statement. `listName` inside a *method* will already refer to the global scope, since it's not already defined locally. – chepner Apr 26 '19 at 17:05
  • If you want `listName` to be a class attribute, then drop the `global` statement. – chepner Apr 26 '19 at 17:06

2 Answers2

3

You did not append the instance of Name to your list, you only appended the name as a string.

See this line in the constructor of Name:

listName.append (self.name)

That line has to be

listName.append(self)

for your code to work.

Also:

As Patrick Artner pointed out in the comments, listName[i].get_name is not a function call. You have to add parentheses to call a function, like this:

listName[i].get_name()

Another thing:

As I just learned myself, you made listName a class variable by declaring it in the body of Name. You have to access it as Name.listName. The global listName statement is not needed.

Tom Lubenow
  • 1,109
  • 7
  • 15
theblackips
  • 779
  • 4
  • 16
0

listName.append(self) is correct. get_name is worked instead of get_name().

class Name:
    global listName 
    listName = []

    def __init__(self,name):
        self.name = name
        listName.append (self)

    @property
    def get_name (self):
        print (self.name)

for i in range (10):
    Name(f"Name{i}")

for i in range (10):
    listName[i].get_name


Name0
Name1
Name2
Name3
Name4
Name5
Name6
Name7
Name8
Name9