-3

I what should happen if I have this

class ObjectA:
    def __init__(self):
        self.some_member = SomeComplexObject()

    def get_some_result(self):
        return self.some_member

and then do this

a = ObjectA().get_some_result()

I tried a couple of times and seems to work fine, but my expectation was that a should hold trash since ObjectA is being created locally and not assigned to any variable.

I would expect the proper way to do it should be

a = copy.deepcopy(ObjectA().get_some_result())

Am I understanding wrong how python works?

Rodrigo
  • 231
  • 3
  • 16
  • Every time you do `objectA()` you create a new object that is not used. Why would you need to copy anything? – Tomerikoo Dec 17 '20 at 16:26
  • 3
    1) `class(object)` is a syntax error; 2) Upon instantiation of this class, you'll get `AttributeError: 'class_name_here' object has no attribute 'some_member'` because `self.some_member` in `__init__` will try to access the `some_member` attribute, but it doesn't exist. So no, this code doesn't "work fine" at all – ForceBru Dec 17 '20 at 16:26
  • 1
    Does this answer your question? [What is the difference between shallow copy, deepcopy and normal assignment operation?](https://stackoverflow.com/questions/17246693/what-is-the-difference-between-shallow-copy-deepcopy-and-normal-assignment-oper) – Asker Dec 17 '20 at 16:27
  • I think you missed something in your post, your code would throw syntax error. – Hammond95 Dec 17 '20 at 16:27
  • 1
    *my expectation was that a should hold trash since ObjectA is being created locally and not assigned to any variable* - but you are not using `objectA()`, you are only using its `some_member` attribute so there is no reason to get trash. You get that value and then the `objectA` itself is probably cleaned, but you still have a reference to its `some_member` – Tomerikoo Dec 17 '20 at 16:30
  • 1
    This is a reasonable question that is unfortunately poorly posed. It seems that you are really asking _"do I need to worry about the lifetime of objects?"_ The answer to that question is a loud, resounding "No!". If you have a reference to an object, that object is alive and valid. – Brian61354270 Dec 17 '20 at 16:41
  • Python uses automatic memory management. Objects stick around as long as they're needed, it doesn't matter whether you assign them to variables or not. – Barmar Dec 17 '20 at 16:44

1 Answers1

3

I think you missed something in your post, your code would throw syntax error.

Let's say you wrote what I assume is the right code:

class ObjectA(object):
    def __init__(self):
        self.some_member = "some_value"

    def get_some_result(self):
        return self.some_member

if __name__ == "__main__":
    # This would create an instance of ObjectA in memory,
    # then call get_some_result() and assign the result (reference)
    # to the variable a
    a = ObjectA().get_some_result()

    # This will create a new ObjectA in memory
    # then call get_some_result() and assign the result (reference)
    # as a parameter of deepcopy.
    # in this case the constructor of the object assigns a fixed value,
    # so python just stores the string 'some value' as a const value in the memory
    # and the string object is actually always the same
    a = copy.deepcopy(ObjectA().get_some_result())

    # Example:
    obj1 = ObjectA()
    obj2 = ObjectA()

    print(id(obj1)) # 4561426512
    print(id(obj2)) # 4562720224
    print(id(ObjectA()) # 4594936224
    print(id(ObjectA()) # 4594869824

    print(id(obj1.get_some_result())) # 4562116656
    print(id(obj2.get_some_result())) # 4562116656
    

Also reading from the docs it seems that in certain cases deepcopy would just return the reference and not create a new object.

from: https://docs.python.org/3/library/copy.html Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.

Also, strings behave like this (are immutable):

>>> a = "strawberry"
>>> b = "strawberry"
>>> id(a) == id(b)
True
>>> a = "strawberry"
>>> b = "Strawberry"
>>> id(a) == id(b)
False

A different story if the value assigned to the member is a mutable object.

Hammond95
  • 556
  • 7
  • 20