第四阶段 -- python核心特性:【内存管理】

1. 元类

  1. 类:我们可以基于“类”创建出很多的“对象”。

  2. 动态创建类:有了一个“元类”就可以创建很多个“类”。

  3. 元类用途:可以动态创建类。

  4. type():

    1. 可以查看对象的数据类型
    2. 可以使用type,动态创建类
    • 语法:类 = type(类名, (父类...), {属性, 方法})
# 创建一个默认父类,不包括任何属性方法的类
Person = type('Person', (), {})
# 是否可以用Person创建对象
p1 = Person()
print(p1)
# mro():父类是object
print(Person.mro())

# 传统方式创建父类Animal
class Animal():
	def __init__(self,color):
        self.color = color
    def eat(self):
        print("动物需要吃东西")
        
# 使用type动态创建一个类,父类就是Animal
def sleep(self):
    print('狗在睡觉')
Dog = type('Dog', (Animal,), {'age':3,'sleep':sleep})
dog = Dog('Yellow')
print(dog.age)
dog.sleep()

# 是否继承了父类中的特性
print(dog.color) # 父类中的属性
dog.eat() # 父类中的方法
print(Dog.__name__)

2. 类装饰器的使用

class AAA():
    def __init__(self,func):
        # print("我是AAA.init()")
        self.__func = func
    # TypeError: 'AAA' object is not callable
    # 把新加的方法写在__call__属性中
    def __call__(self, *args, **kwargs):
        self.addFunc()
        self.__func()
    def addFunc(self):
        print("用户权限验证")
        print("日志系统处理")

@AAA
# TypeError: __init__() takes 1 positional argument but 2 were given
# test1 = AAA(test1)
def test1():
    print("我是功能1")

test1()
  • 实例对象test1不可以直接用函数的的方式来调用,必须在类中写 __ call __ ()方法;定义了__ call __()方法的对象,称为“可调用对象”,即该对象可以像函数一样被调用。

3. 对象池

  1. 小整数池:[-5, 256];程序刚开始,一次性加载到内存。
  • LGEB(局部变量,闭包中的变量,全局变量,内建变量)
  1. 大整数池:没每建一个不是小整数池的变量都会被自动存储在大整数池中。
  2. 字符串—intern机制:每个单词(字符串,下划线),不夹杂空格或者其他符号,默认开启intern机制,共享内存,考引用计数决定是否销毁。

4. 垃圾收集

  1. 垃圾回收机制(GC机制):在python中有两种回收机制

    1. 引用计算机制为主;隔代回收为辅
    2. 如何获取一个对象的引用计数:
      sys.getrefcount()(刚创建出来的对象引用计数为2)
  • 增加引用计数的情况

    1. 如果有新的对象使用该对象,+1

    2. 装进列表,+1

    3. 作为函数参数,+1

  • 减少引用计数的情况

    1. 新对象不再使用,-1
    2. 从列表中移除,-1
    3. 函数调用结束,-1
    4. del 显示销毁,-1
import sys

class AA():
    # 创建对象开辟内存时调用
    def __new__(cls, *args, **kwargs):
        print("开辟内存空间")
        return super(AA, cls).__new__(cls)
    # 初始化方法
    def __init__(self):
        print("创建对象at:%s"%hex(id(self)))
    # 对象被系统回之前,会调用该方法
    def __del__(self):
        print("%s say bye bye"%hex(id(self)))

def test1(aaa):
    print(aaa)
    print('a的引用计数为:%d'%sys.getrefcount(a))

a = AA()
print('a的引用计数为:%d'%sys.getrefcount(a))
b = a
print('a的引用计数为:%d'%sys.getrefcount(a))
list1 = [a]
print('a的引用计数为:%d'%sys.getrefcount(a))
test1(a)
print('a的引用计数为:%d'%sys.getrefcount(a))
print("*"*50)
  1. 隔代回收为辅

    1. 原理:引用计数机制无法删除互相引用的对象;随着时间的推荐,程序冗余对象逐渐增多,到达一定的数量(阈值),系统进行回收。

    2. 代码:

      import gc
      gc.get_count()
      gc.get_threshold() :(700, 10, 10)
      gc.set_threshold()
      gc.disable()

    import gc
    import time
    class AA():
    	def __new__(cls, *agrs, **kwargs):
            print('new')
            return super(AA,cls).__new__(cls)
        def __init__(self):
            print('object:born at %s'%hex(id(self)))
        def __del__(self):
            print('%s 被系统回收'%hex(id(self)))
     
    def start():
        while True:
            a = AA()
            b = AA()
            a.v = b
            b.v = a
            del a
            del b
            time.sleep(0.5)
            print(gc.get_threshold())
            print(gc.get_count())
    start()
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值