0

I have some questions when it comes to classes and OOP in general.

# Lets say we have this variable.
my_integer = 15

Now, if I got it right, when assignment occurs, Python creates an object of the int class with the value of 15 which is then referenced by the name-tag defined as my_integer.

# Now we "change" it.
my_integer = 50

This SHOULD now create a new int object with the value of 50 but the reference tag switches to the newly created object, thus leaving the one with 15 without a tag and up for garbage disposal.

class Point:
        """Point class represents and manipulates x,y coords."""

        def __init__(self):
        self.x = 0
        self.y = 0

one = Point()
two = Point()

one.x = 50
two.y = 150

When I create those Point() objects with the attributes x and y, does Python basically create an integer object inside the Point() object?

Doesn't it get kinda complicated like that when there are multiple objects inside an object?

Is my understanding in the first two points correct?

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
N. Cross
  • 227
  • 1
  • 2
  • 7
  • Internally, primitive values like integers are usually handled specially by language implementations, simply because there's so many of them that allocating and deallocating the integer each time an operation is performed on them would take too much time. – Colonel Thirty Two Oct 11 '15 at 15:20
  • There's a nice talk about it: https://www.youtube.com/watch?v=_AEJHKGk9ns – sobolevn Oct 11 '15 at 15:22
  • @sobolevn Already know about that talk XD. Cleared up a lot of misconceptions but I asked the first two just for confirmation and it doesn't really talk about how inside types are handled. – N. Cross Oct 11 '15 at 15:25
  • Correct me if I'm wrong, but the new object is not created "inside" the Point object. It is allocated from a heap (if not reused from another) and its address is tagged in the name which lives in the Point object's namespace. – Pynchia Oct 11 '15 at 15:47

1 Answers1

1

Basically yes. Let's look at it more closely:

class Point:
        """Point class represents and manipulates x,y coords."""

        def __init__(self):
        self.x = 0 # Create an int-object and set self.x to that
        self.y = 0 # Same as above

one = Point()
# Create a general object tag (Point extends object) by calling
# Point.__init__(Point.__new__()) *see more below
two = Point()
# The same
one.x = 50 # Create an int-object and assign it
two.y = 150

Instance creation

Instance creation of classes is a little bit more special than how it looks above. Every class actually has a meta-class which is the type of the class. This ultimatly resolves - possibly after several layers of nesting - to the builtin class type.

When instantiation happens (as in your code Point()) the following happens:

a = Class(*args, **wargs) # Class is some class you defined
# calls type(Class).__call__(Class, *args, **wargs)
# normally type(Class) is type, and type.__call__() does the following
# def type.__call__(clz, *args, **wargs): # Not a perfect implementation
#      protoobj = clz.__new__(*args, **wargs)
#      protoobj.__init__(*args, **wargs)
#      return protoobj

Let's try this out:

>>> class Point:
>>>     pass
>>> type(Point)
<class 'type'>
>>> type.__call__(int, 2)
2
>>> type.__call__(Point)
<__main__.Point object at 0x0000000003105C18>

It seems to work! Yes!

Community
  • 1
  • 1
WorldSEnder
  • 4,875
  • 2
  • 28
  • 64