粉丝915获赞4647

在 python 编程里, flash 是 个重要概念。简单来说, flash 就 像给管道通一通,能让管道里的水数据马上流出来。在 python 的 输入输出操作中,默认是有缓冲区的。 缓冲区就像一个小仓库,程序产生的数据会先存到这里,等仓库满了或者满足特定条件,才会把数据一次性发送出去。 而 flash 的 作用就是强制把缓冲区里的数据立刻输出。就好比你在给朋友写信,写好的内容并不会马上寄出去,而是先放在一个盒子缓冲区里,等盒子装满了再一起寄走。 但有时候你需要写好一部分内容就马上寄给朋友,这时就可以用 flash 来实现。在 python 里,像文件操作、网络编程都会用到 flash。 在文件操作中,当你往文件里写数据时,数据会先进入缓存区。如果不调用 flash, 可能在程序结束前数据都不会写入文件。 例如以下代码, file equals open test dot txt w file dot round 如果不执行下面这行代码内容,可能不会及时写入文件。 file flash file close 在 网络编程中,当你通过套接字 socket 发送数据时,也会涉及缓冲区,使用 flash 能确保数据及时发送,避免因缓冲区的存在而导致对方接收数据延迟。 总结一下, flash 在 python 里主要用于强制刷新缓冲区,让数据及时输出。如果你希望数据能马上生效,就可以考虑使用 flash 行动。建议是在编辑文件操作或网络编程代码时,根据实际需求合理使用 flash, 确保数据能及时处理。

欢迎来到 nvidia q tile python 执行模型的深度解析。 q tile python 是 nvidia 推出的新一代 gpu 编程框架,它为 gpu 编程带来了全新的抽象层次。 在本系列视频中,我们将深入讲解 q tile 的 执行模型,帮助你理解代码是如何在 gpu 上运行的。 q tile 的 三大核心特性包括,第一, block 级并行,你可以显示指定网格和现成块的组织方式,获得对并行执行的精确控制。 第二, tile 抽象,以数据块为核心的高层抽象,让你无需关心底层现成管理的复杂细节。 第三,自动同步,系统会自动处理线程同步问题,你不再需要手动调用同步操作。理解执行模型是编写高效 gpu 程序的关键, 让我们开始这段学习之旅吧!现在让我们来一节理解 q tile 最核心的概念, block 和 tile 的 区别,这是理解 q tile 最关门键的念。请务必牢记, block 不 等于 tile, 让我们先看左边的 block 快 block 是 执行单元,它负责运行代码。你可以把 block 理解为一个工作组,它是多个现成的集合。 block 是 并行执行的基本单位。在网格中,有许多个 block 同时运行,一个 block 可以 处理多个不同形状的 tile。 再看右边的 tile 数据块, tile 是 数据单元,它代表内存中的数据片段。 tie 是 被 block 处理的数据。就像原材料一样,每个 tie 都有固定的形状,比如十六个元素或者十六乘十六的矩阵。 一个 block 可以 加载和处理多种形状的 tie, 它们的关系是 block。 处理 tie 就 像工人处理材料一样, block 是 执行者, tie 是 被处理的对象。记住这个核心概念, block 是 执行单元, tie 是 数据单元, 它们是完全不同的两个概念。接下来我们了解抽象机器模型中的 grid 和 block 组织方式。 q tile 内核由一个网格,也就是 grid 中的多个逻辑线段块 block 执行。首先看一维网格, 在一维网格中, block 按照线性方式排列,从 block 零、 block 一、 block 二一直到 block n, 这种方式适合处理一维数组数据。再看二维网格, block 按照矩阵方式组织有形和列的概念,比如 block 零零表示第一行第一列, block 一 二表示第二行第三列。这种方式非常适合处理图像和矩阵数据。 grid 还可以是三维的,就是多层二维网格堆叠在一起,适合处理体数据或三维张量。让我们看右边的代码,示意。启动一维网格时,使用 grid 等于八一, e 表示八个 block 在 一维上排列。 启动二维网格时,使用 grid 等于十六,十六, e 表示十六乘十六的网格,三维网格则是八八八。 在内核函数中,我们使用 c t div 函数来获取当前 block 的 锁引, c t 获取第一维的锁引, c t b e 获取第二维的锁引。记住三个关键要点, 第一, grid 定义了 block 的 组织方式,可以是一维、二维或三维。第二,所有 block 并行,执行相同的内核代码。第三,使用 ctb 函数获取当前 block 的 缩影位置。现在我们来了解执行空间的概念, 执行空间定义了代码可以在哪些环境中运行,对吧? q tile 有 三种不同的执行空间,第一种是 host code, 主机代码运行在 cpu 上,这是标准的 python 代码,可以使用 python 的 所有特性。 在 host code 中,你可以调用 c t dot kernel 装饰的内核函数,使用 c t dot launch 来启动 gpu 内核。 q pi 和 num pi 这些库都可以正常使用。第二种是 tile code, 运行在 gpu 上,但使用 tile 抽象层,这是 cq tile 的 核心,使用数据快的高层抽象。 在 tile code 中编辑 c t d kernel 内核代码和 f c d function 函数。注意 tile code 不 能直接访问县城,县城管理是隐式的。第三种是 sim code, 这是传统的 kuda 编程模型, 同样运行在 g p u 上,但与 tile code 是 完全不同的执行空间。 sim to code 可以 直接操作县城,使用 thread idx 和 block idx 这些传统 kuda 概念代码是如何从 host 到 tile 的 呢? 通过 ct 待 launch 函数, host code 调用 ct 待 launch 来启动 gpu 内核,然后控制转移到端口执行。让我们看底部的代码对比。 左边是 host code, 在 cpu 上准备数据,设置网格参数,然后调用 ct 待 launch 启动内核。 中间是 tile code, 使用 at c dot kernel 装饰器定义内核函数。在内核中使用 c dot bit 获取 block, 所引用 c dot load 加载数据块进行 tile 操作,最后用 c dot store 存储结果。 右边是传统的 simt code, c t s 编辑直接操作现成缩影。记住, q tile 的 tile code 和传统 q d 的 simt code 是 两种不同的编程模型,不要混淆它们。本节介绍 tile 函数,它是可以在 tile code 中调用的可复用函数。 tile 函数使用 f c t def function 装饰器来定义,这个装饰器有两个参数, host 控制是否可以从 host code 调用,默认是 false。 type 控制是否可以从 type code 调用,默认是 true。 让我们看右边的三种使用方式。第一种,仅在 type code 可用,直接使用 atct function 装置,不加任何参数。这种函数只能在 gpu 的 type code 中调用,不能在 cpu 的 host code 中使用。 第二种,在 host tile 都可用,使用 sct and function host tile true 这样定义的函数可以在 cpu 和 gpu 两边都调用,非常灵活。第三种,自动推断,这是推荐的方式。 对于简单的工具函数,你可以不使用装饰器。当这个未标注的函数被 tile 函数调用时,它会自动被加入到 tile 执行空间, 这个过程是递归的,调用链上的所有函数都会被自动推断。让我们看左边的完整视力, 这是神经网络的激活函数 relu 函数,没有使用装饰器,它是简单的工具函数 relu derivative 也没有标注。 leaky relu 调用了 relu 函数,也不需要标注, 只有入口函数 activation pipeline 使用了 app ct function 装饰器。当这个函数被内核调用时, 所有他依赖的函数,包括 leaky, relu, relu 和 relu derivative 都会被自动推断为可用。在内核函数 apply activation 中,我们直接调用 activation pipeline。 所有的激活函数都能正常工作,无需逐个标注, 记住最佳实践。对于核心逻辑函数显示,使用 fct 函数标注,提高代码可读性。对于简单的工具函数,让系统自动推断,保持代码简洁。本节介绍胎内核,它是 gpu 程序的入口点, 内核是 tile code 的 入口点,使用 sct kernel 装饰器定义 grid 中的每个 block 都会并行执行这个内核函数。注意内核不能直接调用,必须使用 ct 的 launch 函数来启动。 让我们看左边的基本内核视力,这是一个向量加法。内核定义,使用 at ct kernel 装饰器内核的执行流程分为四步,第一步,获取 block id, 使用 ct 点 bit 零获取当前 block 在 第一维的缩影,这个缩影叫做 p d。 第二步,加载数据 tile, 使用 ct 的 load 函数传入数组 a 指定缩影位置和形状,这里每个 block 加载十六个元素的 tile, 对 b 数组做同样的操作。第三步, tile 计算,直接对两个 tile 进行加法运算,这个操作会在多个县城上并行执行,但对程序员来说是透明的。 第四步,存储结果。使用 c t d store 函数将计算结果 tile 写回到数组 c 中。在 host 端,我们准备数据计算需要多少个 block, 设置 grid 参数,然后调用 c t d launch 启动内核。再看右边的二维 grid 视力,这是处理矩阵的场景。 内核函数使用 ct dip 并获取锁影, ct dip 一, 获取列锁影。加载二 d tile 时, index 参数是 roco, shape 是 十六,十六表示加载一个十六乘十六的矩阵块。启动时, grid 参数设置为 grid y, grid x e 表示一个二维网格有十六行,十六列,共两百五十六个 block。 记住内核执行的关键流程,第一步,获取 block id, 第二步,加载 tile, 第三步,进行计算。第四步,存储结果。 所有的 block 都在并行执行这个流程,这就是 gpu 的 强大之处。本节讲解 tile 支持的派放子集和对象模型。首先要明确一个核心限制, tile 中没有派放运行时, 这意味着只有文档中明确列举的发送特性才被支持。不要假设所有发送特性都可以使用。 让我们看左边支持的特性。第一类是控制流语句,你可以使用 if, if else。 条件语句可以使用 for i in range n 循环,可以使用 while 循环,还支持任意嵌套的控制流。 第二类是基本类型,支持 int, float 波这些标量类型以及 tile 类型,也就是从 c t 的 load 返回的数值。 第三类是函数调用,可以调用使用 s, c, t 的 方程装饰的函数,也可以调用自动推断的函数。第四类是内置操作,支持基本的算数运算,比如加减乘除。支持比较运算,比如大于小于等于。还支持逻辑运算,比如 and or not。 再看右边不支持的特性,这个列表很长,不支持 lambada 表达式异常处理,携程动态类型、特性反射和圆编程。不支持文件 i o 和大部分标准库 不能使用 print 函数镜调试,不支持字母串操作列表、推导式字典和集合 不能在 type 中定义新的类。注意, range 函数不支持赋不长,也不支持生成器和迭代器。现在看底部的不可变性规则,这非常重要,在 type 中创建的所有对象都是不可变的。 当你写 x 等于 x 加五时,实际上是创建了一个新对象,而不是修改原来的 x。 tiled 操作也是创建新的 tile, 不 会修改原 tile。 唯一的例外是作为内核参数传入的数据库是可以修改的。 你可以使用 ctden store 函数修改数据库的内容,这是唯一允许的可变操作。理解这些限制非常重要,它们是 q tile 能够高效翻译到 gpu 代码的基础。本节讲解 tile 并行性,这是 q tile 最强大的特性之一。 让我们看顶部的并行执行模型图示。假设我们有一个包含一百二十八个元素的 tile, 标记为一零,一二一三等等。 当 block 执行一个接受 tile 作为参数的函数时,它会自动将这些元素的计算并形化。看中间的箭头,每个元素会被自动射到一个线段上,一零分配给 thread 零一 one 分 配给 thread, 维一二分配给 thread 二,以此类推。 这个映射过程是隐式的,完全由系统自动完成。所有线程并行执行相同的操作,但处理不同的元素单指令。多线多线程的核心思想。看右边的代码示意。 我们定义了一个 process tile 函数,它接受一个 tile 作为参数。函数内部对 tile 进行乘法和加法运算, 这些运算看起来像是标量操作,但实际上会被自动并形化。在内核函数中,我们加载一个包含一百二十八个元素的 tile, 然后调用 process tile。 这个调用会触发自动并行执行。一百二十八个元素的计算会分配给多个县城,同时进行。 现在看底部的自动同步保证。这是 qu tile 的 另一个重要特性,除非另有说明。函数执行将在函数返回前完成。这意味着当一个 tile 操作返回时,所有的线程都已经完成了,它们的工作结果已经就绪。 让我们对比 q tile 和传统 coud。 在 q tile 中,你只需写 result 等于 tile a 加 tile b, 系统会自动处理所有的同步问题,无需显示调用任何同步函数。而在传统库德中,当你使用共享内存或者需要现成间通信时,必须显示调用 sync threads 函数来同步现成。 忘记同步会导致数据竞争和错误的结果。 q tile 的 核心优势就在这里,它要操作自动并行、自动同步,你无需手动管理现成和同步点。这大大简化了 gpu 编程的复杂度, 让你可以专注于算法本身。本节讲解常量性和常量切入,这是 q tile 的 重要优化特性。 某些功能需要在翻译时静态已知的参数,这些参数必须是常量对象。让我们看左上角,什么是常量表达式呢? 第一类是字面量对象,比如 x 等于四十二, y 等于三点一四,这些直接写在代码里的值都是常量。第二类是整数算数表达式,如果操作数都是字面量,结果也是常量,比如 a 等于十加二十,在编一时就能确定是三十。 第三类是从长量赋值的对象, tile size 等于十六是长量,那么 double 等于 tile size 乘二也是长量,值,为三十二。 第四类是全局长量,在编一或启动时定义的全局对象。现在看右上角的长量嵌入,这是一个强大的优化技术。如果内核参数被标记为长量嵌入, 那么参数的所有使用都像被字面值替换一样。每个不同的参数值都会生成独立的内核机器码。 常量参数的机器表示为零字节,不占用寄存器或内存。常量嵌入的优点是变 e 器可以进行更激进的优化,比如循环展开内联操作, 使用更少的寄存器提高性能。缺点是每个不同的值都需要翻译一次,会增加翻译时间。如果参数值的范围很大,会生成很多不同的内核核版本。 看中间的代码是例,我们使用 ct that constant 来标注参数。内核定义时, tile size 参数的类型标注为 ct const, 这是一个整数类型的常量嵌入参数。 scale factor 标志为 ct 的 constant float。 在 内核中, tile size 在 编辑时,一只编辑器可以对 ct 的 load 进行优化。 scale factor 也在编辑时,一只可以优化乘法运算。启动内核时,我们传入具体的值。十六和二点五 第一次调用会翻译并缓存这个组合。注意,如果使用不同的值,比如 tile size 等于三十二,会触发重新翻译,系统会为新的参数组合生成新的内核代码。 看底部的最佳实践,推荐使用常量迁入的场景,包括 tile 形状参数,因为形状必须在编辑时已知 循环边界。如果你希望变易器展开循环的话,避免使用常量切入的场景,包括频繁变化的参数,会导致大量重新变异,影响性能。 大范围的参数值会生成大量不同的内核版本,增加代码缓存大小。合理使用常量切入可以让你的 gpu 程序获得更好的性能。 最后一节,我们来总结 q tile 编程执行模型的关键要点和最佳实践。首先回顾关键要点。 第一点, block 和 tile 的 区别,这是最核心的概念。 block 是 执行单元,负责运行代码。 tile 是 数据单元,是被处理的数据,千万不要混淆它们。第二点,执行空间有三种不同的执行空间, host code 运行在 cpu 上, tile code 运行在 gpu 上,使用 tile 抽象 simtcode 是 传统的 code 编程模型,代码通过 ct launch 从 host 转移到 type 空间。 第三点,函数类型, kernel 装饰器定义内核函数,它是 grid 的 入口点。 seat function 装饰器定义 tile 函数用于封装可附用的逻辑, 未标注的函数会被自动推断加入执行空间,这是一个非常便利的特性。第四点,并行性, block 级并行是显示指定的,通过 grid 参数控制有多少个 block。 red 级并行是自动处理的,影视管理程序员无需关心它有操作,会自动并形化,并且自动同步, 无需手动调用同步函数。现在看推荐的做法,第一,使用常量嵌入标注 type 形状参数,因为形状必须在翻译时已知,使用 ct constant inter 可以 获得更好的优化。 第二,合理组织 grid 大 小,以匹配问题规模,根据数据大小和 type 大 小来计算需要多少个 block。 第三,利用 s c t 方程赋用代码,将复杂的逻辑分解为多个函数,提高代码的可读性和可维护性。第四,简单的工具函数让编程器自动推断,不需要逐个标注,保持代码简洁。 再看需要避免的做法,第一,不要混淆 block 和 tile 的 概念,它们是完全不同的东西,一个是执行单元,一个是数据单元。第二,不要在 tile code 中使用未支持的 python 特性, 记住, tile code 中没有 python 运行时只支持文档中列举的特性。第三,不要对频繁变化的参数使用长量嵌入, 这会导致大量重新翻译,反而降低性能。第四,不要传递别名数组给内合同一个数组传递多次会导致数据竞争和未定义行为。 总结一下, qtyl 牌坊提供了简洁优雅的 gpu 编程体验,它让你可以专注于算法本身,而不是底层的现成管理和同步细节。 通过 tile 抽象,你可以用接近 number 的 方式编写 gpu 代码,同时获得极致的性能。感谢观看本系列视频,希望你在 gpu 编程之旅中收获满满,编写出高效优雅的 q tile 程序。

pason 从零开始学第三章三点四字典及其常见操作接下来的话呢,就来学习第四个小节,字典及其常见操作。字典呢,是 python 当中一个非常灵活的键值对数据容器, 它就像我们现实中用的字典一样啊,就是不用按照顺序一页一页的去翻找,只要通过关键词就能够快速找到对应的一个解释 啊,那这个关键词呢,就相当于我们字典里面的见而直啊,就解释就是字典里面对应的直啊,这种查找效率是特别高的啊,这不管你是存储用户信息啊,配置参数,还是处理映涉关系,字典呢,都是非常好用的, 那学会运用字典就能够显著的提升关联数据的查询效率,规范数据存储的一个逻辑。 那我们首先就要知道什么是字典,字典呢是专门存储键值对的有序数字结构, 每一个键都是有它唯一的一个标志的,就像你字典里面的一个词条对吧,一个词条就会对应一个解释, 那字典里面的键呢,也对应一个值,而且这个值是非常的灵活的啊,就不管是数字字母串还是列表,甚至另一个字典,都能够作为值去进行存储。 那字典的定义格式呢,也很清晰啊,它就是使用大括号把键值对给它包裹起来,键和值之间使用冒号隔开,不同的键值对之间也就是不同的元素之间使用的是逗号隔开啊,就是你可以写成这样的一个格式, 那我们现在的话就来举一个实际的例子对吧?啊,如果说我们想要去存储一个用户的信息啊,那就可以使用字典来进行定义, 定义字典啊,可以存储用户信息啊,为什么要定义字典呢?因为同学们来看啊,如果按照我们之前我用列表,对吧? l i 啊,然后呢?哎,冰冰, 好,然后女,对吧?啊?再来一个,九十八、八十七九十六,好,那你看现在的话,这个冰冰你知道是姓名啊?女呢?你知道是性别,但是这些九十八、八十七、九十六,你能够知道是什么意思吗? 就是它可能是你的语文、数学、英语成绩,也有可能是 python、 java 啊,这个 mexico, 对 不对?是吧?就是你不知道这个成绩对应的到底是哪一个科目,就这种情况下存储起来,它的这个清晰度不够,对不对?就是可读性没有那么好。 那其实呢,我们就可以定义字典进行存储啊,能够规范数据的一个存储的,那你比如说我们可以怎么样呢?哎,就是这个冰冰,对吧?就是我的姓名,他对应的是冰冰, 这个就是一个数据,有这种对应关系,对吧?把它放到花框里面啊,那这个就是一个元素啊,就是他有我,或者说你改成中文也行,对吧?比如说这个是姓名啊,对应的是 冰冰这个值,就像你字典现实中用的字典,你通过这个关键字找到它对应的一个解释,是不是啊?就有这种对应关系啊? ok, 在 我们编程当中呢,叫它映涉关系啊, ok, 对 应关系其实就是映涉关系, 映射啊,其实就是对应的意思啊,就是一对应的,我的姓名对应的是冰冰啊,然后呢?我的性别啊,性别对应的是 女, ok 啊,然后语文成绩啊,或者说,哎, python 成绩,对吗?对应的是九十八啊,然后呢?这个啊, html 成绩啊,就对应的是八十七, 好,然后再来一个 my secret 啊,九十六, ok, 好, 那么现在的话呢,我们就定义好这样的一个字典了,对吧?如果这个字典你需要使用多次,就怎么样定义变量进行保存,对吧?我们可以去打印一下这个变量对应的值,以及它对应的数据类型 去运行,看一下怎么样,它打印出了对应的一个数据是没有问题的,是吧?然后类型呢?就是 dat 啊, dat 就是 我们 dictionary 的 一个简写啊, dictionary 翻译成中文就是字典的意思, 所以这一个就是字典的定义啊,那么在这一个字典当中呢,像姓名、性别、 python、 html 这些就是键, 而冰冰女,九十八,八十七,九十六,就是直啊, ok, 甚至我们其实也可以,就是直的话啊,我们之前讲了,对吧?他其实可以放任意数据类型啊, 就是直的话可以是任意数据类型,键的话不行啊, ok, 那 现在的话我就来一个直啊,比如说我可以来一个什么呢? 来个爱好,对吧?啊?就是爱好吧, ok, 爱好就来一个什么?来个列表啊,我可以是多个爱好,我可能不止一个爱好,对吧?这个时候我们可以用这个列表存储,比如说啊,爱好是写代码, ok 啊,然后呢?哎?唱歌,对吧?啊?追剧 ok, 追剧在,哎, 刷微博,刷抖音,对吧?好,那现在的话呢,我们就已经写好了,来运行看一下,看有没有问题啊,是没有问题的,对吧?所以它的值也是没有数据类型的一个限制的,那么现在的话呢,我们就已经啊成功的去创建了一个字典类型的变量, 那这里的话有两个重要的注意点要跟大家说一下啊,第一个的话呢,就是字典的键必须是唯一的,不能够重复, 就像字典里面不会有两个一模一样的词条一样,对吧?如果你写了两个重复的键名呢,那么后面的键值对是会覆盖掉前面的,我们可以来试一下啊,比如说我来一个字典, d i c 啊,等于 name, 冰冰,对吧?好。然后呢,再来一个 name 啊, 小明, ok, 你 看现在的话呢,就有两个键名是 name, 对 吧?两个值分别是冰冰和小明。现在的话,键名重复了,我们去打印一下这个字典,会发现后面的值它会覆盖掉前面的值, 这就好比说你变量定义是一样的道理啊,这怎么样呢?我定义了一个变量 name 对 吧?它对应的值是冰冰,好,然后呢,我又定义了这样的一个变量 name, 它对应的值是小名, ok, 那 么此时我再去打印这一个 name 变量的时候,使用的是不是后面的值啊?是不是?所以啊,就是同样的道理,如果你的键名重复啊,后面的值就会覆盖掉前面的, ok, 这是第一个啊,就是键名具备唯一性,不允许重复的,如果重复的话,他会啊,后面的键值对,会覆盖掉前面的啊。第二个的话呢,就是值啊,他没有唯一性的要求,不同的键 可以对应不同的值,而且值的类型是没有限制的,你想存什么类型的数值都可以啊,我们前面存的这一个列表是可以的啊,就是他的值数值类型是没有限制的啊。 ok, 那 么它的值也是可以重复的,你比如说我们现在,对吧?再来一个,就是来个什么呢? nick name 啊,就是昵称的意思,然后呢也是冰冰, ok 啊,现在我们去运行看一下怎么样,是不是就是 nick name 啊,和这个 name 是 一样的对不对啊?你看我就是这里也是用小名嘛 去运行,你看是没有问题的,对吧?值它是允许重复的啊,但是键它是具备唯一性的。 ok, 这个就是注意点。 好,接下来的话呢,我们重点来讲一下字典的常用操作啊,这可是用好多字典的关键啊。 ok, 那 首先的话呢,是啊,我们查找元素,也就是根据键找到对应的值, 这是字典当中最常用的操作啊,有两种方式, ok, 我 们一一的来看一下。第一种是 dict key 啊,就是 dict 就是 字典的意思, key 呢,就是键啊,就是直接通过键来取值啊,它的话呢,找到键就会返回对应的值,但是如果没有找到它是会报错的,那现在我们就来试一下啊,我就来这样的一个字典, 把它复制下来啊。 ok, 然后呢我们去找一下根据键名啊,比如说我要找我的拍审成绩,是不呢啊,那我就把键名放进去,然后再打印一下来运行,看一下怎么样,是不是就获取到我的拍审成绩,就是九十八, 对不对?就是根据键名找到对应的值啊,那如果键名不存在,比如说,哎,我要找这个语文成绩, ok, 现在的话,在我们的字典当中并不存在语文这样的一个键名是不呢?所以呢,它是会报错的啊,就找不到,它是会报错的啊, 找到了就返回对应的值,但是找不到会报错,所以这种方式呢,其实我们并不推荐啊,那我们推荐哪一种呢?推荐第二种就是使用 get 方法, 这是更安全的啊,更推荐的一种安全取值的方式啊,它的语法呢,是通过字典去调用 get 方法,里面有两个参数,一个是键,一个是默认值啊,如果哎,能够找到对应的键,就会返回键对应的值, 如果说没有找到的话呢,就返回我们设置的这个默认值,默认值是可以省略不写的,如果省略不写的话呢,没有找到键的时候,会默认返回个 non 而不会报错。 那现在的话,我们就同样的来试一下嘛,是吧啊,你像我 in four 点 get, ok, 找 python 啊,在我的字典当中存在 python 这样的一个键名,那么它就会返回对应的值,九十八,对不对啊?然后呢,我们再来找一下 这一个语文啊,你看我们上面这种方式啊,我找一个不存在的,它会报错,而现在使用 get 方法不会报错, 它这里没有找到,就默认返回个 non 啊,这个 non 就是 默认值啊,这个默认值呢,其实你可以自定义啊,比如说我想要返回一个什么不存在,是不是可以的啊?那我们怎么做呢?那我就来一个 in four 点 get 啊语文, 然后我设置一个默认值,比如说不存在该数据,对吧?键名不存在,就这样写,该键名不存在, ok, 那 它的一个搜索是怎么样的啊?就是找一下有没有有文件,如果有的话,就返回这个键对应的值,但是如果没有找到呢,会返回这个 默认值,你看是不是不存在?语文这个键名的时候,就返回我们设定的这个默认值啊,他就不会报错对不对?通过这种方式取值呢,就能够避免程序因为找不到键而崩溃啊。大家用字典去查值的时候,我们建议优先使用这个 get 方法。 好,那这个就是查询啊,然后我们再看添加或者修改元素啊,用这两个的话, 你要进行这两个操作的话啊,就是使用一个语法就能够搞定啊,就是同一个语法能够搞定这两种操作,非常的方便。 核心语法呢,就是啊,你先根据键找到对应的值,再重新的去给他赋值。那具体是添加还是修改呢,就要看这个键在字典当中是否存在啊,如果键已经存在,那么就执行这个语法啊,他就会修改 这个键对应的值,如果说这个键它不存在,那么就会在字典当中添加一个新的介值。对,那我们同样的可以来试一下,比如说我们来个 inf 啊,等于 an m 冰冰,好,然后呢? age 十八, ok, 现在我们怎么样呢?我要去操作一下,比如说,哎,我来个 in for age, 对 吧?先找到这个值啊,再怎么样给它重新赋值,比如说来一个二十八, 好,现在我们去 print 答案一下, in for, 你 看当这个键名存在的时候,对吧?在我的字典当中存在 a 指这个键名,它就会把对应的值修改成我现在给它的新值二十八, 原本的十八改成二十八了啊,这个就是键名存在啊,键名存在,那么就是修改键名存在,执行修改操作。 如果是一个不存在的键名呢?比如说啊,来一个 six 或者说 tail 啊,手机号码, 然后呢幺三零幺幺幺幺二二二来运行,看一下怎么样,会发现原本只有两个键值队,现在多了一个键值队,变成三个键值队了,对不对?这里为什么呀?因为这个键名啊,它找一下,找这个 tail 键, 发现 tail 键呢,它不存在,不存在就怎么样?就往这个字典里面添加这样的一个键值?对啊,就是新增, ok, 这个就是我们的添加或者修改啊,如果键名存在就是修改啊,键名不存在就是新增 ok, 就 添加 好。然后呢再来往下看,下一个就是删除元素。删除元素呢,有两种常用的方式,第一种是 pop 啊,它的话有两个参数,一个是 key 键的意思,一个是 default 默认值的意思,它是用来删除指定的箭头。对的 啊,那哎,直行之后就会删除指定键对应的键值,对,并且返回被删除的值啊,如果说指定的键不存在,就会返回我们设定的默认值,如果你没有设定默认值的话呢,是会报错的,那我们同样的来试一下呗, 还是这样的一个字典吧,把它复制过来啊,好,然后呢,我们删除一下,删除,比如说我删除一个存在的键啊,我删除年龄键,对吧? print 啊,就是 in four 点 pop, 把键放进去 h 啊,好,然后呢,我们去打印一下,它会有返回值,有一个结果返回啊,它会获得到一个值啊,就是这个 h 键对应的值,然后呢顺便把它们两个一起删掉了, 你看现在是不是获取到了对应的值,然后呢我们再去打印这个字典的时候呢,发现没有这样的一个键值,对了,看,没有,就是先找到对应的值啊,先找到对应的值啊,然后呢把键啊,把该键 和值都删除啊,那我们再去打印这个字典的时候,发现键和值就不见了,是吧?啊?这个就是存在的键,那如果是不存在的键呢?删除不存在的键, 来试一下 in four 点 pop, 比如说我要删除 tail 键,然后呢我们去 print 输出一下,怎么样?它会找不到?找不到就会报错嘛,是吧?代码在这一行代码就会报错啊,就没有办法往下执行了啊,这里直接报错就卡住了,程序就在这里崩溃了,不会继续往下执行, ok 啊,这个是默认情况下,我们没有设置默认值,它就会报错啊,那其实我可以给它设置一个默认值,比如说,哎,我就如果这个键名不存在,你就给我返回一个,该键不存在, 该键不存在。 ok, 来运行看一下,那就是键名如果存在啊,你比如说我们给他一个存在键名,他就会找到,对不对啊?然后呢并把这个键值对删除, 如果键名不存在,就会返回我设定的这个默认值,该键不存在,这样的话呢,程序他就不会崩溃,不会说没有办法继续往下运行,是吧?啊?所以 这个是破普方法啊,然后继续看下一种方式,就是 clear 方法啊。 clear 方法的话呢,就是用来清空字典里面所有的元素, ok? 它的语法很简单啊,就是通过字典去调用这个 clear 方法啊, 调用之后呢,这个字典就会变成一个空的字典,所有的箭头,对,都会清空掉,那我们同样的来试一下,比如说 inf 点 clear, 好让我们再去打一下音符啊,这个字典看里面是没有元素了的,对吧?他获取到的就是一个空的字典了啊,这个就是空字典 啊,这里面的所有的元素都被清空掉了,直接把你全部清空,对吧?但是仍然保留了这个字典,你还可以使用这个字典进行一些啊,添加呀,修改呀,删除啊这些操作,是不是啊?这个就是删除元素, 除了这些核心的操作呢?哎,字典它还有几个实用的操作,能够帮助我们获取字典里面所有的键,所有的值,以及所有的键值。对, 那第一个的话呢,就是 case 方法啊,调用它之后会返回字典里面所有的键。第二个是 value 方法,它会返回字典里面所有的值。 第三个是 items 方法,会返回字典里面所有的建筑队,每一个元素啊,每一个建筑队会以原组的形式存在,那我们就可以来试一下啊,我觉得我还是一个字典吧,对吧?我们来一个长一点的字典啊,就比如说来一个这个字典, ok 啊,然后现在怎么样呢? in for 点 case 啊,这个就是获取所有的键啊,来运行看一下怎么样,是不是就输出了这样的一个内容,看没有,就把所有的键名放到了这个特殊的类型 dict 杠 case 类型中, 是吧?啊?它是一个特殊的类型啊,不是源组,也不是列表, ok, 那 么我们来看姓名啊,性别,对吧? python, html 啊, my secret 爱好这些,是不是就是键名啊,全部都获取到了,对不对啊?如果你要获取所有的值,就是调用 values 的 方法, 那你看彬彬女啊,九十八,八十七,九十六,写代码,追剧,刷抖音是不是都是值啊? ok, 那 如果要获取键的对呢?就是调用 items 方法, ok 去运行,你看姓名,彬彬性别,女 python 九十八 html 八十七, my c q 九十六。哎,是不是就是一个个键值?对啊对吧,一个原组就是一个键值,对啊,这一个个数据,对吧?它一个元素就是一个键值。对,你看姓名是原组中的第一个元素啊,然后宾宾第二个元素就是键对应的值, 是不是啊?就是键值,对,它是原组的形式啊,这个是获取所有的键值,对,它是以原组的形式返回啊,就每一个键值,对, 是,就是一个原组啊,就是一个原组,原组中的第一个元素啊,原组中的第一个元素是键名啊,第二个元素呢,是对应的值啊。 ok, 好,那这三个函数呢,在我们后续学循环的时候是非常有用的啊,能够帮我们去便利字典里面的所有内容,就是取出每一个数据。 ok, 那 最后的话呢,我们再来总结一下字典的核心知识啊,帮大家巩固记忆。 首先字典呢,本质它是有序的键值,对,容器用 key value 定义值的话啊,就是键必须为一,而且不可变啊,就不能用列表啊,原组啊,就是不能用列表字典集合这种做啊,字典的键, 但是源组可以作为它的键名啊,因为源组不可变嘛,不可以修改啊,不可以修改的数据就可以作为字典的键名啊,可以修改的数据就不能作为字典的键名?直的话呢,是可以是任意类型的,没有限制。 其次的话呢,核心操作要记牢啊,查找优先使用 get 方法,安全不报错 啊。 dict 杠 key 这种方式找不到的话是会报错的,对吧?然后增改的话呢,使用啊,字典名,键名等于值的形式,就是通过 键名找到对应的值,再给它重新赋值,是吧?如果键名存在就是修改,如果不存在的话呢,就是添加啊。删除的话呢,用 pop key 啊,能够删除指定的键值。对, clear 方法是用来清空整个字典啊,把所有的元素都清空了就没有了,是不是 啊?想要获取所有的键,所有的值,所有的键值,对呢,就使用 keys, values 和 items 方法, ok, 那 字典的关键优势就在于,它能够通过键快速地查找值,不用像列表那样按照顺序去一个一个找,是不是 啊,便利,其实一个一个找去依次啊,按照顺序一个一个找的意思啊,那我们的字典是不需要的,对吧?所以他的查询效率非常的高啊,就是特别适合存储关联数据, 比如说存储用户的姓名、年龄、爱好这一些关联的信息,是吧?就是有映涉关系啊,有对应关系的数据,我们就可以使用字典啊,他的逻辑会更加的清晰,因为你一看键名就能够知道对应的值是什么。 所以呢,大家以后遇到存储关联数据,配置参数,或者说哎,处理应用关系的场景啊,就优先考虑使用字典。 那字典的用法虽然比这个列表和源组稍微复杂一些,但是呢,掌握之后能够大大提升你的一个编程效率, 所以大家课后可以自己试着用字典去存储自己的个人信息。哎,练一练这一些查找啊,让增加呀,对吧?修改呀、删除啊这些操作啊,那多动手就能够熟练掌握的。 ok, 那 这个就是我们第四个小节的内容。

在 python 编程里,函数就像生活中的万能工具。想象一下,你是个厨师,每次做蛋糕都要重复打鸡蛋、搅拌面粉等步骤,很麻烦。要是有个机器能一键完成这些步骤就轻松多了。 python 里的函数就是这样的。机器函数是一段有特定功能的代码块,能被多次调用。以经典的数学计算为例,每次计算两个数的和,都写一遍加法代码很繁琐, 这时定义一个函数就方便多了。比如 def add numbers a b return a plus b。 这里 add numbers 是 函数名, a 和 b 是 参数。函数功能是返回两数之和,之后要计算两数和,直接调用 add numbers 函数就行,像 result 等于 add number 三五,结果就是八。 再看个更实际的例子,在处理数据时,可能要对列表里的每个元素做某种转换,比如把列表里的每个数都平方。我们可以定义函数 def square x return x 乘乘二,然后用这个函数处理列表。 这就像有个专门处理物品的小作坊,进来的物品按规则加工后出去。函数还能提高代码的可读性和可维护性。 如果代码里有一大段重复代码,用函数替代后,代码简洁了,也更容易理解和修改。就像整理房间,把同类物品放到一个盒子里,找和整理都方便。 总之,函数是 python 编程的重要工具,学习函数要多定义和调用函数,把重复代码封装成函数,让代码更高效简洁。

pixon 零基础入门第三张三点七文件路径你知道怎么在 python 中使用别的文件吗?在 python 中,我们除了编辑自己的代码之外,常常还需要操作其他类型的文件,比如文本、文档、图片、音乐或视频等。 那么我们如何在 python 中打开其他的文件呢?我们在电脑中打开文件时,需要知道文件保存的位置,然后点击打开。 python 也同样需要知道我们要打开的文件存放在哪里。 这个问题就需要我们查找到文件的路径。文件的存放路径主要分为两种,绝对路径和相对路径。 先来看什么是绝对路径。在电脑中,文键通常储存在各个分区盘符之下,我们可以把文件想象成一片叶子,而盘符就像是它的根。绝对路径的意思就是从根开始,一步步查找到目标文件。 在这个过程中,我们需要依次经过一系列文件夹,这些文件夹在 python 中被称为目录,我们将这些目录按顺序串联起来, 每个目录之间用反斜杠分割。写完目录之后,我们要把目标文件的文件名补充到后面。需要注意的是,在 python 中,反斜杠符表示转一字符不能直接输出。 如果我们想在字母串中表示一个反斜杠,可以采用两种方式,一是把它作为特殊字母使用两个反斜杠输出来。二是在字母串开头加上 r, 表示取消掉反斜杠符的转移,字母正常输出反斜杠符。 在电脑中,我们也可以飞快地粘贴上文件路径,鼠标右击查找到目标文件,选择属性,就会弹出窗口,找到目标文件在电脑中的位置,直接复制目标文件的绝对路径,但是要记住还是需要加上目标文件的名字。除了绝对路径,还有相对路径。 绝对路径是从根目录开始查找目标文件,而相对路径则是基于当前文件所在的位置去查找目标文件。例如,我现在想要在 demo 文件中查找 test 文件,而我们要找的 test 文件与 demo 文件都在同一个名为 study 的 目录下,我们使用点反斜杠来表示当前所在的目录。 我们需要查找的是当前同一个目录下的 test 文件,那么我们就直接写上点反斜杠,加上目标文件的名字就可以了。 在同一个目录下点反斜杠可以省略,我们直接写上目标文件的名字也可以找到。那么如果不在同一个目录下呢?例如,现在我们想要查找的还是 test 文件,它是 demo 文件所处的当前文件上一集目录后目录下的文件, 我们使用两个点反斜杠表示上一级目录。找到了同属的共同目录之后,就能够按照顺序输出目标文件的相对路径,这样我们就能够成功查找到上一级目录下的文件。如果想要查找更上层的文件,则继续往前面加上点点反斜杠就行了。 在所属文件中使用相对路径查找目标文件,最重要的一点就是用清两个文件都同属于哪一个目录,下面是所处于文件的上几级目录, 上一级目录就写一个点点反斜杠,上两级目录就写两个点点反斜杠。相比于绝对路径,我更推荐大家使用相对路径,因为我们编辑代码后,通常需要将代码和相关文件一起打包给用户,如果使用绝对路径,用户存放文件的路径和你的不相同的话,程序就无法正确找到文件。 而使用相对路径的话,只要将整个文件夹打包,用户把整个文件打开,引用的位置还是正确的。这个视频我们主要学习了在 python 中如何查找文件的位置,具体的文件操作我们下期视频再见。

你知道 python 中的这个运算符吗?它有什么作用?这是一个在 python 三点八版本以上新增的运算符。由于它长得像倒过来的海象,被形象地称作海象运算符,官方名称为赋值表达式,语法结构为 variable, 冒号等于 expression。 variable 是 要赋值的变量名, expression 是 在计算的表达式。海象运算符的核心特性是它能在表达式内部完成变量的定义与赋值,这也是它和普通赋值语句最核心的区别。普通赋值语句仅能独立执行,无法嵌入到表达式中,而海象运算符支持边赋值边使用。 我们来看个案例,代码基于一个列表生成字典,字典需包含列表的总和、长度和均值。我们可以看到代码中计算了两次列表的总和与长度,而借助海象计算符,代码只需要计算一次,能有效避免重复计算,尤 其在条件判断、循环迭代、推导式等需要先计算。在使用的场景中合理运用海象计算符能让 python 代码更精炼、更简洁。

拍照从零开始学第三章三点一零模块的导入与使用大家好,我们在编程过程中通常需要使用一些已经编辑好的代码来实现特定功能,这时候我们就需要用到模块。我们来看到什么是模块, 模块就是一个包含拍照、定义和语句的点批外文件,用组织代码实现代码附用和功能隔离。比如我们会常用的 map 模块,就是包含各种需要用到数学相关的运算, 就比如计算平方根的 square 函数、开平方泡函数等。这些模块可能是拍藏自带的标准库模块,也可能是第三方开发者编辑的模块。当然我们自己也是可以编辑点 p、 y 文件的。 为什么要我们使用模块,是因为使用模块有很多好处,首先就是代码附用,不用重复编辑相同功能的代码,直接导入模块调用,节省开发时间。第二就是功能隔离, 将不同功能的代码拆分到不同模块,让程序更清晰,便于阅读和维护。最后就是管理复杂度,将程序功能拆成小模块,各模块接口清晰低藕合,既方便理解维护,也能避免修改一处引发局问题。 然后我们来学习怎么导入模块,导入模块有三种方式,第一直接导入模块,第二只导入模块中的指定函数类或变量。第三导入模块内所有成员。我们先来看第一个直接导入模块,我们使用用破了关键字,加上模块名,就可以将整个模块导入到当前的代码中。 现在我们来计算十六的平方根,首先由 input 导入 map, 再调用 x、 q、 r、 t 函数,再复制给 result 这里的模块名,函数名就像是告诉派藏这个 x q r t 函数是来自 map 模块的,这样派藏就能准确地找到并使用这个函数。最后我们看到终端计算出的值为四。 接下来我们来看到第二种导入模块的方式。我们想指定某个函数或者类,那么我们直接导入整个模块,就需要加载模块中无关的代码,在处理大型模块时就可以节省一点内存资源。 我们可以用 firm name port 的 方式来直接导入我们需要的内容,就比如只导入 map 模块中的 s q r t 函数,这样我们计算平方根就不要加上模块名的前缀了, 这样使用起来也就更加简洁了。如果我们需要用到多个函数,那么我们可以用逗号分隔。第三种就是导入模块中的所有内容。可以用 firm 模块名 in port 新号,它会直接调用模块内所有函数常量等,无需前缀。不过这种写法不推荐在实际开发中使用。第一就是导入模块内所有函数常量等,无需前缀,不过这种写法不推荐导入模块内所有函数长量等。第二,代码可读性变差。 然后我们学习为模块或导入的内容取名。我们在导入模块时,当有的模块名很长,我们用起来很不方便,这时我们可以给模块取一个别名,就比如这样,我导入 mark 模块,使用 a s 给 mark 取了 mark 的 别名,然后我们再用 mark。 调用 s q r t 函数时,我们只需要用 mark 这个别名就行了。下面我们深入理解模块的导入方式。 我们先来看直接导入整个模块,我们导入了 map 模块,这时我们要计算平方根,就要用到数学函数 s、 q r t 来计算。八十一的平方根下面的 map 表示数学中的圆周率 pi 的 值, 这里的 pi 是 个变量,最后我们看到结果,八十一的平方根就是九,下面这个就是圆周率的值。然后可能就有人会想到为什么圆周率的值直到七百九十三,这是因为受到浮点数存储精度和打印显示规则限制。然后我们来看到下面代码, 我们使用了 python 的 内置模块 run 的, run 的 模块适用于生成随机数,然后从 run 的 模块指定导入舍否函数,定义一个 num 的 列表,里面包含整数元素,再调用导入的舍否函数将 num 参数传入,最后运行后, num 的 列表的元素就被随机打乱了顺序。 我们再看到下面代码,我们还是导入 random 模块,我们还给 random 取了个别名。二、因为需要生成一个随机一到一百个数,所以我们就要调用 random 模块的 random 的 函数,它就是用来随机整数的,然后 random 中的参数填我们需要生成的范围。最后我们来看运行后,它生成了四十五 派脏模块的搜索遵循固定的优先级顺序,首先会查找当前脚本所在位置,这是优先级最高的环节,直接在执行派脚本的文件夹中解锁目标模块,若没有找到, 接着会便利派赠帕环境变量指定的目录,按该环境变量配置的路径顺序依次查找,之后会去派藏标准库,目录就是派藏安转时自带的标准库存储文件夹寻找,最后才会解锁第三方库安装目录,就比如塞帕克这文件夹存放屁帕安转的第三方库,若此环节还是没有找到模块,就会抛出异常。 我们通过今天的了解,知道了模块基本概念、导入方式和使用方法。最后希望大家课后多熟练这些知识,下节课我们将学习常用内置模块。

好,今天呢给大家分享一个啊, python 中一个非常的模块叫做待他 classes 啊,这个模块的话,它的主要作用呢是在面向对象的编程过程当中,减少那些不必要的代码啊,然后能够再生成一些魔术方法,比如说 initial, ipr, q 等。 好,我们现在先声明一个普通的类啊,用到任何的待他 classes 的 注解 啊,这里有两个属性,分别是内蒙黑,然后呢,接下来我们声明一个普通类,只需要在这个类的上面添加一个 at class 的 一个注解,下面声明两个对应的它的一个标注, 那我们同一时间发现两个不同的对象,上面这个打印的是不同类,它只能够打印这个内存的地址,而这个 pos 二,这个类它会自动生成 insert 签名,并且将 r, e, p, r 的 方式根据十来进行匹配。好,我们来看一下滤镜的效果。 ok, 这样的话就可以极大的化在面向对象的建模的过程当中的一些繁琐的操作。好,那么今天的分享就到这里。

今天教大家在 python 中部署 gpu 版本 tensor flow 的 方法。 cpu 版本的 tensor flow 安装非常简单,只需要在系统搜索栏输入 anaconda, 进入后输入 pp install tensor flow, 等待几分钟后,那么 cpu 版本就安装好了。 虽然 gpu 版本的 tensor flow 安装只需要在命令栏输入屁屁 install tensor flow gpu 就 可以了,但是你会发现用 gpu 运行 tensor flow 需要下载英伟达的库达 kit 包和库达 n n 包才可以运行,整个过程非常麻烦。首先我们要先查看自己的英伟达库达版本型号, 搜索栏输入 c n b, 然后在命令窗口输入 nvidia, 我 的 nvidia 库达版本是十二点零, 然后在网页上搜索 tensor flow, 查看我们应该安装的 tensor flow 的 gpu 版本型号。接着再在网页上搜索酷的 kit 和酷特 n n 的 官网。看着密密麻麻的下载链接后,我相信百分之九十九的新人已经被劝退了。 但是我们使用这个插件后,点击环境部署,点击 tensor flow gpu 版本套装,然后发现等待七八分钟就安装好了。 安装完后,在本机全局环境这一栏选择 tensor flow, 点击右键鼠标选择,测试 tensor flow gpu 是 否可用。测试发现自己的 tensor flow gpu 版本运行正常,你学会了吗?如果你还没有这个安装助手,请关注在评论区留言安装助手。

这一小节我们将来讲解标识符的规范。好,各位,欢迎回到大师编程,我是阿森老师,那么在上一小节中,我们有介绍到拍省中的两种注色,分别是单行和多行, 那么在日常的使用中呢,单行注适用的会比较多一点,那么大家可以在配色方案里面去把这个颜色配成自己喜欢的,这是一个非常中肯的建议啊。 然后这一小节我们将来讲解标识符的规范。那么在整个拍摄规范中呢,标识符规范是一个比较重要的点, 在讲解之前,我们先来介绍一下什么叫标识符,我们讲通俗一点,它就是名称,所以呢,这个标识符规范指的就是命令规范。 好,那么有哪些名字可以命名呢?呃,你像 python 中最基础的变量名,常量名 啊,叫常量名,对吧?然后再就是函数名以及类名啊,有很多种命名,那那么它们都要遵守哪些规则呢?我们一起看一下。 首先啊,我们讲 python 中的标识符是有一个有效的符设定的,它可以包含字母,数字,下划线, 那么对于字母来说呢,大小写均可,但是它是区分大小写的,也就是说现在给你一个变量叫做 t 啊,给你一个小写的 t, 它们两个是完全不一样的,搞清楚,并且呢, 呃, python 中其实是支持这个中文变量的啊啊,在那个 python 三之后是支持的,但是也不建议使用啊,不建议使用中文变量好吧,呃,这是有效制服, 那么呃,通过这个描述我们可以得知啊,这个 variable verb 下划线加 e 以及 print 下划线和漏都是符合要求的。好,那么第二个呢,叫做命名规则啊,这个命名规则,呃,说白了就是强制要求, 首先呢,在满足你是有效制服的情况下,你不能以数字开头,如果我们这里写上一个 points 三,那是有效的,但是呢,如果你写的是三 points, 那 它就是一个无效命名,会报错的 好,那么第二个强制性要求就是 python 的 关键字不能用做标识符。那么什么叫关键字呢?就比如说 if, for 和 well, 这么未来的语句结构中可能会出现的就叫关键字。那么 python 中的关键字有哪一些呢? 我们可以看一下,喏,这里说的是一个保留字,对吧?那么保留字它就是关键字加上了未来可能使用的关键字的一个集合体啊,那么有这么多,那么这些你都不能用, ok 啊,那么这个就是强制性的规则, 然后下方有一个命名,命名的就给你一个建议,对吧? 比方说它的第一个建议是什么呢?啊?你的变量名通常是用小写字母,如果有多个单词组成呢,那么单词之间可以用下划线来分割,比如说这个 snake case。 好, 第二个函数名,它和变量名是一模一样的,它基本上都要使用那个小写字母,单词之间呢,也是用下划线来分割,比如说这个计算总数的 calculator sum, 那么他就是同样的命名方式啊,所以这个变量名和函数名你可以一起记,对吧?呃,那么到了类名这里呢,就稍微有一点点区别了,他是使用的一个驼峰命名法哎,有这么一个命名法叫做驼峰命名法, 那为什么是驼峰呢?因为你发现它多个单词之间的首字母都是大写的,就像是骆驼一样的,对吧?啊,我们有那个起伏啊,所以叫驼峰命名法好,所以这个地方出现了一个 my class, 就是 我的类,对吧?类名,你看第一个单词 my 和第二个 class 手这么多大写,然后这个银行的账号啊,一个这样的类,对吧?也是 b 和 a 都大写了,那么这个就是类名,当什么类名是干什么用的啊?这个我们会在面向对象编程相关的章节去讲,这里我们只是稍微提一下。好,然后再就是常量啊, 常量呢,它的命名全部是大写,比方说我们要去表示一个最大的尺寸,我们就 max size, 中间仍就是用下划线给他分割,然后再就是当你去表示那个圆周率的时候啊,你可以用这个派 对吧,都是大写啊,为什么我们要讲圆周率?因为圆周率他是一个恒定不变的量。说,如果说啊,我要给他去定义成一个量啊,那就是常量,对吧?好,那么这个是命名约定啊,大家,呃,照这个去做总归是没问题的。 然后再下一个就是特殊的标识符了,就是说啊,在我们某些特定的场景下,我们可能要用到下划线和双下划线。 好,但是这个呢,我现在给你们讲太早了,好吧,呃,到时候我们用到的时候再去讲啊,你注意有这么个玩意啊,它也是影响我们命名的,叫特殊的标识符, ok 啊,那么其他建议的话呢?呃,就大家容易读懂的一些了,就比方说,哎,尽量选择具有描述性的名称,以提高代码的可读性, 就好比什么呢,我现在要表示那个苹果手机的价格,我写个 x 等于一,呃,就等于五千九对吧,或者说是 苹果手机的什么呢?单价等于五九零零啊,你不要看着说我这个 x 好 像简单多了,但是呢它的可读性远没有这个这么高,对吧?叫苹果手机的价格啊,所以建议大家是使用描述性的名称键名之一啊。 那么第二个避免使用单个字母作为标识符,除非在循环缩影或其他特定的情况下,也就是说像这种 a 呀, x 和 i 你 少去定义啊,当然什么时候要定义呢?我们到时候讲循环的时候会讲到这个单个字母作为标识符的情况啊, 所以这个尽量避免好吧。呃当然还一点是什么呢?就是我们在做测试的时候,就是我们在做学习的时候,如果仅仅只是为了表示一个数据,我随便去写个 x, 那 么你们就不要说,哎,老师 你不是说尽量避免吗?呃就不要再说了啊,因为我们只做学习好不好啊,我这里说的是工作中啊,尽量避免 ok 啊。那么最后一点的话呢,就是一个比较主观的内容了,就尽量使用一致的命名约定啊,有助于代码风格的统一。 所以说你如果带个团队啊,大家命名方式都差不多,那么你整合出来的项目就非常的优雅对吧?好,那么这个呢是有关于标示符的规范的一个描述,那么这里我们做一些小小的测试吧。 呃,稍等一下啊,我打开那个界面,好 在这个位置呢,我们来写一下所谓的不满足强制性要求的啊,就是不符合 强制性要求的。好,那我们之前在讲强制性要求的时候给它归类,为什么呀?就就是那个命名规则,对吧?好,你看,当我去写一个 word 这个单词,对吧?等于一是没问题的。好,那么我写上一个 print hello, 好,它也是没问题的,对吧?好,那么如果说我一旦没有满足这个强制性要求啊,重点是什么呢?不能以数字开头啊,那我这里偏偏要以数字开头,你看啊, 我先把这个数写这里,没问题,对吧?然后把这个数字写这里呢?哎,你发现报错了啊,然后关键字也不能作为标识符啊,就比如说那个 if, 我 作为标识符,哎,没用,对不对?好,我用那个 well 呢, 也没用好,所以这是关键字啊。当然,如果说我们违反的命名约定啊,呃,就比如说它让我们在变量命名的时候尽量用到那些。 呃,小写加下划线给它连上。那如果不照这个要求做啊,我就要写上一个 snake case, 好, 报错没有? 事实上呢,它是没有报错的,对吧?它是没有报错的,但是它说了一个什么呀?叫做 p e p 八 w 三九幺,什么什么东西,对不对?好,所以它就是一个警告啊, p e p 八,这个就是 python 的 规范啊,到时候我们会讲到啊,你只了解它是一个 python 规范,那么这里报了警告就证明你不满足它的要求,你给它换成什么呢? snake case 保存一下,好给它回一下啊,这个是什么呀?第五行啊,那个 file 我 看一下啊。呃,第五行,这不是它不满足,对吧? 好,这个就没了,对不对? ok 啊,然后我给它换成那个 snake 的 一个 case, 等于五好。哎,它没有提示啊啊?给了提示,这是一个 ai 操作啊。 啊,没什么毛病啊。他没有没有给提示啊,但这个不要紧,但你肯定是一个错误的。好,我写上一个中文啊,等于我啊,他这个就给了提示。叫什么?叫飞飞飞,什么制服,对不对?好, 行吧。呃,那么建议大家呢,就尽量按照我的要求去做就 ok 了,好不好?行吧,那我们这一节到这里就停下来。

今天跟大家分享的是在 python 中部署 gpu 版本的 uno 视觉检测模型的方法。部署 cpu 版本的 uno 非常简单,我们只需要输入 ppp 引导 u ultralitex 就 可以了。但是众所周知,视频检测训练模型用 gpu 跑同样伦数的数据集可能只需要十几分钟,而用 cpu 训练可能要跑到猴年马月, 所以我们要部署 gpu 版本的优漏。 gpu 版本的优漏安装非常复杂,而且容易出错,我一般都是用插件一键安装,十分的快捷,还没有插件的宝子们扣六六六即可。

拍蒜中的类和对象到底是什么?简单来说,类是抽象的概念,而对象则是类的具体实力。可以理解为类是一个抽象的模具,他提前定义好了形状、大小等基本属性,这个模具是固定不变的,能用它做出无数个成品,而对象就是依靠这个模具制作出来的成品, 每个成品既继承了模具的核心特征,又拥有自身专属的属性和行为。接下来我们来看看案例,类通过 class 关键自定义,后面跟着的 cat 是 类名。接下来这段代码叫抽象方法,双向划线就是它的身份标识。通过抽象方法给类创建属性,其中 self 参数表示对象自身,用来绑定属性和对象。 抽象方法中 self 后的参数是创建时需传入的内容,通过 self 点属性名为传递过来的变量赋值,这样类的属性和实力化对象就绑定好了。类中还可以定义其他方法,这些方法与普通函数的定义方式类似。至此,一个 cat 类就创建完成了。 接下来创建实力对象,通过类名加括号调用类的抽象方法传入具体参数,就能创建出类的实力对象。用同样的方法可以创建多个对象。最后通过对象名、点属性名或方法名就能访问对象中定义好的属性和方法啦。

上次课我们一起学习了 python 自带的开发环境 ide 的 使用方法,我们了解到 ide 有 两种工作模式,交互模式和文件模式。 那么这次课我们一起来学习一下 python 的 基础知识。 首先我们先复习一下 python 的 输入语句和输出语句, print 的 语句就是将括号里的内容在屏幕上显示出来,我们看几个实力,第一个呢, print 一 就是将数值一输出, 这个呢是将字母 a 输出,这个是将一和二的和这个表达式的值输出,如果有多项输出的话,中间呢可以用逗号隔开。下面我们看一下输入语句。 import 输入语句的功能呢是程序在运行过程当中,如果需要用户输入数据的时候,我们可以使用 input 语句。下面我们通过一个具体的案例来看一下如何使用 input 语句。 我们在 idle 的 文件模式下写一个代码,这个代码的功能呢是知道正方形的边长来计算正方形的周长, 我们将正方形边长的值放到 a 当中,我们用 l 来代表正方形的周长,所以 l 应该就等于边长乘以四,然后输出 有多个部分输出的话中间用逗号隔开。 代码写好了以后,要点击文件菜单里面的保存, 将这个文件保存到我们的桌面,给这个文件取一个文件名,计算正方形的周长,然后通过文件菜单里面的打开命令,我们可以打开电脑上存在的 py 文件, 然后再去点击运行菜单里边的运行命令,就可以运行刚才打开的文件。这个程序的功能啊,是计算边长为三的正方形的周长, 程序中边长 a 的 值是程序员设定好的,值为三,所以呢,这个程序只能够计算边长为三的正方形的周长,那如果我们想要计算任意边长正方形的周长,那么这个程序该如何修改呢? 我们是需要将这个边长的值啊,从长量三变成一个变量,而且这个值由用户在运行程序时输入。 ok, 我 们来修改一下代码,需要将边长的值从长量三把它改成一个变量,而且这个值呢是由用户来输入,所以我们需要使用 input 函数,在括号里边,我们可以通过字母串来改出提示性的字母, 那这一行代码在执行的时候就会提示用户输入正方形编程的值,然后复制给变量 a, 然后再计算出 l 的 值。代码编辑好了以后,我们点击文件菜单里面的保存, 其实这个保存呢,有快捷键,就是 control 加 s, 这样可以提高我们编程的效率。然后去点击 运行菜单里面的这个运行命令,运行命令呢,也可以按键盘上的 f 键,这也是运行的快捷键。我们看一下运行的结果,果然程序在运行过程当中要求我们来输入正方形变成了值,我们输入一个三,然后按回车, 哎,这个地方大家看一下说这个正方形的周长是三三三三出问题了,是不是?哎,很奇怪啊,我们再变形一次, 四四四四四,这不是我们想要的结果,对吧?那为什么呢?因为啊, import 它接收的这个值呢是字母串 而不是数值型,所以这个地方收集到的这个数据啊,是一个函数型数据,函数型数据参加这个数值运算的时候,他只是简单的把这个函数型数据重复四次,所以你输入的三,他这个变长的值就是四个三,输入的四,这个变长的值呢,就是四个四,很明显不符合我们的要求。 i e t 函数就是将你这个输入的值转变成整数来参与运算,如果这个变长的值是小数的话,那么就把它改成这个 float 浮点数,浮点型就是小数,好,我们修改一下,然后点击 ctrl s 保存代码,然后点击 f 五运行代码,输入正方形,变长的值是三按回车,它就是十二点零。好,我们再测试一个数据, 比如说它的变长的值是五 按回车,那么正反方向走上去就是二十点零,为什么后面多了一个点零呢?因为这个地方呢,它用的是一个 float 类型, float 类型呢是浮点数,就是带小数的,那如果是整数的话,那么就刚才说过,就把它改成 i n t 整数,我们按 ctrl s, 然后 按 f 五运行一下,如果输入五显示的就是二十,这就是输入语句 import。 使用方法, 长量和变量。在刚才这个程序当中,我们知道计算正方形周长的公式,周长等于四倍的边长,在这个公式当中,边长 a 是 可以变化的量,我们称之为变量 数字。四在程序运行过程当中是保持不变的量,我们称之为常量。计算机在处理数据时,首先要将数据调入到内存当中,然后才能进行各种操作。 变量是为了存放掉入的数据,在内存中开辟的一个存储单元,然后用一个标签指向这个存储单元,这个标签就是变量名。存储空间中存放的数据就称为变量的值,比如说 a 等于三, 意思就是将三这个数值存放到内存当中的这个空间,然后标签 a 指向这个空间, a 就 称为变量名,三就称为变量的值。那么这个变量 c 呢? 同样一个存储单元里边存放的值也是三,他用另外一个标签 c 来指向这个存储单元,所以啊, a 和 c 指向的是同一个地方,它们的值也是相同的,都是三。 而变量 b 它存放的值呢,是四。用标签 b 来指向这个存储单元,所以变量 b 的 值是等于四。 那么这个标签的命名规则啊,就是变量名的命名规则有下面三条,以后大家在写程序的时候一定要注意变量名,要写合法的变量名,如果你写的这个变量名不合法,程序是会报错的。 第一条规则是变量名是由字母、数字、下划线组成,并且呢是以字母或者下划线开头,不能以数字开头,所以这个 a 三 name 下划线,一下划线 name 包括单纯的这个下划线,它都是合法的变量名,而这个三 a 呢,是不合法的变量名。 第二条规则是区分大小写,大写的 a 和小写的 a, 它代表的是不同的变量。第三个就是变量名啊,不能使用 python 自己的关键字, 每一种高级语言都有自己定义过的关键字,比如我们 python 语言里面的一个 print, 包括刚才我们学的这个 import, 包括 if, else 等等,这些不能作为变量名。 下面我们来通过这个 i、 d、 l、 e 来简单的验证一下,比如说 我将三这个值赋给变量 a, 我 将三这个值复制复制给变量 c, 我 们通过 print 的 语句来验证一下 a 和 c 是 否相等 啊,输出的值是处,这说明变量 a 和变量 c 的 值是一样的,包括我用这个 id 查看一下变量 a, 我 用 id 查看一下变量 c, 这 id 的 功能呢,就是显示变量在内存当中的一个地址,大家看一下,这两个地址的值是一样的。这个变量 a 和变量 c 啊,其实是指向同一个存储空间,这个存储空间的编号是一样的。 piecing 常用的数据类型,在刚才计算正方形周长的这个程序当中,我们了解到 piecing 是 有不同的数据类型, 常见的数据类型呢,有下面这几种,整形就是整数。复变型就是小数字母型,是放在引号当中的数据,这个引号可以是单引号、双引号、三引号、 逻辑型数据。逻辑型数据的值呢,有处和 false 两个,比如说一大于二,这个表达式的值呢,它的一个值就是逻辑型数据 false。 同时啊,我们可以通过 int 函数、 float 函数和 str 函数进行数据类型的转换。下面我们通过 idele 给大家来演示一下不同数据类型之间有什么特征,以及转换函数是如何使用的。 一,它是一个整型数据,一点二是一个负点型数据,比如说一加一点二,它的值也是一个负点型数据。 那么函数型数据是放在引号里面的,这是函数型数据。而逻辑型数据,比如说一大于二,这个表达的值呢是 false, 这是一个逻辑型数据的值,可以通过 int 将函数型数据一、二、三转化为数值型数据。 可以使用 f、 a、 l、 t 将 字母型数据转化为浮体型数值,也可以通过 str 将数值型数据转化为字母。这就是 python 的 常用的数据类型 运算符和表达式。 python 为了进行数据运算,提供了大量的运算符,数值运算符,关系运算符, 还有一种叫逻辑运算符。以后我们再学数值运算符呢,有加减乘除乘方整除取于关系运算符,有大于小于、大于等于、小于等于不等于等于。 大家注意一下这些运算符的书写方法,下面我们通过 idle 来演示一下这些运算符的使用方法和使用格式。加 减乘 除二除一,二点零乘方二的三、四方 正除五,正除二就是五除以二。商的整数部分是二,取余就是五 除以二的余数是多少。这些呢就是数值运算符。下面看一下关系运算符, 关系运算符的值呢是处或者 false, 二大于一是处二小于一。 false, 二大于等于一,处二小于等于一。 false, 二不等于一,应该是处二等于一是 false。 这就是关系运算符的使用方法。 赋值语句,我们在计算正方形周长的这个程序里边,计算公式呢是边长乘以四, 是正方形的周长。那么怎么样把这个边长乘以四的这个值传递给这个周长 l 的 呢?是通过赋值号,赋值号就是我们数学里边这个等于符号,赋值号就可以实现把赋值号右边的这个值传递给赋值号左边的变量。 好,下面我们就来看一下这个赋值语句的使用方法,第一个 将数值一复制给变量 a, 第二个可以将变量 a 的 值复制给变量 b。 第三个是将变量 a 的 值加一,然后复制给变量 c。 这个使用格式大家注意一下,赋值号的左边是两个变量,赋值号的右边呢,是两个值,大家注意下对应关系,它的作用呢是将数值一复制给 a, 数值二复制给 b。 同样的道理,如果是三个变量的话,那么要注意一下对应关系, 同样可以将两个变量的值同时复制给左边的两个变量。这条复制语句的作用是将变量 a 的 值加一,然后复制给变量 a, 它的效果就是让变量 a 的 值增一。和这条语句相同的效果呢?有下面这个书写格式, a 加等于一,这个赋值语句的作用是等同于 a 等于 a 加一,但是呢,它的效率要比上面这条语句的效率要高。注意一下它的一个书写格式, a 乘等于二,就相当于 a 等于 a 乘二。 通过上面这些赋值语句的使用格式,我们注意到赋值号的左侧必须是变量,可以是一个变量,也可以是多个变量,它不能是表达式。赋值号的右侧可以是常量、数值性常量,也可以是字母性常量,可以是变量, 也可以是表达式。下面我们通过 ide 来演示一下赋值语句的使用, 给变量 a 复制一个一,我们输出 a 的 值就是一,我们可以把 a 的 值复制给 b, 那 么我输出 b, b 的 值肯定也是 a, 如果我让 a 的 值加一,然后复制给了 c, 所以 c 的 值就变成了二, 同时我们可以给两个变量同时复制,将二和三复制给 a 和 b, 那 么 a 就 等于二, b 就 应该等于三。 c 和 d, 那 它的值等于 a 和 b, 所以 c 的 值应该是等于二, d 的 值应该是等于三,那么 a 等于 a 加一,就是让 a 的 值增一。 a 刚才等于二嘛,现在增一就变成了三。 a 加等于一,那么 a 的 值应该等于几了, a 的 值就应该等于四了。刚才 a 的 值等于三嘛。 所以 a 加等于一的作用就等于 a 等于 a 加一, a 乘等于二, 那么 a 的 值应该等于几啦?等于八。这就是赋值语句的使用方法。

这节课我们来学习 python 里常见的数据容器, list, set 端口 get。 现在看 list 比较列表,它用的是中括号元素,直接用逗号隔开,而且它不限制数据类型,我们可以多写一点。 再来一个双引号的。 python 在 python 里,单引号、双引号以及三引号都表示,这不串来把它打印一下 它的类型以及它的长度类型。 list 长度是六,而且从打印结果也可以看出来,它是有下标的,也就是有顺序的,而且支持重复内容。我们学这四种数据容器,其实都是学同一套操作, c r u d 增删改差。那我们先来看添加列表是有顺序的嘛,所以最自然的添加方式就是追加元素,当然追加元素只在有顺序的容器里才成立, 等会儿讲到 set, 你 就会发现它连顺序都没有,就不存在追加的问题。比如我们用了 print 在 后面加一个 java, 既然有顺序,那就还可以在指定下标插入元素, 用 insert 在 下标一的位置插入 java 来打印看一下,最后面就多了一个 java, 下标一的位置也多了一个 java, 有 添加就有删除。我们可以用 pop 弹出最后一个元素, 他会把弹出的元素返回,可以打印一下弹出的结果,再打印一下 l, 可以 看到最后一个加 y 被弹出来了,当然也可以给他传下标, 弹出指定的元素,比如我们弹出倒数第二个派生就被弹出来了。除此之外,还可以根据内容删除数据,比如我们删除 abc, 也打印一下吧,他没有返回删除的元素,所以打印出来是浪。既然有下标,当然也能按位置删,比如我删除缩影一的元素, d l 是 派生的关键字。再来看 这个,加 y 也没了。然后再来看修改,比如把下标零改成 g s, 没问题吧?查就很简单了,用下标取值就好了。 或者使用 index 查询某个元素的下标,以及用 for 循环便利所有元素。上节课我们说过, for 循环支持便利训练,所谓训练就是可以被拆分的元素,比如 str, list 等会儿要讲的 set, apple 以及 dick, 当然还有一些可替代对象也能便利。 这些以后再说。或者你去看拍摄基础片,里面有详细讲解来跑一下,全都被打印出来了。 再来看 set, 也就是集合,再用大括号表示,无需且不重复。现在我们创建一个集合,随便写点重复的元素,把它打印一下,还有它的类型。可以看到,我们写了两个 a, 但实际上只存了一个,而且是没有顺序的。 我们写的是 a 在 前面,打印出来是 b 在 前面,内心也是 set, 由于它没有顺序,所以也就没有追加方法。给来试一下 app 就 报错了,要往集合里添加数据,它提供了一个 app 方法,然后还有人目方法 以及 pop 方法。由于没有顺序,所以它的 pop 方法就不能传下标了,默认会随机弹出一个元素。所有和下标相关的操作几何都做不了,包括前面讲的按下标做了修改,查询以及插入都做不了,但可以循环,因为它也是可拆分的训练。