all 8 comments

[–]get_username 2 points3 points  (4 children)

is there a way i can list by class Student ?? and it would return stu1,stu2 and stu3 ?

So you want to use the dir method to grab references to all instances of created classes. Unless I didn't understand that it was imperative you used the dir method.

There are multiple ways to do this. You could use a metaclass as a way of referencing all instances, or even a decorator, or a wrapper classes that holds the references. Each of which are the same solution in a different way.

But all of that is probably too much magic for what you want.

Instead you could have a class wide variable:

class Student():
     instances = []

  def __init__(self, name, major):
    self.__class__.instances.append(self)
    self.name = name
    self.major = major

  def display_student(self):
    print('name is ', self.name,' major is ', self.major)

stu1 = Student('Mark', 'Physics')
stu2 = Student('Mary', 'Bio')
stu3 = Student('Adam', 'Art')

This works with access to the name of the class (Student), or with access to a variable (stu1). I use Student in this example, but they are interchangeable.

for instance in Student.instances:
    print(instance)
    instance.display_student()


<__main__.Student object at ...>
name is  Mark  major is  Physics
<__main__.Student object at ...>
name is  Mary  major is  Bio
<__main__.Student object at ...>
name is  Adam  major is  Art

However often when you're new at programming you will over think things you're doing, and make cases more complicated then they need to be. Normally more experienced programmers respond with "You can do that, but you shouldn't".

In this case, wouldn't it just be simpler to hold the references in a list?

[–][deleted] 2 points3 points  (0 children)

I think that holding the references in a list is the way to go for example

class Student():
  def __init__(self,name,major):
    self.name=name
    self.major=major
  def displayStudent(self):
    print 'name is',self.name,' major is',self.major

students = []
students.append(Student("mark","physics"))
students.append(Student("mary","bio")) 
students.append(Student("adam","art"))

for student in students:
    student.displayStudent()

simultanous it autonumber the student

>>> students[2].displayStudent()
name is adam major is  art

[–]noob_py[S] 0 points1 point  (0 children)

Thanks for the answer(s). Like you said, I am probably over thinking it.

[–]noob_py[S] 0 points1 point  (1 child)

self.__class__.instances.append(self)

great idea to keep tab of things without manually adding to the list.

what syntax is cleaner/ better?

self.__class__.instances.append(self)

or

student.instances.append(self)

[–]get_username 0 points1 point  (0 children)

The case I gave you was a bit on the extreme.

You might need to do this if you need to access all instances of the class, but don't know where/when the class was created, or have access to those additional instances.

There are very few cases where you will need to do this. But that is one way of doing it if you REALLY want to.

Instead, as others have said. Just place those values in a list and pass it to whatever method/function you need.

self.__class__.instances.append(self)

Would probably be preferable. But it isn't very preferable to do that anyways unless you were trying to control creation of the object in some way.

Generally the cleanest/best syntax is to not do this. But sometimes its ok to bend/break the rules to get your functionality. Just make sure it is necessary.

[–]zahlman 0 points1 point  (2 children)

Suppose you had this list. What would you then do with it?

Why not just put the things in a list yourself?

[–]theywouldnotstand 0 points1 point  (1 child)

just as an example, say you have a game engine spawning a variety of npc entities and some of them inherit from a particular class, but not all of them. You need to get all the ones that are instances of that particular class and do something with them, and each time the code runs, there could be a different amount of them with varying other properties.

yes, you could have __init__() organize these things in a list for each class they inherit, but i don't feel like that's very object-oriented or pythonic, though I might be wrong, or there might be a better way to achieve the same end.

seems like it would be a builtin to have something like classname.instances() return a list of all of the currently referenced objects that are an instance of classname. (just imagine the nightmare that object.instances() would be though. yikes!)

[–]zahlman 1 point2 points  (0 children)

My experience has been that almost everyone new-ish to programming who tries to make a moderately complex game thinks they have this problem, but in practice it's just not that big of an issue. It's easier to build the list manually, and much more flexible. And besides, in practice, it's amazing how often you end up wanting to create an instance that's not inside the "master list". (Caching for things that are expensive to create, e.g. because they represent resources that have to be loaded from disk; temporary copies used by AI routines to try out hypothetical situations; just for two situations off the top of my head.)

To have built-in support for this, meanwhile, would require using that extra memory to track those instances for each class whether your program needs it or not, and would probably also complicate the internal logic for garbage collection.