python使用了引用计数这个简单技术来跟踪和回收垃圾
在python内部记录着所有使用中的对象各有多少引用
一个内部跟踪变量,称为一个引用计数器
当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收,但是回收不是’立即’的,又解释器在适当的时机,将垃圾对象占用的内存空间回收
a = 40 # 创建对象<40> b = a # 创建引用,<40>的计数 c = [b] #增加引用,<40>的计数 del a #减少引用<40>的计数 b = 100 #减少引用<40>的计数 c[0] = -1 #减少引用<40>的计数垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况.循环引用指的是,两个对象相互引用,但是没有其他变量引用它们.在这种情况下,仅使用引用计数是不够的.python的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器.作为引用计数的补充,垃圾收集器也会留心被分配的总量很大(及未通过引用计数器销毁的那些)的对象,在这种情况下,解释器会暂停下来,试图清理所有未引用的循环
# -*- coding: utf-8 -*- class Point: def __init__(self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print(class_name, "ruin.....") pt1 = Point() pt2 = pt1 pt3 = pt1 print('pt11111111', id(pt1), id(pt2), id(pt3)) del pt3 '''output pt11111111 2032686524616 2032686524616 2032686524616 Point ruin..... '''面向对象的编程带来的主要好处是代码的重用,实现这种重用的方法之一是通过继承机制
通过继承创建的新类称为子类或者派生类,被继承的类称为基类,父类或者超类
类的继承的一些特点:
如果在子类这个需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法,
在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量,区别在于类中调用普通函数时并不需要带上self参数
python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找,(现在本类中查找调用的方法,找不到才到基类中去找)
基础重载方法
# 以下是一些通用的功能,可以在自己的类重写 __init__(self[,args]) 构造函数,调用方法:obj = className(args) __del__(self) 析构方法,删除一个对象,调用方法:del obj __repr__(self) 转化为供解释器读取的形式,调用方法:repr(obj) __str__(self) 用于转化为适于人阅读的形式,调用方法:str(obj) __cmp__(self, x) 对象比较,调用方法:cmp(obj,x)运算符重载
__add__(self)类的私有属性:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问,在类内部的方法中使用时self.__private_attrs
类的私有方法:private_method,两个下划线开头,声明该方法为私有方法,不能在类的外部调用,在类的内部调用
self.__private_methods # print('22222222', j.__secretCount) #直接访问不了 # 用obj._className.__secretvariablename来访问私有属性 print('22222222', j._JustCounter__secretCount)ps:单下划线 双下划綫 头尾双下划綫说明
__foo__定义的是特殊方法,一般是系统定义名字,类似__init__()之类的 _foo 以单下划线开头的表示的是protected类型的变量,即保护类型只允许本身和子类进行访问,不能用于from module import * __foo 双下划线的表示的是私有类型的变量,只能是允许这个类本身进行访问了护类型只允许本身和子类进行访问,不能用于from module import *
__foo 双下划线的表示的是私有类型的变量,只能是允许这个类本身进行访问了
[外链图片转存中...(img-V5n48TiK-1599124345172)]