python learning advanced part (part9) -- reference counting of objects

Study notes are for reference only. Mistakes must be corrected

python learning advanced


# Support multi line output
from IPython.core.interactiveshell import InteractiveShell 
InteractiveShell.ast_node_interactivity = 'all' #The default is' last '

Special methods for class objects__ str__ ()


In the interactive interface of python, we type in the following code

"""
>>> class MyClass(object):
...     pass
... 
>>> mc = MyClass()
>>> mc
<__main__.MyClass object at 0x103f41550>
>>> print(mc)
<__main__.MyClass object at 0x103f41550>
>>> str(mc)
'<__main__.MyClass object at 0x103f41550>'
>>> repr(mc)
'<__main__.MyClass object at 0x103f41550>'
"""

"""
>>> class MyClass(object):
...     def __str__(self):
...         return "__str__Called"
... 
>>> mc = MyClass()
>>> mc
<__main__.MyClass object at 0x103e5c588>
>>> print(mc)
__str__Called
>>> str(mc)
'__str__Called'
>>> repr(mc)
'<__main__.MyClass object at 0x103e5c588>'
"""

"""
>>> class MyClass(object):
...     def __repr__(self):
...         return "__repr__Called"
... 
>>> mc = MyClass()
>>> mc
__repr__Called
>>> print(mc)
__repr__Called
>>> str(mc)
'__repr__Called'
>>> repr(mc)
'__repr__Called'
"""

"""
>>> class MyClass(object):
...     def __str__(self):
...         return "__str__Called"
...     def __repr__(self):
...         return "__repr__Called"
... 
>>> mc = MyClass()
>>> mc
__repr__Called
>>> print(mc)
__str__Called
>>> str(mc)
'__str__Called'
>>> repr(mc)
'__repr__Called'
"""
'\n>>> class MyClass(object):\n...     def __str__(self):\n...         return "__str__Called"\n...     def __repr__(self):\n...         return "__repr__Called"\n... \n>>> mc = MyClass()\n>>> mc\n__repr__Called\n>>> print(mc)\n__str__Called\n>>> str(mc)\n\'__str__Called\'\n>>> repr(mc)\n\'__repr__Called\'\n'

Special methods for class objects__ str__ () and__ repr__ () used to customize and return the string representation of the instance object

  • When printing an instance object directly on the interactive command line, if a special method is implemented in the class object corresponding to the instance object__ repr__ (), the method will be called automatically; Otherwise, the class object corresponding to the instance object and the address of the instance object in memory will be printed.
  • When calling the built-in function print to print an instance object, if a special method is implemented in the class object corresponding to the instance object__ str__ (), the method will be called automatically; Otherwise, if a special method is implemented in the class object corresponding to the instance object__ repr__ (), the method will be called automatically; Otherwise, the class object corresponding to the instance object and the address of the instance object in memory will be printed.
  • When calling the built-in function STR to create a string and the argument is an instance object, if a special method is implemented in the class object corresponding to the instance object__ str__ (), the method will be called automatically; Otherwise, if a special method is implemented in the class object corresponding to the instance object__ repr__ (), the method will be called automatically; Otherwise, the class object corresponding to the instance object and the address of the instance object in memory will be printed.
  • If the object is a built-in instance of the function, and the object implements a special method in the built-in instance of the function__ repr__ (), this method will be called automatically inside the built-in function repl; Otherwise, the class object corresponding to the instance object and the address of the instance object in memory will be printed.

In general, special methods of class objects__ str__ () and__ repr__ The implementation code of () is the same, so when one of them is implemented, its method name can be assigned to the method name of the other.

class MyClass(object):
    def __str__(self):
        return 'XXX'
    __repr__ = __str__

The built-in functions str() and repr() both return the string representation of the object. The difference is:

  • The return value of str() is shown to users, which is more user-friendly;
  • The return value of repr() is for program developers and serves debugging.
str('A \nB')
repr('A \nB')
'A \nB'




"'A \\nB'"

Special methods for class objects__ new__ ()


When using "class name ([argument])" to create an instance object, the main processing process of the Python interpreter includes two steps:

  • Call special methods__ new__ () create instance object: first, we will find out whether this kind of object implements special methods__ new__ (), if there is no implementation, search in its parent class until the class object object; Special method__ new__ () returns the created instance object
  • Call special methods__ init__ () initialize the created instance object__ new__ The instance object returned by () will be automatically passed to as an argument__ init__ The first formal parameter of () is self
class Parent(object):
    def __new__(cls, *args, **kwargs):
        print("Parent class__new__()Called, its formal parameters cls Corresponding argument id:%s" % id(cls))
        obj = super().__new__(cls) 
        print("Of the instance object created id:%s" % id(obj))
        return obj

class Child(Parent):
    def __init__(self, name):
        print("Subclass__init__()Called, its formal parameters self Corresponding argument id: %s" % id(self))
        self.name = name

print("Parent class id: %s" % id(Parent))
print("Subclass id: %s" % id(Child))

child = Child("Mike")
print("Of the instance object created id: %s" % id(child))
Parent class id: 1968492033576
 Subclass id: 1968492039240
 Parent class__new__()Called, its formal parameters cls Corresponding argument id:1968492039240
 Of the instance object created id:1968521654224
 Subclass__init__()Called, its formal parameters self Corresponding argument id: 1968521654224
 Of the instance object created id: 1968521654224


Reference count of object


What is reference counting


Usually, developers do not need to care about memory allocation and release. When an object is created, the system will automatically allocate a piece of memory to store the information of the object. When the object is no longer used, the system will conduct garbage collection to automatically release the memory occupied by it.

To ensure that objects in use are not destroyed, Python uses reference counting to track and count the number of times each object in memory is referenced. An object can be destroyed only when its reference count is 0.


The case where the reference count of the object is increased by 1


  1. Object assigned to variable

  2. The variable of the reference object is assigned to another variable

  3. Objects act as elements in containers (for example, lists, tuples, collections, etc.)

  4. Object as an argument to a function call

class MyClass(object):
    pass

def do_sth(param):
    pass

# The reference count increases by 1 to become 1
a = MyClass()
# The reference count increases by 1 to 2
b = a
# The reference count increases by 1 to 3
L = [1, 2, a]
# During the execution of the function, the reference count increases by 1 to 4
do_sth(a)
# When the function is executed, the reference to the argument is automatically destroyed. Therefore, the reference count is reduced by 1 to 3
import sys
# During the execution of the function, the reference count increases by 1 to 4
print(sys.getrefcount(a))
# When the function is executed, the reference to the argument is automatically destroyed. Therefore, the reference count is reduced by 1 to 3
4


Object's reference count minus 1


  1. Object leaves its scope. For example, the function where the object is located has been executed
  2. The reference to the object is explicitly destroyed
  3. Variables that reference objects are assigned to new objects
  4. Delete the object from the container, or the container in which the object is located is destroyed
class MyClass(object):
    pass

# The reference count increases by 1 to become 1
x = MyClass()
# The reference count increases by 1 to 2
y = x
# The reference count decreases by 1 and becomes 1
del x
# The reference count increases by 1 to 2
z = y
# The reference count decreases by 1 and becomes 1
y = 18
# The reference count increases by 1 to 2
l = [1, 2, z]
# The reference count decreases by 1 and becomes 1
del l
# During the execution of the function, the reference count increases by 1 to 2
print(sys.getrefcount(z))
# When the function is executed, the reference to the argument is automatically destroyed. Therefore, the reference count is reduced by 1 to 1
2

Keywords: Python

Added by devangel on Tue, 08 Mar 2022 21:43:47 +0200