0

I want to get all the instances created for a class. Is there any way to get the instances without importing any module ?

I tried this way to append self in a class attribute.

class A(object):
    instances = []

    def __init__(self, foo):
        self.foo = foo
        A.instances.append(self)
        
foo = A("hi")
bar = A("Hey")
star = A("Hero")

for instance in A.instances:
    print("Ins is ",instance)

Output

<__main__.A object at 0x148b8b6e0780>,
<__main__.A object at 0x148b8b6e0780>,
<__main__.A object at 0x148b8b6e0780>

I expect it to print foo,bar,star. Is there any way to get it in class without any module?

shaila
  • 177
  • 2
  • 10
  • Suppose you did `baz = foo`. What would you expect it to print then? – SethMMorton Jan 30 '22 at 06:24
  • 1
    zyou *are* printing the instances of that class. "I expect it to print foo,bar,star. " **why** do you expect that? If I do `x = 1` then `print(x)`, does it print `x` or `1` to the screen? – juanpa.arrivillaga Jan 30 '22 at 06:26
  • In general, you should be providing the data an object should know about to it explicitly, usually as an argument to the constructor (a fancy name for this is *dependency injection*). If you want an object to know about `"foo"`, then *pass in that string*. Then you can modify the default printing behavior for that type by implementing `__repr__` and/or `__str__`. – juanpa.arrivillaga Jan 30 '22 at 06:30
  • Also note that you may create instances without ever bind them to a name, e.g. in a list comprehension. Your object shouldn't care about the name it is bind to. The opposite suggest there is probably design problem. – buran Jan 30 '22 at 06:30
  • If you want to rely on variable names, you'd have to go through various hijinks like those seen in [this library](https://github.com/pwwang/python-varname) (note, it's a pretty good read if you want to understand python internals, and how you'd do it). But really, truly, you should *simply [keep data out of variable names](https://nedbatchelder.com/blog/201112/keep_data_out_of_your_variable_names.html)*. The long and the short of it is, while it's an interesting exercise to see how this could be done, you generally should not design your code around this – juanpa.arrivillaga Jan 30 '22 at 06:34

3 Answers3

1

Use this snippet:

for instance in A.instances:
    print("Ins is ", (instance.__dict__).get("foo"))

Output:

Ins is  hi
Ins is  Hey
Ins is  Hero

Or:

for instance in A.instances:
    print("Ins is ", instance.__dict__)

Output:

Ins is  {'foo': 'hi'}
Ins is  {'foo': 'Hey'}
Ins is  {'foo': 'Hero'}

To print an object, you can turn it into a dictionary. In this case, these values will be printable.

This method is usually used to convert objects to a dictionary and then to the JSON type, which is widely used to exchange information.

1

you could do the following, if I got you right :

Proposal

tmp = globals().copy()
print(tmp)

for k,v in tmp.items():
    if isinstance(v, A):
        print(k)

You must copy the global variable dictionary, because otherwise i will be changed with the first instantiation in the for-loop:

Result:

foo
bar
star
baskettaz
  • 741
  • 3
  • 12
  • This won't work everywhere. See info [here](https://docs.python.org/3/library/functions.html#globals). – deponovo Jan 30 '22 at 10:59
0

There is no way to define such behavior in a class, because the class assigns a value to a variable after instantiation. There is no way to get the name of the variable during class instantiation, because the variable does not exist yet

Clumsy
  • 1
  • 1