一、可变对象和不可变对象

  • 可变对象:列表,字典,集合
  • 不可变对象:整型,浮点数,字符串,元组

二、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):

classmethod:类方法 (无需实例化)

  • 定义方式:要使用classmethod装饰函数
  • 传参方式:要求第一个参数是cls,cls表示类本身。
  • 访问情况:可用访问类内部的类属性和类方法,因为可以通过cls访问到类属性和类方法,也可以访问到静态属性和方法,但访问不到实例属性和方法。
  • 调用情况:可用使用实例化对象和类名去调用,推荐使用类名调用。
    • @classmethod
      def class_method(obj):

六、元类

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的参数