Python基础知识点合集

概念

Python有什么优势

  • 解释性语言,语法简单易懂,可读性强
  • 自动内存管理,基于引用计数法等可以对垃圾进行自动回收;内存池机制,提前申请好小内存,内存分配效率更高。让程序员可以更加专注代码的实现。
  • 有很多库可以调用,站在巨人的肩膀上简单的实现想要的功能
  • 可扩展,和其他编程语言或者软件有可连接的接口
  • 免费开源

Python和Java的对比

编译型语言:经过一次编译之后,由操作系统直接执行。如c++和c

解释型语言:读一行,解释执行一行

Java:现将程序编译成字节码文件,然后字节码文件在虚拟机上运行,虚拟机从字节码文件读一行解释执行一行。

所以Java是结合了编译型和解释型语言的特点。

  • 语言特点:Python是强类型的动态语言,是解释性语言;Java是强类型的静态语言,结合了解释性语言和编译型语言的特点。所以Java的运行速度要快一些。
  • 多线程模型:python的多线程不能实现多CPU条件下的并行运行,每个线程在运行时首先需要获得GIL,Python的多线程是通过协程或者多进程的机制来实现。但是Java的多线程编程很强大,支持真正的多线程并发操作。
  • 垃圾回收:Python的垃圾回收机制以引用计数法为主,标记清除和分代回收为辅。

语法基础

is和==的区别

  • is表示两个对象是否指向同一块地址空间,若为true,表示指向同一地址空间,且值一定相等。(Java的==)

  • ==表示值是否相等。(Java的equals)

    “hello world” 有空格,为非标识符允许的字符,不驻留内存。

    a = "hello world"
    b = "hello world"
    print(id(a))   # 输出 140506208811952
    print(id(b))   # 输出 140506208812208
    print(a is b)  # 输出 False
    print(a == b)  # 输出 True 
    
    a = "hello"
    b = "hello"
    print(id(a))   # 输出 140506224367496
    print(id(b))   # 输出 140506224367496
    print(a is b)  # 输出 True 
    print(a == b)  # 输出 True
    

元组、列表和字典的区别

列表:可重复,类型可不同

元组:结构和列表类似,但是是不可变对象

扫描二维码关注公众号,回复: 11448863 查看本文章

字典:定义了键和值之间一对一的关系,但是是以无序的方式存储的。键值不可以重复。但是python3.7以后变成有序了。

深拷贝和浅拷贝

  • 对于不可变对象(元组、字符串等),python采用的是引用计数法,不管是深拷贝还是浅拷贝,作用都是一致的,相当于复制了一份副本,当原对象内部的对象发生改变时,不会影响到幅值对象。

  • 等号赋值:相当于给给原来对象贴一个新标签,当其中一个标签被改变的时候,另一个标签也会随之变化。

  • 对于浅拷贝,分两种情况:

    1)一种是不可变对象,和等号赋值一样。

    2)一种是可变对象,这里又分两种情况:

    ​ 可变对象内部无复杂子元素:原来值的改变不会影响浅拷贝的值

    ​ 可变对象内部有复杂子元素:如果改变原来值中复杂子对象的值,会影响浅拷贝的值。

  • 对于深拷贝,对一个对象所有层次的拷贝,作为一个新的个体单独存在,所以不管原本对象怎么改变,都不会改变拷贝副本的值。相当于备份。

    浅拷贝占用空间小,拷贝层次低,拷贝速度快,因此效率高。一般默认就是浅拷贝。

位置参数和关键字参数的区别(*args,**kw)

函数参数可为分如下几种:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

*args:可变参数,args接收的是一个tuple

**kw:关键字参数,kw接收的是一个kw。比如我们要实现用户注册,有必输项和非必输项,这些非必输项就可以用关键字参数来接受。

对于任意函数都可以通过类似func(*args,**kw)的形式来调用,无论他的参数是怎么定义的。

装饰器

装饰器本身是一个函数,可以让已有的函数再不改变的情况下增加功能。适合有切面需求的场景,比如权限校验,日志记录等。

和Java里面的动态代理实现方式有点类似。

生成器和迭代器

迭代器

是访问集合元素的一种方式,用iter()创建迭代器,调用next()函数获取对象。(迭代器只能往前不能往后)

生成器

是一种特殊的迭代器,生成一系列的值用于迭代。

使用了yield函数,返回迭代器。

区别

  • 创建:生成器创建一个函数,用yield返回对象;迭代器用内置函数iter()和next();

线程

多线程的创建

使用threading的模块,启动一个线程就是把一个函数传入并创建thread实例,然后调用start( )开始执行。

GIL

python中线程通信的方式是通过GIL(全局解释锁)来实现的,任何python的线程执行前必须先获得GIL锁,然后每执行100个字节,解释器就释放GIL锁,让别的线程有机会执行。所以多线程在python中只能交替执行,Python的多线程只能利用一个核。

Python多线程模型

Python由于GIL锁的设计,导致多线程无法利用多核。

对于CPU密集型的任务,主要是消耗CPU资源,Python这样的脚本语言运行效率很低,完全不适合这种计算密集型的任务。

Python适合IO密集型的任务,开发效率最高(代码最少)

内存管理与垃圾回收

内存管理

python有内存池机制,小内存使用内存池进行分配,大内存使用malloc进行分配。当创建大量消耗小内存的对象时,频繁调用new/malloc会导致大量的内存碎片,同时效率较低。内存池就是先申请一定数量的内存块作为备用,当有内存需求时,就从内存池中分配内存给这个需求。

垃圾回收

以引用计数为主,标记清除和分代回收为辅。

引用计数

每个对象都会有一个引用计数,当一个对象有新的引用时就计数加一,当引用它的对象被删除,计数就减一。一旦一个对象的引用计数为0,该对象就被回收,对象占用的内存空间被释放。

优点:简单,一旦没有被引用,内存就直接释放了。

缺点:需要额外的空间维护引用计数;同时不能解决对象的循环引用。

标记清除

解决循环引用的问题。先根据可达性分析把活动对象标记,再把没有标记的对象进行回收。

分代回收

把内存分成三代,年轻代、中年代、老年代。新建的对象呗分配到年轻代,年轻代回收之后,没有被回收的对象被挪到老年代。

猜你喜欢

转载自blog.csdn.net/weixin_41524366/article/details/107573823