一、可变对象和不可变对象
- 可变对象:列表,字典,集合
- 不可变对象:整型,浮点数,字符串,元组
二、python的内存缓存机制
- 小整数对象池:[-5,257),这些是提前创建好的。
- 单个字符:提前创建好放在缓存池中。
- 字符串的intern机制:字符串中只包含数字,字母下划线,那么python会自动开启intern机制,吧创建的字符串放入一个形如字典的内存中,如果下次创建相同的字符串会直接从内存中拿出来。
from sys import intern a=intern('!abc') b=intern('!abc') #此时id(a)=id(b),该效果只在cmd下实现该效果
三、python垃圾回收机制
引用计数
- 优点:简单,实时性高
- 缺点:维护计数消耗资源,循环引用
标记清除
- 目的:解决循环引用
- 缺点:
- 检查的时间不好控制
- 每次检查都会去检查所有数据,开销非常大
分代收集
- 目的:解决标记清除的缺点
- 原因:把可能存在循环引用的链表划分为3个列表,分布叫0代【对象达到700次后检查】,1代【在0次检查10次之后检查】,2代【在1代检查10次之后检查】
四、魔法方法:
- init:初始化
- new:创建实例化对象,主要用来创建单例模式
class A: def __new__(cls,*args,**kwargs): return super().__new__(cls) def __init__(self,name): self.name=name #self为__new__返回的对象 a=A('abc') print(a.name)
单例模式:
#默认在创建不同的对象时,会独立创建一块内存 class A(object): __instance=None def __new__(cls,*args,**kwargs): if cls.__instance==None: cls.__instance =super().__new__(cls) return cls.__instance def __init__(self,name): self.name=name a=A('abc') b=A('abc') print(id(a),id(b))#此时a,b的id是一样的
后续:https://blog.nowcoder.net/n/9753293bce1c4fc5b3307b4cdb98e97c
五、对象方法,类方法,静态方法
method:对象方法[普通:需要实例化]
- 定义方式:无需特殊要求,正常定义即可
- 传参方式:需要第一个参数是self,代表实例对象本身
- 调用情况:需要实例对象去调用,并且会自动把实例对象传入函数
- 访问情况:可用访问类内部所有的属性和方法,通过self可用获取到类内部的任何属性和方法
- def normal(self):
staticmethod:静态方法(无需实例化)
- 定义方式:需要使用staticmethod装饰函数
- 传参方式:没有传参要求,一般可用不传参
- 访问情况:无法访问类内部的任何属性和方法,若要访问要手动把实例化对象传入
- 调用情况:可用用实例对象和类名调用,推荐用类名调用,
- @staticmethod
def static_method(obj):
- @staticmethod
classmethod:类方法 (无需实例化)
- 定义方式:要使用classmethod装饰函数
- 传参方式:要求第一个参数是cls,cls表示类本身。
- 访问情况:可用访问类内部的类属性和类方法,因为可以通过cls访问到类属性和类方法,也可以访问到静态属性和方法,但访问不到实例属性和方法。
- 调用情况:可用使用实例化对象和类名去调用,推荐使用类名调用。
- @classmethod
def class_method(obj):
- @classmethod
六、元类
type不仅可用查看对象的类型,还可以动态的创建类。
元类就是创建类这种对象的东西,type就是python的内建元类。
class Test: pass print('Test') Test=type('Test',(),{}) print('Test')#与上面的结果是一样的
自定义元类:
七、私有属性
@property
class Money: def __init__(self): self.__money=100 @property def getMoney(self): return self.__money @getMoney.setter def setMoney(self,value): if isinstance(value,int): self.__money=value else: print('error:不是整型数字') m=Money() print(m.getMoney)
八、深浅拷贝
copy拷贝表层元素,deepcopy在内存中重新创建所有的资源搜索
a[:]#浅拷贝
九、python的上下文管理
with open('a.txr','r') as fp: data=fp.read()#会自动关闭
with包含enter,exit方法
class File: def __init__(self,filename,mode): self.fp=open(filename,mode) def __enter__(self): print('entering') return self.fp def __exit__(self,*args): print('exiting') fp.close() with open('abc.txt','r') as fp: print(fp.read()) if __name__= '__main__': main()
十、生成器和迭代器
生成器:
一种特殊的迭代器,(不需要我们去实现iter,next方法,只有定义生成器,生成器自动实现这两个方法)
- 定义:
- 函数使用yield来返回
- 使用生成器表达式(列表生成式把中括号改成小括号)
- 创建
- 元组推导式:(i for i in range(10))
- send可以给生成器动态传值
def G(): i=0 while i < 5: m=yield i print(m) i+=1 print(G().send(None)) print(G().send(10))
- yield和send就是协程底层的写法
迭代器
- 实现了iter和_next__方法的对象
- iter,必须返回自身
- next,返回当前的元素,并备好下一个元素
自定义迭代器: class A: def __init__(self): self.num=0 def __iter__(self): return self def __next__(self): self.num+=1 return self.num
- 可迭代对象:可直接作用于for的数据类型
只实现了iter没有是实现next方法的对象
十一、闭包
闭包可以不去回收外层函数的变量,将私有变量转换为全局变量。
引用了自由变量的函数叫闭包(函数)
十二、装饰器
遵循开放封闭原则,
体现了面向切面编程的思想(AOP)
带参数的装饰器,需要多加一层函数,用来接收装饰器本身的参数。
装饰器的问题:会修改被装饰的函数的name,docsinting
解决:加@wraps(foo) from funtools import wraps def func(n): def inner(foo): @wraps(foo) def deco(*args,**kwargs): result=foo() return result return deco return inner
多层装饰器
- 装饰时,从里到外
- 执行时,从外到里,在从里到外返回
- 装饰器一般是函数进,函数出
类装饰器
@Deco
def foo(x,y):
pass
foo=Deco(foo)#相当于生成了类的实例对象
foo(1,2)#相当于使用Deco的实例对象进行函数调用- 只要实现了call方法,那么这个类的实例对象就变得和函数一样可用被调用
带参数的类装饰器
- 类的init方法用来接收装饰器本身的参数
- call
- 第一层用来接收func函数
- 第二层用来接收func的参数