python核心技术
文章平均质量分 93
python核心技术
_Rye_
左手代码右手诗
一行代码一行诗
展开
-
32 | 答疑(三):如何选择合适的异常处理方式?
很明显,这种认知是错误的。到最后,万分无奈的情况下,几个工程师专门立项,花了三个多月时间,重写了这一模块的代码,才解决了这个问题。通常来说,我们会在类的开头、函数的开头或者是某一个功能块的开头加上一段描述性的注释,来说明这段代码的功能,并指明所有的输入和输出。另外,必须提醒一点,如果在写好之后修改了代码,那么代码对应的注释一定也要做出相应的修改,不然很容易造成“文不对题”的现象,给别人也给你自己带来困扰。比方说,一个模块的功能是对输入进行检测,如果输入不合法,则弹出对话框进行提示,并终止程序。原创 2023-11-27 09:45:50 · 849 阅读 · 0 评论 -
31 | pdb & cProfile:调试和性能分析的法宝
这节课,我们一起学习了 Python 中常用的调试工具 pdb,和经典的性能分析工具 cProfile。pdb 为 Python 程序提供了一种通用的、交互式的高效率调试方案;而 cProfile 则是为开发者提供了每个代码块执行效率的详细分析,有助于我们对程序的优化与提高。关于它们的更多用法,可以通过它们的官方文档进行实践,都不太难,熟能生巧。原创 2023-11-26 20:19:32 · 768 阅读 · 0 评论 -
30 | 真的有必要写单元测试吗?
单元测试,通俗易懂地讲,就是编写测试来验证某一个模块的功能正确性,一般会指定输入,验证输出是否符合预期。实际生产环境中,我们会对每一个模块的所有可能输入值进行测试。这样虽然显得繁琐,增加了额外的工作量,但是能够大大提高代码质量,减小 bug 发生的可能性,也更方便系统的维护。说起单元测试,就不得不提Python unittest 库,它提供了我们需要的大多数工具。# 将要被测试的排序函数# 编写子类继承unittest.TestCase# 以test开头的函数将会被测试sort(arr)原创 2023-11-26 19:00:50 · 869 阅读 · 0 评论 -
29 | 巧用上下文管理器和With语句精简代码
在任何一门编程语言中,文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,我们必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻者使得系统处理缓慢,重则会使系统崩溃。这就是一个典型的资源泄露的例子。因为程序中同时打开了太多的文件,占据了太多的资源,造成系统崩溃。为了解决这个问题,不同的编程语言都引入了不同的机制。而在 Python 中,对应的解决方式便是上下文管理器(context manager)。原创 2023-11-26 11:45:13 · 804 阅读 · 0 评论 -
28 | 如何合理利用assert?
Python 的 assert 语句,可以说是一个 debug 的好工具,主要用于测试一个条件是否满足。如果测试的条件满足,则什么也不做,相当于执行了 pass 语句;如果测试条件不满足,便会抛出异常 AssertionError,并返回具体的错误信息(optional)。这里的__debug__是一个常数。如果 Python 程序执行时附带了-O这个选项,比如Python test.py -O,那么程序中所有的 assert 语句都会失效,常数__debug__便为 False;原创 2023-11-26 10:08:44 · 850 阅读 · 0 评论 -
27 | 学会合理分解代码,提高代码可读性
今天这节课,我们简单讲述了如何提高 Python 代码的可读性,主要介绍了 PEP 8 规范,并通过实例的说明和改造,清楚如何对 Python 程序进行可读性优化。原创 2023-11-26 09:44:47 · 807 阅读 · 0 评论 -
26 | 活都来不及干了,还有空注意代码风格?!
学到这里,相信你对代码风格的重要性有了全新的认识。代码风格之所以重要,是因为它关乎阅读者的体验、编程者的体验和执行代码的机器体验。当然,仅仅意识到代码风格重要,是远远不够的。我还具体分享了一些自动化代码风格检查的切实方法,比如强制代码评审和强制静态或者动态 linter。总之还是那句话,我们强调编程规范,最终一定是为了提高开发效率,而不是做额外功。原创 2023-11-25 10:41:01 · 889 阅读 · 0 评论 -
25 | 答疑(二):GIL与多线程是什么关系呢?
而 Python 中的多线程,是指多个线程交替执行,造成一个“伪并行”的结果,但是具体到某一时刻,仍然只有 1 个线程在运行,并不是真正的多线程并行。这里所谓的 CPU 密集型任务,是指会消耗大量 CPU 资源的任务,比如求 1 到 100000000 的乘积,或者是把一段很长的文字编码后又解码等等。我们还是来看 x,虽然它是无限嵌套的列表,但 x 的 top level 只有 2 个元素组成,第一个元素为 1,第二个元素为指向自身的列表,因此 len(x) 返回 2。原创 2023-11-25 10:37:15 · 792 阅读 · 0 评论 -
24 | 带你解析 Python 垃圾回收机制
今天这节课,我们深入了解了 Python 的垃圾回收机制,主要强调下面这几点:1. 垃圾回收是 Python 自带的机制,用于自动释放不会再用到的内存空间;2. 引用计数是其中最简单的实现,不过切记,这只是充分非必要条件,因为循环引用需要通过不可达判定,来确定是否可以回收;3. Python 的自动回收算法包括标记清除和分代收集,主要针对的是循环引用的垃圾收集;4. 调试内存泄漏方面, objgraph 是很好的可视化分析工具。原创 2023-11-24 21:20:54 · 794 阅读 · 0 评论 -
23 | 你真的懂Python GIL(全局解释器锁)吗?
今天这节课,我们先通过一个实际的例子,了解了 GIL 对于应用的影响;之后我们适度剖析了 GIL 的实现原理,不必深究一些原理的细节,明白其主要机制和存在的隐患即可。自然,也提供了绕过 GIL 的两种思路。不过还是那句话,很多时候,我们并不需要过多纠结 GIL 的影响。原创 2023-11-24 19:08:27 · 899 阅读 · 0 评论 -
22 | 并发编程之Asyncio
我们首先来区分一下 Sync(同步)和 Async(异步)的概念。所谓 Sync,是指操作一个接一个地执行,下一个操作必须等上一个操作完成后才能执行。而 Async 是指不同操作间可以相互交替执行,如果其中的某个操作被 block 了,程序并不会等待,而是会找出可执行的操作继续执行。举个简单的例子,你的老板让你做一份这个季度的报表,并且邮件发给他。如果按照 Sync 的方式,你会先向软件输入这个季度的各项数据,接下来等待 5min,等报表明细生成后,再写邮件发给他。原创 2023-11-24 17:55:28 · 883 阅读 · 0 评论 -
21 | Python并发编程之Futures
Python 中的 Futures 模块,位于 concurrent.futures 和 asyncio 中,它们都表示带有延迟的操作。Futures 会将处于等待状态的操作包裹起来放到队列中,这些操作的状态随时可以查询,当然,它们的结果或是异常,也能够在操作完成后被获取。通常来说,作为用户,我们不用考虑如何去创建 Futures,这些 Futures 底层都会帮我们处理好。我们要做的,实际上是去 schedule 这些 Futures 的执行。原创 2023-11-24 16:55:48 · 883 阅读 · 0 评论 -
20 | 揭秘 Python 协程
到这里,今天的主要内容就讲完了。今天用了较长的篇幅,从一个简单的爬虫开始,到一个真正的爬虫结束,在中间穿插讲解了 Python 协程最新的基本概念和用法。这里简单复习一下。协程和多线程的区别,主要在于两点,一是协程为单线程;二是协程由用户决定,在哪些地方交出控制权,切换到下一个任务。协程的写法更加简洁清晰,把 async / await 语法和 create_task 结合来用,对于中小级别的并发需求已经毫无压力。原创 2023-11-24 14:15:02 · 933 阅读 · 0 评论 -
19 | 深入理解迭代器和生成器
总结一下,今天我们讲了四种不同的对象,分别是容器、可迭代对象、迭代器和生成器。容器是可迭代对象,可迭代对象调用 iter() 函数,可以得到一个迭代器。迭代器可以通过 next() 函数来得到下一个元素,从而支持遍历。生成器是一种特殊的迭代器(注意这个逻辑关系反之不成立)。使用生成器,你可以写出来更加清晰的代码;合理使用生成器,可以降低内存占用、优化程序结构、提高程序速度。生成器在 Python 2 的版本上,是协程的一种重要实现方式;原创 2023-11-24 12:03:09 · 967 阅读 · 0 评论 -
18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?
可能会让你惊讶,事实上,类本身不过是一个名为 type 类的实例。在 Python 的类型世界里,type 这个类就是造物的上帝。# Python 3和Python 2类似pass# 输出# 输出可以看到,instance 是 MyClass 的实例,而 MyClass 不过是“上帝”type 的实例。当我们定义一个类的语句结束时,真正发生的情况,是 Python 调用 type 的__call__运算符。data = 1data = 1# 输出# 输出1# 输出# 输出1。原创 2023-11-24 10:26:06 · 1057 阅读 · 0 评论 -
17 | 强大的装饰器
其实,装饰器还有更大程度的灵活性。刚刚说了,装饰器可以接受原函数任意类型和数量的参数,除此之外,它还可以接受自己定义的参数。@repeat(4)# 输出:这节课,我们一起学习了装饰器的概念及用法。所谓的装饰器,其实就是通过装饰器函数,来修改原函数的一些功能,使得原函数不需要修改。而实际工作中,装饰器通常运用在身份认证、日志记录、输入合理性检查以及缓存等多个领域中。合理使用装饰器,往往能极大地提高程序的可读性以及运行效率。原创 2023-11-24 08:51:25 · 838 阅读 · 0 评论 -
16 | 值传递,引用传递or其他,Python里参数是如何传递的?
如果接触过其他的编程语言,比如 C/C++,很容易想到,常见的参数传递有 2 种:值传递和引用传递。所谓值传递,通常就是拷贝参数的值,然后传递给函数里的新变量。这样,原变量和新变量之间互相独立,互不影响。// 交换2个变量的值int temp;temp = x;// 交换x和y的值x = y;y = temp;return;int a = 1;int b = 2;swap(a, b);return 0;原创 2023-11-23 21:09:40 · 913 阅读 · 0 评论 -
15 | Python对象的比较、拷贝
今天这节课,我们一起学习了 Python 中对象的比较和拷贝,主要有下面几个重点内容。比较操作符'=='表示比较对象间的值是否相等,而'is'表示比较对象的标识是否相等,即它们是否指向同一个内存地址。比较操作符'is'效率优于'==',因为'is'操作符无法被重载,执行'is'操作只是简单的获取对象的 ID,并进行比较;而'=='操作符则会递归地遍历对象的所有值,并逐一比较。浅拷贝中的元素,是原对象中子对象的引用,因此,如果原对象中的元素是可变的,改变其也会影响拷贝后的对象,存在一定的副作用。原创 2023-11-23 19:27:12 · 849 阅读 · 0 评论 -
14 | 答疑(一):列表和元组的内部实现是怎样的?
因此,判断类型的多态和子类继承的多态,在本质上都是一样的,只不过可以把它们理解为多态的两种不同表现。当然,需要注意的是,这里的x.append(2),并没有改变变量 x,x 依然指向原来的列表。事实上,这句话的意思是,访问 x 指向的列表,并在这个列表的末尾增加 2。你会发现,它是一个 over-allocate 的 array,根据元素键(key)的哈希值,来计算其应该被插入位置的索引。因此,这里提醒我们,在平时写代码时,一定要保证 except 中异常赋予的变量,在之后的语句中不再被用到。原创 2023-11-23 18:44:16 · 22 阅读 · 0 评论 -
13 | 搭建积木:Python 模块化
这是基础版块的最后一节。到目前为止,你已经掌握了 Python 这一门当代武功的基本招式和套路,走出了新手村,看到了更远的世界,有了和这个世界过过招的冲动。于是,你可能开始尝试写一些不那么简单的系统性工程,或者代码量较大的应用程序。这时候,简单的一个 py 文件已经过于臃肿,无法承担一个重量级软件开发的重任。今天这节课的主要目的,就是化繁为简,将功能模块化、文件化,从而可以像搭积木一样,将不同的功能,组件在大型工程中搭建起来。原创 2023-11-23 18:05:48 · 166 阅读 · 0 评论 -
12 | 面向对象(下):如何实现一个搜索引擎?
今天这节课是面向对象的实战应用,相比起前面的理论知识,内容其实不那么友好。不过,若能静下心来,仔细学习,理清楚整个过程的要点,对理解面向对象必将有所裨益。比如,可以根据下面两个问题,来检验今天这节课的收获。能把这节课所有的类的属性和函数抽取出来,自己在纸上画一遍继承关系吗?迭代开发流程是怎样的?原创 2023-11-23 17:06:28 · 120 阅读 · 0 评论 -
11 | 面向对象(上):从生活中的类比说起
到目前为止,我们一直在强调一件事情:面向对象编程是软件工程中重要的思想。正如动态规划是算法中的重要思想一样,它不是某一种非常具体的技术,而是一种综合能力的体现,是将大型工程解耦化、模块化的重要方法。在实践中要多想,尤其是抽象地想,才能更快掌握这个技巧。回顾一下今天的内容,希望你能自己回答下面两个问题。第一个问题,面向对象编程四要素是什么?它们的关系又是什么?第二个问题,讲了这么久的继承,继承究竟是什么呢?你能用三个字表达出来吗?原创 2023-11-23 16:08:23 · 43 阅读 · 0 评论 -
10 | 简约不简单的匿名函数
这节课,我们一起学习了 Python 中的匿名函数 lambda,它的主要用途是减少代码的复杂度。需要注意的是 lambda 是一个表达式,并不是一个语句;它只能写成一行的表达形式,语法上并不支持多行。匿名函数通常的使用场景是:程序中需要使用一个函数完成一个简单的功能,并且该函数只调用一次。原创 2023-11-23 14:49:55 · 90 阅读 · 0 评论 -
09 | 不可或缺的自定义函数
这节课,我们一起学习了 Python 函数的概念及其应用,有这么几点需要注意:1. Python 中函数的参数可以接受任意的数据类型,使用起来需要注意,必要时请在函数开头加入数据类型的检查;2. 和其他语言不同,Python 中函数的参数可以设定默认值;3. 嵌套函数的使用,能保证数据的隐私性,提高程序运行效率;4. 合理地使用闭包,则可以简化程序的复杂度,提高可读性。原创 2023-11-23 14:15:29 · 28 阅读 · 0 评论 -
08 | 异常处理:如何提高程序的稳定性?
前面的例子里充斥了很多 Python 内置的异常类型,你可能会问,可以创建自己的异常类型吗?答案是肯定是,Python 当然允许我们这么做。def __init__(self, value): # 自定义异常类型的初始化def __str__(self): # 自定义异常类型的string表达形式try:raise MyInputError(1) # 抛出MyInputError这个异常。原创 2023-11-23 11:16:45 · 29 阅读 · 0 评论 -
07 | 修炼基本功:条件与循环
今天这节课,我们一起学习了条件与循环的基本概念、进阶用法以及相应的应用。这里,我重点强调几个易错的地方。在条件语句中,if 可以单独使用,但是 elif 和 else 必须和 if 同时搭配使用;而 If 条件语句的判断,除了 boolean 类型外,其他的最好显示出来。在 for 循环中,如果需要同时访问索引和元素,可以使用 enumerate() 函数来简化代码。写条件与循环时,合理利用 continue 或者 break 来避免复杂的嵌套,是十分重要的。原创 2023-11-23 09:39:22 · 25 阅读 · 0 评论 -
06 | Python “黑箱”:输入与输出
这节课,我们主要学习了 Python 的普通 I/O 和文件 I/O,同时了解了 JSON 序列化的基本知识,并通过具体的例子进一步掌握。再次强调一下需要注意的几点:I/O 操作需谨慎,一定要进行充分的错误处理,并细心编码,防止出现编码漏洞;编码时,对内存占用和磁盘占用要有充分的估计,这样在出错时可以更容易找到原因;JSON 序列化是很方便的工具,要结合实战多多练习;代码尽量简洁、清晰,哪怕是初学阶段,也要有一颗当元帅的心。原创 2023-11-22 19:20:14 · 55 阅读 · 0 评论 -
05 | 深入浅出字符串
这节课,我们主要学习了 Python 字符串的一些基本知识和常用操作,并且结合具体的例子与场景加以说明,特别需要注意下面几点。Python 中字符串使用单引号、双引号或三引号表示,三者意义相同,并没有什么区别。其中,三引号的字符串通常用在多行字符串的场景。Python 中字符串是不可变的(前面所讲的新版本 Python 中拼接操作’+='是个例外)。因此,随意改变字符串中字符的值,是不被允许的。Python (2.5+)中,字符串的拼接变得比以前高效了许多,可以放心使用。原创 2023-11-22 18:07:27 · 23 阅读 · 0 评论 -
04 | 字典、集合,你真的了解吗?
这节课,我们一起学习了字典和集合的基本操作,并对它们的高性能和内部存储结构进行了讲解。字典在 Python3.7+ 是有序的数据结构,而集合是无序的,其内部的哈希表存储结构,保证了其查找、插入、删除操作的高效性。所以,字典和集合通常运用在对元素的高效查找、去重等场景。原创 2023-11-22 17:32:25 · 38 阅读 · 0 评论 -
03 | 列表和元组,到底用哪一个?
关于列表和元组,今天聊了很多,最后一起总结一下必须掌握的内容。总的来说,列表和元组都是有序的,可以存储任意数据类型的集合,区别主要在于下面这两点。列表是动态的,长度可变,可以随意的增加、删减或改变元素。列表的存储空间略大于元组,性能略逊于元组。元组是静态的,长度大小固定,不可以对元素进行增加、删减或者改变操作。元组相对于列表更加轻量级,性能稍优。原创 2023-11-22 16:35:38 · 26 阅读 · 0 评论 -
02 | Jupyter Notebook为什么是现代Python的必学技术?
说了这么多,到底什么是 Jupyter Notebook?按照 Jupyter 创始人 Fernando Pérez 的说法,他最初的梦想是做一个综合 Ju (Julia)、Py (Python)和 R 三种科学运算语言的计算工具平台,所以将其命名为 Ju-Py-te-R。发展到现在,Jupyter 已经成为一个几乎支持所有语言,能够把软件代码、计算输出、解释文档、多媒体资源整合在一起的多功能科学运算平台。英文里说一图胜千言(A picture is worth a thousand words)。原创 2023-11-22 15:46:04 · 251 阅读 · 0 评论 -
01 | 如何逐步突破,成为Python高手?
工作中,总听到很多程序员抱怨,说现在的计算机编程语言太多了,学不过来了。一些人 Java 用了很多年,但是最近的项目突然需要用 Python,就会不知所措,压力很大。众所周知,Facebook 的主流语言是 Hack(PHP 的进化版本)。不过,我敢拍着胸脯说,就刚入职的工程师而言,100 个里至少有 95 个,以前都从未用过 Hack 或者 PHP。但是,这些人上手都特别快,基本上一两周后,日常编程便毫无压力了。他们是怎么做到的呢?事实上,他们遵循的,正是 “从工程的角度去学习 Python”。原创 2023-11-22 14:56:05 · 30 阅读 · 0 评论