美文网首页
基础合集-概念篇

基础合集-概念篇

作者: 啊哈_6377 | 来源:发表于2020-07-19 12:55 被阅读0次

概念篇:

1、深拷贝,浅拷贝?

  深拷贝是将对象本身复制给另一对象,另一对象的修改是对原对象副本的修改,不会影响原对象

  浅拷贝是新增对象的引用给另一对象,另一对象的修改会影响原对象

2、三元表达式?

  格式 :true的执行语句 if 条件 else flase的执行语句

3、python多线程?

  python的代码执行由python虚拟机来控制,对python虚拟机的访问又由GIL(全局解释器锁)来控制,全局解释器一次只能执行单个线程。在多线程的时候,python虚拟机会先设置GIL-->切换到线程运行-->运行-->将线程设置为睡眠-->解锁,再执行另一线程。

4、内存管理机制?

引用计数:python中变量声明时会为其分配内存,并计数引用次数。当对象引用次数减至0时,该对象成为要被回收的对象。在容器对象中会产生循环引用,会使用标记清除法清除引用环,计算出对象的有效引用计数。(标记-清除算法会有两个链表,root链表和unreachable链表,容器对象会维护两个额外指针,用来将容器对象串成一个链表,根据指针前后容器对象的应用拆除引用环,放入unreachable链表中,如果被判无罪,放入root链表)

循环引用列子:a=[1,2],b=[3,4],a.append(b),b.append(a),del a,del b。a,b两对象的引用次数为2,当执行了del a,b,两对象引用次数减1,仍无法成为被回收的对象,此时标记-清除算法开始起作用,从拆除a,b的引用环,之后a,b的计数减为0,成为垃圾回收对象。

分代回收:频繁GC是相当耗资源的,故为提升GC性能,有分代回收机制。其将对象分为三代,新生对象是0代,当0代经过一次垃圾回收之后仍存活,则升级为1代青年,1代青年经垃圾回收之后存活就成为2代老年。当第0代分配的对象减去释放对象的个数差值大于threshold0,触发一次0代垃圾回收。当第0代被GC的次数大于threshold1,会触发一次第1代的GC。阈值是可以设置的。

内存池:为加速python执行效率,引用内存池管理小块内存的申请和释放。

5、对象储存机制?

  数字,短小字符分配内存,相同的值只是增加引用计数,不分配新内存空间,容器对象储存其中对象的指向,不储存实际对象本身。

6、*args 和 **kwargs参数?

  当未知函数需要传入多少个参数时,可使用*args,相当于列表;未知会传入多少个关键字参数时,使用**kwargs,相当于字典

7、闭包?

  当外函数中定义了一个内函数,内函数中使用了外函数的变量(非全局作用域的),外函数返回内函数的函数调用,这样的结构就形成了闭包。闭包特殊在,一般函数调用结束后,函数内的变量将会被释放掉,但使用闭包,外函数发现内函数使用了自己的临时变量,将会把这个变量绑定给内部函数,然后再结束。当调用外函数,返回的是内函数的引用,一旦外函数被调用过一次,返回的就是内函数的引用;此后实际是调用内函数,使用的是外函数的临时变量,且每次使用的是同一份闭包变量。

8、装饰器?

  是在不改变原函数的情况下,给函数新增功能。装饰器装饰函数,返回函数,这个函数是装饰后的函数内嵌原函数的函数。

  函数执行前预备处理,函数执行后清理,函数执行时间统计等。

9、生成器,迭代器?

  说到迭代器,还有一个可迭代对象的概念,我们可以使用for循环遍历的对象,都是可迭代对象,可迭代对象是指含有iter()或getitem()函数的对象,可迭代对象在迭代时是将对象一次性加载在内存中,然后调用getitem()方法根据索引遍历元素。而迭代器是含有next()方法的对象,迭代器不能使用for循环去遍历,他不会一次性将对象读到内存中,而是需要自己在next()方法中维护索引,调用next()方法实现遍历。生成器是既可以使用for循环遍历,也可以使用next(),在使用next()时他会记录最后一次被调用的位置和数据,读到最后一个后会抛出异常,但是遍历时又不会一次把对象读到内存中。含有yield()函数的对象都是生成器。

  列表解析和生成器?

  print sum([len(word) for word in str.split()])#列表解析,将分割出的单词长度生成列表后求和

  print sum(len(word) for word in str.split())#生成器,性能更优。不会生成列表。是可迭代对象传递给sum函数

10、数组,链表,队列,堆栈?

    数组,链表是描述数据的储存方式,数组是在连续空间存储数据,链表是在不连续空间存储数据

    队列,堆栈是描述数据存取的方式,队列是先进先出,堆栈是后进先出。

11、is和==?

    is是比较两对象的内存地址是否一致,检查是否指向同一对象;==是检查两对象的值是否相等。

12、__init__和__new__?

    在实例化对象时,这两个方法都调用了。__new__是创建对象并返回实例对象,当返回对象时会调用__init__初始化;__init__是实例方法

13、上下文管理器,with语句?

    一个实现了__enter__和__exit__方法的对象,就是一个上下文管理器。要使用上下文管理器需要执行with语句建立运行时上下文,负责with内语句块进入和退出操作,__enter__是语句块执行前的上下文,__exit__是退出语句块时上下文。如果有as语句,则是将__enter__返回对象赋值给as目标对象。__exit__方法只能返回布尔值,TRUE代表忽略异常,with代码块中不再抛出异常,flase表示需要抛出异常,让其在with代码块中处理异常。

class TestWith():

    def __init__(self,a):

        self.a=a

    def __enter__(self):

        print("connect....")

        self.a.append("b")

        self.a.append("c")

        return self.a

    #__exit__返回True表示异常已处理,不用再在with代码块中抛异常

    #__exit__返回Flase表示异常在with代码块中处理

    #无论with代码块中是否发生异常,__exit__函数都会执行

    # 后面三个参数贮存发生异常时信息:<class 'ZeroDivisionError'>, division by zero, <traceback object at 0x000001FCBAE63DC8>

    def __exit__(self, exc_type, exc_val, exc_tb):

        print("close....")

        if exc_tb:

            print("异常被捕获")

            print(exc_type,exc_val,exc_tb)

        self.a.pop()

        return True

t=TestWith(["a"])with t as tt:#执行__enter__方法,贮存在as中    print(1 / 0)    print(tt)#['a', 'b', 'c']#离开with语句,执行__exit__方法print(tt)#['a', 'b']#with open("with.txt","w+") as f:#    f.write("hello")#无需再调用关闭,with会在离开这个语句块后自动关闭了

相关文章

网友评论

      本文标题:基础合集-概念篇

      本文链接:https://www.haomeiwen.com/subject/teblkktx.html