当前位置: 首页 > news >正文

学Python的漫画漫步进阶 -- 第十六步

学Python的漫画漫步进阶 -- 第十六步

  • 十六、多线程
    • 16.1 线程相关的知识
      • 16.1.1 进程
      • 16.1.2 线程
      • 16.1.3 主线程
    • 16.2 线程模块——threading
    • 16.3 创建子线程
      • 16.3.1 自定义函数实现线程体
      • 16.3.2 自定义线程类实现线程体
    • 16.4 线程管理
      • 16.4.1 等待线程结束
      • 16.4.2 线程停止
    • 16.5 动动手——下载图片示例
    • 16.6 练一练
    • 16.7 多线程总结
    • 全部16步学习完成 ,后续就是介绍项目实战,请大家给予点赞、关注,绝对超值!

十六、多线程

如果想让我们的程序同时执行多个任务,就需要使用多线程技术了。到目前为止,我们编写的程序都是单线程的,在运行时一次只能执行一个任务。

Python多线程是指从软件或者硬件上实现多个线程并发执行的技术。在多线程中,一个程序可以划分为多个独立运行的线程(也称为轻量级进程),这些线程可以并行执行,从而提高程序的执行效率。

多线程的优点在于可以充分利用多核CPU资源,同时执行多个任务,特别是在等待I/O操作(如用户输入、文件读写和网络收发数据等)时,线程可以释放一些珍贵的资源如内存占用等。此外,多线程还可以用于实现并发执行的任务,如网络爬虫、文件批量处理等。

在Python中,多线程相关的模块主要有ThreadThreadingQueue等。其中,Thread是底层支持模块,不建议使用。Threading模块对Thread模块进行了封装,实现了线程的一些操作对象化。而Queue模块则实现了多生产者、多消费者的队列模式,可以方便地在多线程中使用。

需要注意的是,多线程编程也存在着一些问题。首先是线程安全问题,如果多个线程同时访问共享数据,可能会导致数据竞争或冲突的问题。其次是线程同步问题,如果多个线程之间存在依赖关系,需要按照一定的顺序执行,就需要使用线程同步机制来确保正确地执行顺序。此外,多线程的开销也比较大,因为每个线程都需要分配和管理自己的栈空间等资源,所以在实际应用中需要注意控制线程的数量和开销。

总之,Python的多线程编程是一种有效的技术,可以有效地提高程序的执行效率和响应速度。但是在实际应用中需要注意线程安全和线程同步等问题,并合理控制线程的数量和开销。

在这里插入图片描述

16.1 线程相关的知识

本节先介绍线程相关的知识。

16.1.1 进程

一个进程就是一个正在执行的程序,每一个进程都有自己独立的一块内存空间、一组系统资源。在进程的概念中,每一个进程的内部数据和状态都是完全独立的。
在Windows操作系统中,一个进程就是一个exe或者dll程序,它们相互独立,相互也可以通信。

16.1.2 线程

在一个进程中可以包含多个线程,多个线程共享一块内存空间和一组系统资源。所以,系统在各个线程之间切换时,开销要比进程小得多,正因如此,线程被称为轻量级进程。

16.1.3 主线程

Python程序至少有一个线程,这就是主线程,程序在启动后由Python解释器负责创建主线程,在程序结束后由Python解释器负责停止主线程。
在多线程中,主线程负责其他线程的启动、挂起、停止等操作。其他线程被称为子线程。

在这里插入图片描述

16.2 线程模块——threading

Python官方提供的threading模块可以进行多线程编程。threading模块提供了多线程编程的高级API,使用起来比较简单。
在threading模块中提供了线程类Thread,还提供了很多线程相关的函数,这些函数中常用的如下。
在这里插入图片描述
active_count():返回当前处于活动状态的线程个数。

current_thread():返回当前的Thread对象。

main_thread():返回主线程对象。主线程是Python解释器启动的线程。示例代码如下:
在这里插入图片描述

通过Python指令运行文件:

在这里插入图片描述

16.3 创建子线程

创建一个可执行的子线程,需要如下两个要素。

1 线程对象:线程对象是threading模块的线程类Thread或Thread子类所创建的对象。

2 线程体:线程体是子线程要执行的代码,这些代码会被封装到一个函数中。子线程在启动后会执行线程体。实现线程体主要有以下两种方式。

1)自定义函数实现线程体。

2)自定义线程类实现线程体。
在这里插入图片描述

16.3.1 自定义函数实现线程体

创建线程Thread对象的构造方法如下:
在这里插入图片描述
target参数指向线程体函数,我们可以自定义该线程体函数;通过name参数可以设置线程名,如果省略这个参数,则系统会为其分配一个名称;args是为线程体函数提供的参数,是一个元组类型。
示例代码如下:

在这里插入图片描述
在这里插入图片描述

通过Python指令运行文件:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

16.3.2 自定义线程类实现线程体

另外一种实现线程体的方式是,创建一个Thread子类并重写run()方法,run()方法就是线程体函数。
采用自定义线程类重新实现16.3.1节的示例,示例代码如下:
在这里插入图片描述
在这里插入图片描述

16.4 线程管理

线程管理包括线程创建、线程启动、线程休眠、等待线程结束和线程停止,其中,线程创建、线程启动和线程休眠在16.3节已经用到了,这些不再赘述。本节重点介绍等待线程结束和线程停止的内容。
在这里插入图片描述

16.4.1 等待线程结束

有时,一个线程(假设是主线程)需要等待另外一个线程(假设是t1子线程)执行结束才能继续执行。
在这里插入图片描述
join()方法的语法如下:
在这里插入图片描述
参数timeout用于设置超时时间,单位是秒。如果没有设置timeout,则可以一直等待,直到结束。
使用join()方法的示例代码如下:
在这里插入图片描述
通过Python指令运行文件:

在这里插入图片描述
从运行结果来看,在子线程t1结束后,主线程才输出变量value的内容,这说明主线程被阻塞了。
如果尝试将t1.join()语句注释掉,则输出结果如下:

在这里插入图片描述
从运行结果可见,子线程t1还没有结束,主线程就输出变量value的内容了。

在这里插入图片描述

16.4.2 线程停止

在线程体结束时,线程就停止了。但在某些业务比较复杂时,会在线程体中执行一个“死循环”。线程体是否持续执行“死循环”是通过判断停止变量实现的,“死循环”结束则线程体结束,线程也就结束了。
另外,在一般情况下,死循环会执行线程任务,然后休眠,再执行,再休眠,直到结束循环。
在这里插入图片描述

示例代码如下:

在这里插入图片描述
通过Python指令运行文件:

在这里插入图片描述

16.5 动动手——下载图片示例

在这里插入图片描述

这个网络爬虫程序每隔一段时间都会执行一次下载图片任务,在下载任务完成后,休眠一段时间再执行。这样反复执行,直到爬虫程序停止。
示例参考代码如下:

在这里插入图片描述

本示例从服务器下载图片,因此需要参考14.2节启动Web服务器,
然后通过Python指令运行文件:

在这里插入图片描述

在这里插入图片描述

16.6 练一练

1 请简述如何创建线程体。

2 请简述线程中join()方法的作用。

3 下列哪些情况可以停止当前线程的运行?()
A.引发一个异常时。

B.当该线程调用sleep()方法时。

C.当创建一个新线程时。

D.当该线程调用stop()方法时。

4 判断对错(请在括号内打√或×,√表示正确,×表示错误)。
1)线程对象是threading模块线程类Thread或Thread子类所创建的对象。()

2)实现线程体主要有以下两种方式:自定义函数实现线程体和自定义线程类实现线程体。()

3)在线程体结束时,可通过调用stop()方法停止。()

4)在线程体结束时,可通过调用join()方法停止。()

16.7 多线程总结

Python多线程是一种在程序中实现并发执行的技术,它允许同时执行多个线程,从而提高程序的运行效率。在Python中,多线程编程可以使用threading模块或concurrent.futures模块来实现。下面是关于Python多线程的总结:

  1. 多线程的概念和原理

多线程是指在一个程序中同时执行多个线程,以充分利用多核CPU资源,提高程序的运行效率。多线程的原理是将程序划分为多个子任务或线程,每个线程并行执行,从而加快程序的执行速度。在Python中,多线程编程可以使用threading模块或concurrent.futures模块来实现。

  1. 线程的创建和管理

在Python中,可以使用threading.Thread()方法来创建一个新线程。创建线程时,需要传入一个可调用对象(即线程要执行的任务)作为参数。当线程被创建后,可以调用start()方法来启动线程,调用join()方法等待线程执行完毕,以及调用is_alive()方法来判断线程是否仍在运行。

  1. 线程安全和线程同步

在多线程编程中,需要注意线程安全和线程同步的问题。线程安全是指在多线程环境下,数据访问不会出现冲突或竞争的情况。如果多个线程同时访问同一个数据,就可能会出现数据竞争或冲突的问题。为了解决这个问题,可以使用同步机制(如互斥锁)来确保在同一时间只有一个线程可以访问共享数据。

  1. threading模块和concurrent.futures模块的比较

Python的threading模块是标准库中的多线程库,使用起来比较简单,但是它不支持异步执行和线程池的概念。相比之下,concurrent.futures模块则提供了更强大的功能,它支持异步执行和线程池的概念,可以更好地管理多线程的执行。

  1. 多线程编程的适用场景

多线程编程适用于需要并发执行多个子任务的场景,特别是当这些子任务之间没有依赖关系,可以并行执行时。例如,在一个网络爬虫程序中,可以使用多线程同时爬取多个网页;在一个文件下载程序中,可以使用多线程同时下载多个文件。需要注意的是,在某些情况下,多线程并不一定能提高程序的性能,因为线程的创建和管理也需要一定的时间和资源开销。因此,在使用多线程编程时,需要根据实际情况进行评估和优化。

  1. 注意事项

在多线程编程中,需要注意以下几点:

  • 避免共享数据:在使用多线程编程时,应该尽量避免共享数据,以避免出现数据竞争或冲突的问题。如果必须要共享数据,应该使用同步机制来确保同一时间只有一个线程可以访问共享数据。
  • 注意线程的生命周期:每个线程都有自己的生命周期,包括创建、启动、运行和结束等阶段。在程序中管理好线程的生命周期,避免出现死锁或其他问题。
  • 慎用全局变量:在多线程编程中,全局变量可能会导致线程不安全。如果必须要使用全局变量,应该使用同步机制来保护全局变量的访问。
  • 选择合适的同步机制:在多线程编程中,选择合适的同步机制非常重要。例如,可以使用互斥锁(mutex)或条件变量(condition variable)等同步机制来确保数据的正确性和一致性。

总之,Python的多线程编程可以让程序实现并发执行多个子任务的目标,从而提高程序的性能和响应速度。但是在使用多线程编程时,需要注意线程安全和线程同步的问题,以及选择合适的同步机制来保护共享数据的访问。


全部16步学习完成 ,后续就是介绍项目实战,请大家给予点赞、关注,绝对超值!



附录

“练一练”参考答案

第1步
答案:(略)

第2步
1 答案:BCDF
2 答案:BC
3 答案:√
4 答案:(略)

第3步
1 答案:ABCD
2 答案:1)×2)√
3 答案:(略)

第4步
1 答案:BD
2 答案:BC
3 答案:CD
4 答案:B

第5步
1 答案:(略)
2 答案:B
3 答案:D

第6步
答案:1)×2)√ 3)√ 4)×

第7步
1 答案:B
2 答案:D
3 答案:AD
4 答案:1)√ 2)×3)√ 4)√

第8步
1 答案:AB
2 答案:ABC
3 答案:global
4 答案:1)√ 2)√

第9步
1 答案:ABCD
2答案:1)√2)√3)√4)√5)×6)√7)×8)×
3 答案:(略)

第10步
1 参考答案:AttributeError、OSError、IndexError、KeyError、NameError、TypeError和ValueError等。
2 答案:B
3 答案:1)√ 2)√ 3)√ 4)×5)×

第11步
1 答案:1)-2 2)-1
2答案:1)√2)√3)×4)√5)×

第12步
1 答案:(略)
2答案:1)×2)√3)√4)√5)×6)×7)√8)√

第13步
1 答案:(略)
2 答案:1)√ 2)×

第14步
1 答案:(略)
2 答案:(略)
3答案:1)√2)√3)√4)√5)×6)√7)√8)√

第15步
1 答案:(略)
2 答案:BCD
3答案:1)√2)√3)√4)√5)×6)×7)√8)√

第16步
1 答案:(略)
2 答案:(略)
3 答案:AB
4答案:1)√2)√3)×4)×

相关文章:

学Python的漫画漫步进阶 -- 第十六步

学Python的漫画漫步进阶 -- 第十六步 十六、多线程16.1 线程相关的知识16.1.1 进程16.1.2 线程16.1.3 主线程 16.2 线程模块——threading16.3 创建子线程16.3.1 自定义函数实现线程体16.3.2 自定义线程类实现线程体 16.4 线程管理16.4.1 等待线程结束16.4.2 线程停止 16.5 动动…...

MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点5:数据字典(Data Dictionary)

文章目录 MySQL 8.0 OCP (1Z0-908) 考点精析-架构考点5:数据字典(Data Dictionary)File-based Metadata Storage (基于文件的元数据存储)Transactional Data Dictionary (事务数据字典)Serialized Dictionary Informat…...

7分钟了解ChatGPT是如何运作的

ChatGPT是现在最为热门的聊天助手应用,它使用了一个大型语言模型(LLM),即GPT-3.5。它通过大量的文本数据进行训练,以理解和生成人类语言。但是,你是否有了解过ChatGPT是如何运作的吗? 下面我们就一起通过这个视频来一起…...

蓝桥杯打卡Day8

文章目录 C翻转矩阵幂 一、C翻转IO链接 本题思路:本题需要找出顺时针旋转和逆时针旋转的规律,然后就可以解决该问题。 矩阵顺时针90旋转规律:列号变为行号,(n-行号-1)变为列号 规律:a[i][j]b[j][n-i1]; 矩阵逆时针90旋转规律:行号变为列号&#xff0…...

React 学习笔记目录

学习使用的开发工具 编译器 VSCode 开发语言工具 TypeScript /JavaScript 重要程度分类 一般 这个程度的知识点主要是达到熟练掌握即可,不用太深入研究和学习。 重要 这个程度的知识点主要是达到熟练掌握,并且内部的原理切要熟记,因为会关…...

一起Talk Android吧(第五百五十一回:如何自定义SplashScreen)

文章目录 概念介绍实现方法修改启动页中的内容修改启动页显示时间修改启动面消失时的页面各位看官们大家好,上一回中咱们说的例子是"如何适配SplashScreen",本章回中介绍的例子是" 如何自定义SplashScreen"。闲话休提,言归正转,让我们一起Talk Android…...

PYTHON-模拟练习题目集合

🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由Aileen_0v0🧸 原创 CSDN首发🐒 如…...

UE5学习笔记(1)——从源码开始编译安装UE5

目录 0. 前期准备1. Git bash here2. 克隆官方源码。3. 选择安装分支4. 运行Setup.bat,下载依赖文件5. 运行GenerateProjectFiles.bat生成工程文件6. 生成完成,找到UE5.sln/UE4.sln7. 大功告成 0. 前期准备 0.1 在windows的话,建议装一个Git…...

DP读书:《openEuler操作系统》(二)操作系统的发展史

操作系统的发展历史 操作系统的发展历史手工操作时代批处理系统多道程序系统分时操作系统CTSSMULTICS的历史UNIX和Linux的历史Debian系列Red Hat系列 DOS和Windows的历史DOS的历史:Windows的历史: Android和iOS的历史Android:iOS:…...

SQL sever中相关查询

目录 一、简单查询 二、条件查询 三、别名查询 四、分组查询 五、排序查询 六、去重查询 七、分页查询 八、模糊查询 九、表连接查询 十、子查询 十一、嵌套查询 一、简单查询 简单查询是最基本的查询类型,用于从数据库中选择特定列或所有列的数据。 1…...

Java手写IO流和案例拓展

Java手写IO流和案例拓展 1. 手写IO流的必要性 在Java编程中,IO流是非常重要的概念。尽管Java已经提供了许多现成的IO类和方法,但是了解IO流的底层实现原理,能够手写IO流是非常有必要的。手写IO流可以帮助我们更深入地理解IO的工作原理&…...

Linux入门教程||Linux 文件与目录管理

我们知道Linux的目录结构为树状结构,最顶级的目录为根目录 /。 其他目录通过挂载可以将它们添加到树中,通过解除挂载可以移除它们。 在开始本教程前我们需要先知道什么是绝对路径与相对路径。 绝对路径: 路径的写法,由根目录 /…...

MyBatis获取参数值的两种方式#{}和${} 以及 获取参数值的各种情况

一、参数值的两种方式#{}和${} 在 MyBatis 中,可以使用两种方式来获取参数值:#{} 和 ${}。 1. #{}:这是 MyBatis 推荐使用的方式。在 SQL 语句中使用 #{},MyBatis 会自动将参数值进行预编译处理,防止 SQL 注入攻击&a…...

(手撕)数据结构--->堆

文章内容 目录 一:堆的相关概念与结构 二:堆的代码实现与重要接口代码讲解 让我们一起来学习:一种特殊的数据结构吧!!!! 一:堆的相关概念与结构 在前面我们已经简单的学习过了二叉树的链式存储结…...

[运维|数据库] MySQL 中的COLLATE在 PostgreSQL如何表示

在 PostgreSQL 中,字符集(collation)和排序规则(collation order)的概念与 MySQL 类似,但语法和用法略有不同。在 PostgreSQL 中,字符集和排序规则通常是数据库、表或列级别的设置,而…...

【Linux】tar 与 zip 命令

tar 命令 tar 本质上只是一个打包命令,可以将多个文件或者文件夹打包到一个 tar 文件中,结合其他的压缩程序再将打包后的档案文件压缩。 所以看到 .tar.gz, .tar.bz2, .tar.xz 等等文件其实是 tar 文件之后进行 Gzip, Bzip2, XZ 压缩之后的文件。 tar…...

VS2015+opencv 3.4.6开发环境

VS2015+opencv 3.4.6开发环境 一、安装包下载二、安装过程三、VS环境配置四、测试一、安装包下载 这里提供两种下载方法:   1. opencv官网   2. csdn资源下载 二、安装过程 2.1 下载opencv-3.4.6 安装包 2.2 双击开始安装,选择要安装目录,点击Extract。  2.3 等待解…...

[运维|数据库] 将mysql的null.unix_timestamp(now()) * 1000转为PostgreSQL的语法

在 PostgreSQL 中,您可以使用以下方式将 MySQL 中的 UNIX_TIMESTAMP 和 NOW() 函数的组合转换为等效的语法: EXTRACT(EPOCH FROM NOW()) * 1000在这个 PostgreSQL 表达式中: EXTRACT(EPOCH FROM NOW()) 获取当前时间戳的秒数。 2. * 1000 将…...

springboot使用filter增加全局traceId,方便日志查找

一&#xff1a;引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> 二&#xff1a;编写过滤器&#xff1a; package com.example.demo.filter;import or…...

面经学习三

目录 Java 与 C 的区别 面向对象和面向过程的区别 面向对象特性 Java的基本数据类型 深拷贝和浅拷贝 Java创建对象的几种方式 final, finally, finalize 的区别 Java 与 C 的区别 Java 是纯粹的面向对象语言&#xff0c;所有的对象都继承自 java.lang.Object&#xff0c…...

Open3D 点云配准——可视化匹配点对之间的连线

点云配准 一、算法原理1、概述2、主要函数二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、概述 可视化源点云和目标点云中匹配点对之间的连线,这对于点云配准,尤…...

io多路复用之poll的详细执行过程

1.结构体struct pollfd的定义 struct pollfd { int fd; /* 文件描述符 */ short events; /* 想要监视的事件&#xff08;input/output/priority&#xff09; */ short revents; /* 实际发生的事件&#xff08;返回的事件&#xff09; */ }; 2.定义po…...

网络安全深入学习第四课——热门框架漏洞(RCE— Log4j2远程代码执行)

文章目录 一、log4j2二、背景三、影响版本四、漏洞原理五、LDAP和JNDI是什么六、漏洞手工复现1、利用DNSlog来测试漏洞是否存在2、加载恶意文件Exploit.java&#xff0c;将其编译成class文件3、开启web服务4、在恶意文件Exploit.class所在的目录开启LDAP服务5、监听反弹shell的…...

大数据Flink(八十一):SQL 时区问题

文章目录 SQL 时区问题 ​​​​​​​一、SQL 时区解决的问题...

Input子系统 - Kernel驱动程序 - Android

Input子系统 - Kernel驱动程序 - Android 1、Input子系统相关定义1.1 代码位置1.2 input_dev结构体&#xff1a;表示输入设备1.3 input_handler结构体&#xff1a;struct input_handler - implements one of interfaces for input devices1.4 input_handle结构体&#xff1a;将…...

MySQL里的查看操作

文章目录 查看当前mysql有谁连接查看数据库或者表 查看当前mysql有谁连接 show processlist;查看数据库或者表 列出所有数据库&#xff1a; show databases;查看正在使用的数据库&#xff08;必须大写&#xff09;&#xff1a; SELECT DATABASE();列出数据库中的表&#xf…...

Vim的基础操作

前言 本文将向您介绍关于vim的基础操作 基础操作 在讲配置之前&#xff0c;我们可以新建一个文件 .vimrc&#xff0c;并用vim打开在里面输入set nu 先给界面加上行数&#xff0c;然后shift &#xff1b;输入wq退出 默认打开&#xff1a;命令模式 在命令模式中&#xff1a…...

十天学完基础数据结构-第一天(绪论)

1. 数据结构的研究内容 数据结构的研究主要包括以下核心内容和目标&#xff1a; 存储和组织数据&#xff1a;数据结构研究如何高效地存储和组织数据&#xff0c;以便于访问和操作。这包括了在内存或磁盘上的数据存储方式&#xff0c;如何将数据元素组织成有序或无序的集合&…...

神经网络 03(参数初始化)

一、参数初始化 对于某一个神经元来说&#xff0c;需要初始化的参数有两类&#xff1a;一类是权重W&#xff0c;还有一类是偏置b&#xff0c;偏置b初始化为0即可。而权重W的初始化比较重要&#xff0c;我们着重来介绍常见的初始化方式。 &#xff08;1&#xff09;随机初始化 …...

div设置圆角#前端

要在 div元素上设置圆角&#xff0c;您可以使用 CSS 的 border-radius 属性。 这个属性允许您指定元素的边角为圆角&#xff0c;可以将其应用于一个或多个边角。以下是一些示例代码&#xff1a;1.设置所有四个边角为圆角&#xff1a; div {border-radius: 10px; /* 设置所有四…...

做刀模网站/企业线上培训平台有哪些

原文链接&#xff1a;工程师男友如何反窃听&#xff1f;趣聊密码学入门科普 阿里妹导读&#xff1a;谁都不想在通信过程中被别人“窃取”小秘密。本文借助一对情侣与八卦女、猥琐男的斗智故事&#xff0c;为大家讲述科普密码学基础知识。既有料又有趣&#xff0c;深入浅出&…...

做门名片设计网站/google seo是什么

前言&#xff1a; js通过元素id获取元素及元素值的方法 document.getElementById("元素的id"); //找到该id元素的对象 document.getElementById("元素的id").value;的value值 下面就开始吧 一、客户端处理(即前端处理) //声明变量,用于保存异步传输对象XML…...

第一次做网站怎么样下手/怎么在百度上推广自己

下面介绍MySQL主从复制&#xff0c;读写分离&#xff0c;双主结构完整构建过程&#xff0c;不涉及过多理论&#xff0c;只有实验和配置的过程。Mysql主从复制(转载请注明出处&#xff0c;博文地址:)原理是master将改变记录到二进制日志(binary log),slave将master的binary log拷…...

工商注册公司名称核准/成都爱站网seo站长查询工具

CyclicBarrier 意思是&#xff1a;环形栅栏&#xff0c;通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后&#xff0c;CyclicBarrier可以被重用。我们暂且把这个状态就叫做barrier&#xff0c;当调用await()方法之后&…...

西安seo外包费用/惠州seo按天计费

1、vue2.0 响应式数据的原理 概述:Object.defineProperty() 递归数据劫持+订阅发布者模式 Vue2.0在初始化数据时,会给data中的属性使用Object.defineProperty重新定义所有属性,当页面取到对应属性时,会进行依赖收集(收集当前组件的watcher)如果属性发生变化会通知相关依…...

如何快速自己做网站/网络销售怎么聊客户

转载至&#xff1a;http://blog.csdn.net/denglxsc/article/details/51188444 在开发过程中对程序方法、类的描述不仅方便阅读、更能体现一个良好的编码习惯&#xff0c;但是自带的文档注释快捷键以及自动生成的注释总是不够完美&#xff0c;既然不完美&#xff0c;那么我们就…...