-1
class myClass:
    pass

myClass()

The use of myClass() creates an object of type myClass. How can I assign exactly that object to a variable after just calling it like that? Because if I add a = myClass() after the call to myClass(), another object will be created and a will point to that other object.

Eb946207
  • 748
  • 8
  • 26
  • 3
    `a = myClass() ; b = a` ? – DeepSpace Nov 27 '18 at 15:51
  • I just want to know if after using `myClass()` just like that I can assign exactly that object to a variable. – Populară Sălaj Nov 27 '18 at 15:53
  • 1
    I just answered that. Why don't you try and see what happens? – DeepSpace Nov 27 '18 at 15:54
  • 1
    If you just call ``myClass()`` and don't assign the resulting object to a variable, the reference to that object is lost and it will be garbage collected. It's like calling any other function and not storing the result. – Mike Scotty Nov 27 '18 at 15:57
  • 1
    I think you don't understand me. I want to know if is possible something like this: `myClass() ; a = lastObjectCreatedInTheMemory()'. Of course this function doesn't exist, but I hope I made myself understood. – Populară Sălaj Nov 27 '18 at 15:59
  • Yes, you understood. So isn't there an option to find that lost reference? – Populară Sălaj Nov 27 '18 at 16:00
  • 1
    If you're using the interactive interpreter, then `_` will be a reference to the vaue of the last expression evaluated, provided it has not been assigned another value. See: https://stackoverflow.com/questions/200020/get-last-result-in-interactive-python-shell – Patrick Haugh Nov 27 '18 at 16:20

3 Answers3

0

If you just call the class constructor and don't assign the result to a variable, no reference will be created. Not even the garbage collector knows of an instance of this class.

import gc

class myClass:
    pass

myClass() 
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

a = myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )
del a

gc.disable() # even disabling the garbage collector will not make a difference
myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

Output:

[] []
['a'] [<__main__.myClass object at 0x00000000046026D8>]
[] []

However, you could make the class keep track of references itself:

import gc

class myClass:
    ref = []
    def __init__(self):
        myClass.ref.append(self)

myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

a = myClass()
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )
del a

gc.collect() # force garbage collection
print( [o for o,t in globals().items() if isinstance(t, myClass)], [o for o in gc.get_objects() if isinstance(o, myClass)] )

Output:

[] [<__main__.myClass object at 0x00000000048226D8>]
['a'] [<__main__.myClass object at 0x00000000048226D8>, <__main__.myClass object at 0x0000000004890860>]
[] [<__main__.myClass object at 0x0000000004890860>, <__main__.myClass object at 0x00000000048226D8>]

Note: this way, the garbage collector will never delete instances of this class, even if the variable is deleted, as long as the class keeps a reference to the instance!

Mike Scotty
  • 10,530
  • 5
  • 38
  • 50
0
class MyClass:
    instances = []

    def __init__(self, name: str):
        self.name = name

        MyClass.instances.append(self)

    def printName(self):
        print("My name is " + self.name)

    def setName(self, name: str):
        self.name = name


a = MyClass("Joshua")

a.printName()   # Outputs 'My name is Joshua'

b = a

b.printName() # Outputs 'My name is Joshua'

b.setName("DeepSpace")

a.printName()   # Outputs 'My name is DeepSpace'
b.printName()   # Outputs 'My name is DeepSpace'

MyClass.instances[0].printName()    # Outputs 'My name is DeepSpace'

When b = a is used, it means that b will point to the same memory location as a, this happens as your class is mutable. You could manually store instances to refer to later by storing them as a list in the base class.

Joshua Nixon
  • 1,379
  • 2
  • 12
  • 25
-3

To do something like this is impossible because of CPython garbage collection:

myClass()
a = lastObjectCreated()

But has no use case and is 100% impossible (at least with CPython) because the object is destroyed right after it is created sense no variable is pointing to it (no variable has a reference to the class).


A weak reference is a reference that does not keep a object from being deleted. With this, we can witness an object be deleted, like so:

class myClass:
    pass

import weakref

def catch_deletion(object):
    print('Object was deleted')

weakref.ref(myClass(), catch_deletion)
#Output: Object was deleted

That proves that it is truly gone.

Eb946207
  • 748
  • 8
  • 26
  • 1
    I know that, but I was asking something else. If you use `myClass()` just like this, without assigning it to a variable, can you assign that exact object to a variable? Is the reference to that object forever lost? – Populară Sălaj Nov 27 '18 at 16:03
  • The reference is not lost, but deleted. It is impossible to get it back. – Eb946207 Nov 27 '18 at 16:05
  • And why is it deleted? – Populară Sălaj Nov 27 '18 at 16:06
  • Because there is no way to get it back, so it would take up memory forever. – Eb946207 Nov 27 '18 at 16:08
  • 1
    This has nothing to do with garbage collector. The object may still exist in memory, but its reference is unknown. – DeepSpace Nov 27 '18 at 16:10
  • But if the reference is unknown CPython will automatically garbage collect it. – Eb946207 Nov 27 '18 at 16:12
  • 1
    @EthanK eventually. It may or may not do that immediately after the object is created. Anyway, the GC implementation in Python is an implementation detail. – DeepSpace Nov 27 '18 at 16:14
  • No, CPython does it right away. Other interpreters will wait, but CPython (the main interpreter) does not. – Eb946207 Nov 27 '18 at 16:15
  • 1
    @DeepSpace if I write ``myClass() ; print(locals())`` I can only see the class definition, no instance of the class, even with ``gc.disable()``. – Mike Scotty Nov 27 '18 at 16:15
  • My point exactly, the `myClass` instance is deleted right away before `locals()` can see it. However, classes are never deleted unless the `del` statement is used. – Eb946207 Nov 27 '18 at 16:17
  • To downvoter(s): What is wrong with my answer? I don’t understand. – Eb946207 Dec 21 '18 at 15:48