热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

pythonglobal用法_Python基础知识点整理

内容整理函数函数返回:函数执行时遇到return即执行完毕,返回结果;没有return,执行完毕返回None;returnNone可以简写为return.内建函数:高效快速,e.g
32a6437d68631f401a9968d4138bc5c7.png

内容整理

函数

  • 函数返回: 函数执行时遇到return即执行完毕, 返回结果; 没有return, 执行完毕返回None; return None可以简写为return.
  • 内建函数: 高效快速, e.g. input(), ord(), pow(), isinstance(), iter()
  • 局部变量: 比全局变量快, 尽量避免global; 但下文有提到全局字典保存不同线程专属对象的技巧
  • 默认参数: 必须指向不变对象: 函数在定义时, 默认参数值就会被计算出来
  • Python解释器: 只检查参数个数, 不检查参数类型. 但它会检查自己的内置函数参数格式和类型, 这不公平...对于自己写的函数, 可以用内置函数isinstance实现参数类型检查

1 if not isinstance(x, (int)): 2 raise TypeError('not int type')

  • 多返回值: return x, y, 当然本质是省略了括号的tuple
  • 多重赋值: x,y = y,x 要比三条语句执行快
  • 字符串连接: 和Java语法一样, 使用join()要比"+"高效, "+"会创建一个新的字符串并复制内容
  • 延迟加载: ipmort在需要时再导入
  • 无限循环: while 1比while True高效, 因为while 1是单步运算
  • 列表生成式(list comprehension): 取代for和while更高效, 因为Python解释器能够在循环中发现它是一个可以预测的模式而被优化, 同时list更具可读性. 和Java一样, 可以在循环中节省一个额外的计数变量. e.g. evens &#61; [i for i in range(10) if i%2 &#61;&#61; 0] 要比 while i<10: if i%2 &#61;&#61; 0: evens.append(i) i&#43;&#61;1 易读高效
  • 生成器(generator): 里提到, 生成器保存的是算法, 每次调用next()时才会计算出下一个值, 返回后保存这次计算的位置. 里也给出了逐个字节发送视频流的例子: chunk&#61;(1000*i for i in xrange(1000)), chunk.next(), chunk.next(). 从两个例子中可以看出生成器的共性: 是一个表达式, 再调用的时候才执行一次, 再次调用时执行第二次...而构造生成器, 要么是一个xrange表达式, 要么是在函数里合适的位置加入yield, 保存当前状态后返回本次计算结果
  • 查找效率: dict和set的查找很快, 因为是哈希表实现. list的实现是数组, 所以在list前插入效率不高, 因为list的后续下标不得不全部改变. 类比到Java里的集合框架: ArrayList数组线性表不适合在中间插入, 因为要改变后续元素下标; Java的Set和Python的set一样都是元素不重复的, 而且由Hash实现. Java的集合框架太强大太繁杂, Python则简化了很多, 记住dict, set, list, tuple目前就够用了
  • 装饰器: 目前只掌握了简单修饰, 加参数修饰的用法

进程和线程的基础知识

  • CPU执行代码是顺序执行, 单核CPU通过让任务交替执行, "模拟"除了多任务并发执行. 真正的多任务并发, 是在多核CPU上, 每个CPU负责执行一个任务. 但实际任务数量远多于CPU核心数量, 所以最终还是操作系统把多任务轮流调度到不同的核心上执行.
  • 进程/线程和物理内存(寄存器)/CPU的关联: 函数调用, 会在栈中分配一块空间, 存放局部变量和参数, 调用结束, 栈空间被释放. 每个线程都有独立的栈, 寄存器. 同一进程里的所有线程共享文件, 代码和数据.
  • 进程独立性: 以CPU中的程序计数器PC为例, 物理的PC只有一个, 但是每个进程有独立的逻辑PC, 保存了程序运行中的值, 但CPU轮到该进程时, 就将逻辑PC值复制到物理PC.

Python跨平台支持多进程

  • Unix/Linux平台Python支持fork(): 父进程复制出一个子进程
  • Windows平台Python支持Process(target,args): "模拟出fork()的效果", 即父进程所有Python对象pickle后传递给子进程

Python进程间通信的数据交换方式

multiprocessing模块提供的Queue, Pipes

Python多线程基础知识

  • 标准库提供了两个模块: thread和threading(推荐).
  • 任务进程都默认启动一个叫做MainThread的主线程, 主线程可以启动新的子线程.
  • 多线程的变量锁: 高级语言的一条语句在CPU执行时是若干条语句, 计算中的结果会存入临时变量中, 每个线程都有自己的临时变量.
  • 获取锁后一定要释放, 否则等待锁的线程会一直阻塞下去, 成为死线程. Python中可以通过try...finally确保释放.
  • 锁的坏处: (1) 加锁的代码只能以单线程模式执行, 阻止了多线程并发, 降低效率; (2) 可能造成死锁.

Python的GIL锁导致多线程不能充分利用多核CPU

  • Python的解释器有一个GIL(Global Interpreter Lock)锁, 任何线程执行前, 先获得GIL锁, 每执行100行代码, 解释器会自动释放GIL锁, 让别的线程有机会执行. 所以即使100个线程跑在100核CPU上, 也只能用到1个核.
  • GIL是Python解释器设计的历史遗留问题, 使得Python不能有效利用多核, 但可以通过多进程实现.
  • 多个Python进程有各自独立的GIL锁, 互不影响.
  • GIL: 只是CPython解释器存在. "GIL会序列化你的所有线程". 可以使用线程来管理多个派生进程, 使这些进程独立运行于Python代码之外.

多线程下选择加锁的全局变量or不得不传递下去的局部变量?

加锁和传递局部变量都是老方法了, 只是局部变量传递起来很麻烦. 如果遇到每个线程一个专属对象, 不能使用全局变量的情况, 作者就想到用一个全局dict, 但是通过线程自身作为key获得保存的对应的对象, 例如:

# -*-coding:utf-8 -*-

global_dict &#61;{}作为一个全局变量, 保存了线程和它的专属对象. 运行结果:

D:WorkspaceVSCode>python multiprocess.py
thread MainThread is running...
thread t1, do_task_1() std.name &#61; Elsathread t2, do_task_2() std.name &#61; Annathread MainThread ended.

然后Python又简化了对每个线程专属对象的存储和访问, 也就是封装了上面的global_dict &#61; {}. 可以理解成, local_school &#61; threading.local()是一个全局变量, 但它里面保存的是各个线程的局部变量, 还不用管理线程锁了, 感觉很方便的样子.

多线程时使用ThreadLocal用全局变量保存线程的局部变量

常用于为每个线程绑定一个数据库连接, HTTP请求, 用户身份信息等.

进程, 线程和计算密集, IO密集型任务

  • 多进程更稳定, 系统的子进程互相内存独立, 子进程崩溃不会影响其它进程(主进程除外)
  • 多线程更高效, 但由于所有线程共享进程的内存, 一个崩溃会引发系统强制结束整个进程
  • 计算密集型任务, 如视频高清解码, 主要开销在CPU计算, 任务数&#61;核心数最好
  • IO密集型任务, 如网络, 磁盘IO等, CPU消耗很少, 大部分时间都是在等待IO操作完成, 任务越多, CPU效率越高(有限度)

CPU和IO操作间巨大的速度差异催生了异步IO

既然一个任务在执行时大部分时间都是CPU等待IO, 单进程单线程并不能充分的利用CPU资源, 在CPU等待IO的时候, 不放用空闲时间去执行CPU计算任务. "现代操作系统对IO操作已经做出了巨大改进, 最大的特点就是支持异步IO. 如果充分利用操作系统提供的异步IO支持, 就可以用单进程单线程模型来执行多任务." (Android里的AsyncTask就是一种异步, 但是它本质是另外起了一个小线程, 所以异步就是多线程?)

分布式多进程, 还能够通过网络共享任务队列

  • Python的multiprocessing模块, 支持多进程, 还支持多进程分布到多台设备
  • 原理就是将多进程共享的Queue通过网络暴露出去, 其它机器就可以访问Queue了(就像remoterobotserver通过网络暴露出robot的库一样)

性能调优工具

python -m cProfile mypython.py

Native&#43;包装器

Python程序可以直接加载已变成的二进制库(.dll或.so)文件, 不用编写C/C&#43;&#43;代码(直接源码&#43;NDK)或构建依赖(Gradle中添加.so库构建依赖)

嵌入式物联网资料分享交流群&#xff1a;332650978 入群有全套学习视频资料电子书免费赠送&#xff01;

资料参考&#xff1a;

Python基础视频教程 入门免费观看​www.makeru.com.cn
208f62bc059afbf0f3321ab10b39df2e.png
python入门_python​www.makeru.com.cn
dfb96099174a5c13f11b3bb8667b2822.png
Python AI开发实战营 - Day1:建立python语言世界​www.makeru.com.cnPython AI开发实战营 - 一堂课快速认识Python机器学习​www.makeru.com.cn


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
author-avatar
mobiledu2502901883
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有