Python基础

Python

  • _name_
  • java string和字符串区别
  • 深浅拷贝
  • 内存池 垃圾回收机制
    • 引用增减
    • 垃圾回收
      • 引用计数
      • 标记清除
      • 分代回收
    • 缓存机制
      • 池机制
      • free_list
  • 装饰器
  • 迭代器
  • 提高运行效率的方法
  • 函数传递方式

name

当一个Python文件作为主程序运行时,name__属性的值将被设置为__main。这提供了一种方式,通过判断__name__来执行特定的代码块。

如果一个Python文件被其他文件导入,name__的值将是该模块的名称,而不是__main。这为模块提供了一种在导入时不执行某些代码的方式。

在编写单元测试时,__name__属性可以用于判断当前模块是否为测试模块,以便执行相应的测试代码。

模块独立运行
通过在模块中使用if name == “main”:语句,确保模块在需要时能够独立运行。这使得每个模块都成为一个可执行的脚本,方便测试和调试。

当在其他程序中导入模块时,name__属性的值将是模块的名称,而不是__main。这使得模块能够无缝地集成到其他程序中,而不执行在if name == “main”:块内的代码。

方便维护、模块独立测试、模块复用

java string和字符串区别

线程安全:
StringBuffer:线程安全
StringBuilder:线程不安全
使用环境:
操作少量的数据使用 String;
单线程操作大量数据使用 StringBuilder;
多线程操作大量数据使用 StringBuffer。

深浅拷贝

深拷贝
不仅拷贝对象,对象内的元素也会发生拷贝。拷贝的是对象。

浅拷贝
只拷贝了对象,对象内的元素并不会发生拷贝。也就是说拷贝的是引用。

但是并不代表浅拷贝下修改了其中一个元素的值,另一个素内元素的值一定会发生变化,还要看被修改的值是否是可变对象:
【情况一】:如果是修改的元素是可变对象(set list dict字典),那么修改了其中一个元素,拷贝的元素会发生变化,;
【情况二】:如果修改的元素是不可变对象(int string tuple元组),那么修改了其中一个元素,拷贝的元素不会发生变化,

内存池 垃圾回收机制

引用增减


对象被创建:a = ‘abc’
对象被引用:b = a
对象作为其他对象的一个元素:c = [1,2,a]
对象被作为参数传递给函数:f(a)


变量被删除:del a or del b
变量引用了其他对象:b = c or a = c
在其他的引用对象中被删除(移除):c.remove(a)
引用对象本身被销毁:del c
变量离开了所在的作用域(函数调用结束):比如f(a)结束时,传入参数a的引用次数-1

可以用sys.getrefcount函数看某个参数引用次数,但是其返回的计数总是比实际的引用次数多1,这是因为这里面包含了调用此函数的临时计数。

垃圾回收

引用计数

当一个对象的引用计数归零时,会被垃圾回收。
Python解释器会定期执行一个循环检测器,搜索不可访问的对象的循环,并删除他们。
优点:简单实时性。
缺点:维护引用计数消耗资源,且无法解决循环引用。

标记清除

创建特殊链表专门用于保存 列表、元组、字典、集合、自定义类等对象,之后再去检查这个链表中的对象是否存在循环引用
缺点:清除非活动的对象前它必须顺序扫描整个堆内存,哪怕只剩下小部分活动对象也要扫描所有对象。

分代回收

简单来说,分代回收就是为了提升标记清除的效率
对标记清除中的链表进行优化,将那些可能存在循引用的对象拆分到3个链表,链表称为:1/2/3三代,每代都可以存储对象和阈值,当达到阈值时,就会对相应的链表中的每个对象做一次扫描,除循环引用各自减1并且销毁引用计数器为0的对象。

缓存机制

因为内存申请和销毁一般比较耗时,Python有两大类缓存机制来避免频繁的内存申请和销毁从而提升效率。

池机制

在解释器中程序一开始就默认创建了一些常见的对象放在池中,当程序中用到这些对象时,只需要从池中获取就行,即引用次数+1,而不需要重新一个新的对象,也不需要开辟新的内存。
此外,在程序过程中池中的对象不会被销毁,除非程序结束。

Python提供了对内存的垃圾回收机制,将不用的内存放到内存池而不是返回给操作系统。

1)Pymalloc 机制。为了加速 Python 的执行效率和管理对小块内存的申请和释放。
2)Python 中所有小于 256 个字节的对象都使用 pymalloc 实现的分配器,而大的对象则使用系统的 malloc。
3)对于Python对象,如整数、浮点数和List,都有其独立的私有内存池,对象间不共享它们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。

free_list

当一个对象的引用计数为0时,程序内部本应该立即将内存销毁,但内部并没有直接销毁。
而是将对象添加到free_list链表中当做缓存,以后再去创建新对象时,不在重新开辟内存,而是直接使用free_list。
Python中不同的数据类型使用的free_list也不同,比如小的整数型就不使用free_list,而是使用池

装饰器

通过装饰器函数,来修改原函数的一些功能,又不会改变原函数的内部实现,又使得原函数不需要修改。装饰器本身可以增强其他函数的功能。
优点:
避免大量的重复代码;

装饰器的原理
装饰器的原理是基于Python的函数对象和闭包的特性。当定义一个装饰器时,我们实际上创建了一个新的函数对象,该对象接受一个函数作为参数。这个新的函数对象的__call__方法被调用,它将调用我们传递给装饰器的原始函数。

当我们使用@decorator语法将装饰器应用于一个函数时,Python会执行以下操作:

创建一个新的函数对象,该对象将调用我们传递给装饰器的原始函数。
将新创建的函数对象的__call__方法设置为装饰器函数。
将新创建的函数对象的__name__属性设置为原始函数的名称。
将新创建的函数对象的__doc__属性设置为原始函数的文档字符串。
将新创建的函数对象的__module__属性设置为原始函数的模块名称。
将新创建的函数对象的__globals__属性设置为原始函数的全局作用域。
将新创建的函数对象的__closure__属性设置为原始函数的闭包。
返回新创建的函数对象。
当我们调用被装饰的函数时,Python会调用我们传递给装饰器的原始函数,并执行我们在装饰器中添加的额外功能。

迭代器

迭代器是一个对象,它可以返回一个序列中的一个个元素。迭代器可以用于遍历列表、字典、集合等数据结构。

迭代器的主要优点是它们可以一次只返回一个元素,这意味着它们可以处理大量数据时节省内存。所以循环遍历常用迭代器。
迭代器的原理
迭代器的原理是基于Python的内置iter()函数和next()函数的特性。当我们调用iter()函数并传递一个可迭代对象时,Python会返回一个迭代器对象。当我们调用next()函数并传递一个迭代器对象时,Python会返回迭代器对象的下一个元素。

当我们调用iter()函数时,Python会执行以下操作:

创建一个新的迭代器对象。
将新创建的迭代器对象的__next__方法设置为迭代器对象的next()方法。
将新创建的迭代器对象的__iter__方法设置为迭代器对象本身。
返回新创建的迭代器对象。
当我们调用next()函数时,Python会执行以下操作:

调用迭代器对象的__next__方法,并返回下一个元素。
如果迭代器对象的__next__方法已经被调用过一次,并且迭代器对象的__iter__方法返回False,则会引发StopIteration异常。

提高运行效率的方法

5方法-使用外部功能包-排序时使用key-针对循环优化-尝试多种编译方法-python版本-交叉编译

函数传递方式

python参数传递采用的是“传对象引用”的方式,这种方式是值传递和引用传递的综合。

不可变参数类型是值传递:

如果函数收到的是一个不可变数据类型(比如数字、字符或者元组)的引用,就不能直接修改原始对象,相当于通过“传值’来传递对象。

可变参数类型是引用传递:

如果函数收到的是一个可变数据类型(比如字典或者列表)的引用,就能修改对象的原始值,相当于通过“传引用”来传递对象。

你可能感兴趣的:(python,jvm,开发语言)