
Python
文章平均质量分 72
Deniro Lee
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
在命令行运行 python 抛出 ModuleNotFoundError 的解决方法
所要运行的 py 文件在子目录中,并且该文件引用了另一个子目录中的 py 模块。类似这样:原因在运行环境下, a.py 找不到 b.py 所以抛出 ModuleNotFoundError。解决把父文件夹的所在路径加入运行环境,代码如下:import osimport sysdirname = os.path.dirname(__file__)curPath = os.path.abspath(dirname)r= os.path.split(curPath)rootPath = r[原创 2022-03-20 18:19:27 · 828 阅读 · 0 评论 -
说说 Python 的 lru_cache 装饰器
Python 的 lru_cache 装饰器是一个为自定义函数提供缓存功能的装饰器。其内部会在下次以相同参数调用该自定义函数时直接返回计算好的结果。通过缓存计算结果可以很好地提升性能。1 从示例说起假设我们有一个计算斐波那契数列的求和函数,其内部采用递归方式实现。from xxx.clock_decorator import clock@clockdef fibonacci(n): if n<2: return n return fibonacci(n-2)原创 2021-03-14 11:27:15 · 348 阅读 · 1 评论 -
说说在 Python 中如何实现输出指定函数运行时长的装饰器
假设我们需要一个可以输出某个函数运行时长的装饰器。1 基础实现一种可能的定义方式为:import timedef clock(func): def clocked(*args): t0 = time.perf_counter() result = func(*args) elapsed = time.perf_counter() - t0 name = func.__name__ arg_str = ', '原创 2021-02-27 17:31:55 · 460 阅读 · 0 评论 -
说说 Python 中 nonlocal 的作用
假设我们需要一个函数,用于计算平均值,每次调用这个函数时,都会把传入的入参保存在内部。根据要求,这个函数的一种实现方式是使用装饰性函数,其内部使用闭包来存放次数与总量。最后再使用这两个数计算出平均值。实现代码为:def make_averager(): count = 0 total = 0 def averager(new_value): count += 1 total += new_value logging.debug(原创 2021-02-27 16:31:36 · 645 阅读 · 0 评论 -
说说 Python 函数装饰器
Python 函数装饰器可以把被装饰的函数替换为另一个函数。1 基础def deco(func): def inner(): logging.info('inner -> %s','running') return inner@decodef target(): logging.info('target -> %s', 'running')target()logging.info('target -> %s',target)运原创 2021-02-27 16:15:39 · 755 阅读 · 0 评论 -
说说 Python 中的闭包
闭包不好理解,所以先从示例说起。假设我们需要计算平均值,这些值会从外层传递进来,然后被保存在内部。(1) 非闭包方式实现class Averager(): def __init__(self): self.series = [] def __call__(self, new_value): self.series.append(new_value) total = sum(self.series) return tot原创 2021-02-10 17:34:33 · 909 阅读 · 7 评论 -
说说 Python 的变量作用域
先来看一个示例:def f1(a): logging.info('a -> %s', a) logging.info('b -> %s', b)logging.info('f1(3) -> %s',f1(3))运行结果:因为 b 没有定义,所以在运行 f1() 函数时抛错了。在 pycharm 中也会以红色波浪形式提示我们这个变量还未定义:解决这个问题也很简单,先定义好变量 b 即可:输出结果:因为我们没有为 f1() 函数定义返回值,所以f1()原创 2021-02-10 16:23:25 · 413 阅读 · 2 评论 -
说说如何使用 Python 函数实现策略模式
假设某电商平台网店制定了下述折扣规则:A. 有 1000 或以上积分的顾客,每个订单享 5% 折扣;B. 同一订单中,单个商品的数量达到 20 个或以上,享 10% 折扣;C. 订单中的不同商品达到 10 个或以上,享 7% 折扣。为了方便说明问题,我们假定一个订单一次只能享用一个折扣。这个功能很明显应该采用策略设计模式,我们先画出类图:类图属性栏中的 - 表示 private1。虚线三角箭头表示类实现关系,实现类指向接口;虚线箭头表示类依赖关系,箭头指向依赖类。1 传统实现方式1.1原创 2021-02-06 11:44:21 · 483 阅读 · 2 评论 -
说说 Python 中的 Operator 模块
Python 中的 Operator 模块可以让它支持函数式编程。1 计算函数假设我们需要一个计算阶乘的函数,一般做法是使用递归。如果使用函数式编程,可以有两种方式,一种 lambda,另一种使用 Operator 模块中的算术函数。我们做个比较。首先使用 lambda 方式来实现:from functools import reducedef fact(n): return reduce(lambda a, b: a * b, range(1, n + 1))这里用到了 reduce原创 2021-01-23 16:26:20 · 418 阅读 · 0 评论 -
说说 Python 中的高阶函数
高阶函数(higher-order function)指的是:接受一个函数为参数,或者把函数作为结果值返回的函数1。1 sorted()比较常见的高阶函数是 sorted(),其内部的关键字参数 key 可以接受一个函数为参数,来指定值的排序规则2。比如一个单词列表,如果给关键字参数 key 赋予一个 len 函数,就可以让这个列表按照单词的长度进行排序。animals = ['ox', 'giraffe', 'mouse', 'tiger', 'lion', 'deer', 'goose']r原创 2020-12-06 17:03:38 · 369 阅读 · 0 评论 -
说说 Python 函数对象的本质
Python 函数对象本质上是 function 类的实例1。1 从示例说起def factorial(n): '''return n!''' return 1 if n < 2 else n * factorial(n - 1)r = factorial(42)logging.info('r -> %s', r)logging.info('__doc__ -> %s', factorial.__doc__)logging.info('type(factor原创 2020-11-29 15:48:08 · 336 阅读 · 0 评论 -
说说 Python 的不可变字典类型 MappingProxyType
MappingProxyType 类接受一个字典入参,它会返回一个只读的映射视图1。这个视图对象会受原字典对象的影响,也就是说如果原字典对象中的内容发生变化,那么这个视图对象也会跟着发生变化。dict={1: 'A'}not_modify_dict=MappingProxyType(dict)logging.info('not_modify_dict -> %s', not_modify_dict)logging.info('not_modify_dict[1] -> %s', not_原创 2020-11-22 15:52:43 · 996 阅读 · 0 评论 -
说说 Python 的 collections.Counter 类型
collections.Counter 类型可以用来给可散列的对象计数,或者是当成多重集合来使用 —— 多重集合就是集合里的元素可以出现多次1。collections.Counter 类型类似于其它编程语言中的 bags 或者 multisets2。(1)基本用法counter = collections.Counter(['生物', '印记', '考古学家', '生物', '枣', '印记'])logging.info('counter -> %s', counter)counter.u原创 2020-11-22 15:02:59 · 806 阅读 · 2 评论 -
说说在 Python 字典中如何在读取不存在的键时得到一个默认值
如果有方法能够在 Python 字典类型中,当读取不存在的键时能够得到一个默认值,那么代码就会变得更加直观。通过 defaultdict 类型可以实现这个目的1。我们来改写一个 “输出单词所在坐标” 的示例来说明使用 defaultdict 类型与使用 setDefault 方法之间的区别2。改写后的完整示例代码如下:import collectionsimport logginglogging.basicConfig(level=logging.DEBUG, format='%(level原创 2020-11-21 17:09:01 · 2784 阅读 · 0 评论 -
说说在 Python 中如何使用 setDefault 方法提高效率
1 从示例说起Luciano Ramalho 举了一个示例来说明 setDefault 方法相对于传统写法的高效性1。import sysimport reWORD_RE = re.compile(r'\w+')index = {}with open(sys.argv[1], encoding='utf-8') as fp: for line_no, line in enumerate(fp, 1): for match in WORD_RE.finditer(lin原创 2020-11-15 11:57:57 · 521 阅读 · 0 评论 -
说说 Python 的字典推导
利用 Python 的字典推导,我们可以把以键值对作为元素的可迭代对象中构建出字典。以键值对作为元素的可迭代对象的一个典型对象是包含键值对元组的列表。Luciano Ramalho 举了一个示例,用来说明如何使用字典推导。DIAL_CODES = [ (91, 'India'), (1, 'United States'), (62, 'Indonesia'), (55, 'Brazil'), (92, 'Pakistan'), (880, 'Bangladesh'), (234, 'Ni原创 2020-10-24 09:02:36 · 237 阅读 · 0 评论 -
说说在 Python 中如何递归创建不存在的文件夹路径
代码模板如下所示:import osif not os.path.exists(path): os.makedirs(path)首先先引入 os,os 是 operating system(操作系统)的缩写。接着使用 os.path.exists(path) 判定 path 路径是否存在。如果存在则返回 True。最后使用 os.makedirs(path) 方法,它可以递归创建指定路径下的文件夹。如果文件夹创建失败或者已经存在,会抛出 OSError 异常。所以在调用 makedi原创 2020-10-10 20:25:15 · 2446 阅读 · 0 评论 -
说说 Python 的映射数据类型
1 映射类关系Python 的 collections.abc 模块内拥有 Mapping 和 MutableMapping 这两个抽象基类,它们为 dict 和其他类似的类型提供了接口定义。mutable /ˈmjuːtəbl/adj.Capable of or subject to change or alteration.它们之间的类关系如下图所示:箭头从子类指向父类,抽象类和抽象方法的名称以斜体显示。首先是 Container、Iterable 与 Sized 三大接口,接着原创 2020-10-08 10:22:06 · 1074 阅读 · 0 评论 -
说说 Python 的双向队列
虽然可以使用 Python 列表的 .append 和 .pop 方法模拟栈或者队列,但删除列表的第一个元素或者在第一个元素之前添加一个新元素,都非常耗时。因为需要把列表中的所有元素向后移动。Python 的双向队列使用 collections.deque 类来实现。它是一个线程安全且可以快速从两端添加或者删除元素的类。deque /dɛk/也可以利用 collections.deque 类来实现缓存。首先先指定缓存队列的大小,然后从队首删除过期元素和在队尾添加新元素。Luciano Rama原创 2020-10-04 11:14:43 · 562 阅读 · 1 评论 -
说说 Python 的内存视图
Python 的内存视图(memoryview)是一个内置类,它能取出数组中的某一部分作为切片进行处理。切片的任何变化都会影响到数组。NumPy 的作者 Travis Oliphant 是这样看待内存视图的:内存视图其实是泛化和去数学化的 NumPy 数组。它让我们可以在不需要复制内容的前提下,实现在数据结构之间共享内存。其中数据结构可以是任何形式,比如 PIL 图片 、SQLite 数据库和 NumPy 数组等等。对于处理大型数据集合的场景,这个功能非常重要。PIL:Python Imaging L原创 2020-10-04 10:27:55 · 623 阅读 · 0 评论 -
说说 Python 数组的高效性
如果我们需要一个只包含数字的列表,那么使用数组方式比 list 方式更高效。而且数组还支持所有跟可变序列有关的操作,比如移除列表中的一个元素(.pop)、插入元素(.insert) 和 在列表末尾一次性追加另一个序列中的多个值(.extend)。 除此之外,数组还定义从文件读取(.frombytes)与写入(.tofile)的效率更高的方法。创建数组需要一个类型码,形如 array(‘d’),这个类型码是用来表示在底层实现的 C 语言的数据类型。一般我们用的 Python 底层是用 C 语言编写实现的&n原创 2020-10-02 11:21:56 · 650 阅读 · 0 评论 -
说说 Python 的 bisect 模块
bisect 模块包含两个主要函数( bisect 和 insort),它们内部利用二分查找算法,分别用于在有序序列中查找元素与插入元素。bisect /baɪˈsekt/to divide sth into two equal parts 对半分;二等分1 bisect 函数Luciano Ramalho 举了这样一个在干草垛中找针的示例来说明如何使用 bisect.bisect 与 bisect.bisect_left。HAYSTACK = [1, 4, 5, 6, 8, 12, 15,原创 2020-10-01 12:09:29 · 622 阅读 · 0 评论 -
说说 Python 中 list.sort()方法与函数sorted() 之间的区别
(1) list.sort() 方法list.sort() 方法就地排序,也就是说会直接作用于当前列表,直接把当前列表变为已排序的列表。它会返回 None。在 Python 中 ,如果一个函数或者方法对对象进行的是就地改动操作,一般来说,它们会返回 None。这样做的目的是让 API 的使用者知道这个函数或者方法是就地改动操作。比如 random.shuffle 函数也有这个特性。shuffle() 方法会将序列的所有元素进行随机排序。有利就有弊,因为这些函数或者方法只能返回 None,所以无法原创 2020-10-01 08:28:28 · 1184 阅读 · 0 评论 -
说说 Python 序列增量赋值的效率
*= 在可变和不可变序列上在实现方式上是不同的。Luciano Ramalho 举了这样一个示例:l = [1, 2, 3]logging.info('id(l) -> %s', id(l))l *= 2logging.info('l -> %s', l)logging.info('id(l) -> %s', id(l))t = (1, 2, 3)logging.info('id(t) -> %s', id(t))t *= 2logging.info('t -原创 2020-10-01 08:27:16 · 339 阅读 · 0 评论 -
说说在 Python 中如何快速复制序列
1 基本用法把序列乘以一个整数,就会产生一个新序列。这个新序列是原始序列复制了整数份,然后再拼接起来的结果。l=[1,2,3]l2=l * 3logging.info('l2 -> %s',l2)l3=5 * 'deniro'logging.info('l3 -> %s',l3)运行结果:INFO - l2 -> [1, 2, 3, 1, 2, 3, 1, 2, 3]INFO - l3 -> denirodenirodenirodenirodeniro* 复制原创 2020-09-06 11:05:09 · 1066 阅读 · 0 评论 -
说说 Python 切片的高级用法
Python 中的列表(list)、元组(tuple)和字符串(str)等序列类型都支持切片操作。1 最后一个元素设计切片操作时不会包含区间范围中的最后一个元素,因为 Python 与 Java 语言一样,以 0 作为起始下标。这样做的好处是:当看见[:x]语法时,就可以知晓切片内包含 x 个元素。当看见 [start:stop]语法时,就可以知晓切片内包含 stop-start 个元素。通过一个下标就可以把序列分割成不重叠的两部分,形如 my_list[:x] (范围为 0 ~ x-1)和原创 2020-09-06 09:06:00 · 851 阅读 · 0 评论 -
说说 Python 元组的高级用法
1 元组记录元组可以当做存放数据的记录。元组中的元素用于存放记录字段数据,而元素所在的位置用于表达该字段的隐含含义。Luciano Ramalho 举了这样一个示例:lax_coordinates=(33.33,-11.92)logging.info('longitude -> %s',lax_coordinates[0])logging.info('latitude -> %s',lax_coordinates[1])city,year,pop,chg,area=('Tokyo'原创 2020-08-22 11:27:34 · 623 阅读 · 0 评论 -
说说 Python 的生成器表达式
列表推导与生成器表达式都可以用于初始化元组、数组或其他类型的序列。但列表推导需要先建立一个完整的列表,然后再把这个列表传递到某个构造函数。而生成器表达式会逐个产出元素,这样显然能够节省内存。列表推导写法:codes = [ord(symbol) for symbol in symbols]x = tuple(codes)生成器表达式写法:x = tuple(ord(symbol) for symbol in symbols)从这个示例中可以看出,生成器表达式比列表推导,减少了创建 code原创 2020-08-01 10:35:58 · 398 阅读 · 0 评论 -
说说在 Python 中如何使用列表推导
1 从示例说起Luciano Ramalho 举了这样一个示例,把一个字符串转为 Unicode 码的列表。传统写法是这样的:symbols='@#$%^&'codes=[]for symbol in symbols: codes.append(ord(symbol))运行结果:INFO - codes -> [64, 35, 36, 37, 94, 38]ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unico原创 2020-07-25 11:28:55 · 341 阅读 · 0 评论 -
说说 Python 内置序列类型
Python 标准库用 C 语言实现了很多种序列类型,具体说明见下图:可变序列(MutableSequence)从不可变序列 (Sequence)中继承了一些方法。箭头从子类指向超类,斜体表示是抽象类或抽象方法。原创 2020-07-25 08:55:10 · 363 阅读 · 0 评论 -
说说 Python 的具名元组
Python 提供的元组与列表类似,不同之处在于元组的元素不能修改。虽然有时候很方便,但因为不能为元组内部的数据进行命名,所以没有那么直观。Python 引入了 collections.namedtuple 这个工厂函数,用来构造一个带字段名的元组。(1)声明与实例化我们一般这样来构造具名元组:namedtuple(typename, field_names)参数说明typename元组名称。field_names元组中元素的名称;可以是有多个字符串组成的可迭代对象原创 2020-06-20 11:59:53 · 529 阅读 · 0 评论 -
说说如何使用 Python 发送电子邮件
使用 Python 的 smtplib 模块,就可以实现发送邮件。1 电子邮件服务器如果是网易 163 邮箱,我们可以在浏览器中登陆 https://mail.163.com/ 邮箱后,依次点击 设置 → POP3/SMTP/IMAP ,进入服务器设置页:进入服务器设置页后,确保开启 SMTP 与 IMAP 服务。设置页的最下面就是网易邮箱的服务器地址:(1)SMTP发送电子邮件使用的协议是简单邮件传输协议( SMTP ,Simple Mail Transfer Protocol)。它是一种提原创 2020-05-30 10:32:11 · 2463 阅读 · 0 评论 -
说说 Python 的 datetime 模块
Python 的 datetime 模块可以自定义日期的显示格式,而且还可以很方便地对日期进行算术运算,比如增减天数等操作。datetime 模块定义了 datetime 数据类型,用于表示一个特定的时刻。import datetimeimport loggingimport timelogging.basicConfig(level=logging.DEBUG, format='%...原创 2020-05-01 09:39:43 · 451 阅读 · 0 评论 -
说说如何使用 Python 的 cProfile 模块分析代码性能
cProfile 模块是自 python 2.5 以来标准版 Python 解释器的默认性能分析器。它是一种确定性分析器,只测量 CPU 时间,并不包含内存消耗和其他与内存相关联的信息。代码分析模板如下:import cProfile, pstats, iofrom pstats import SortKeypr = cProfile.Profile()pr.enable()# .....原创 2020-04-12 10:21:43 · 649 阅读 · 0 评论 -
说说 Python 的 round 函数
round( number ) 函数会返回浮点数 number 的四舍五入值。具体定义为 round(number[,digits]):如果 digits>0 ,四舍五入到指定的小数位;如果 digits=0 ,四舍五入到最接近的整数;如果 digits<0 ,则在小数点左侧进行四舍五入;如果 round() 函数只有 number 这个参数,则等同于 digits=0。...原创 2020-04-12 09:23:01 · 1555 阅读 · 1 评论 -
说说 Python 的 time 模块
Python 内置的 time 模块可以让 Python 程序读取系统时钟的当前时间。1 time.time() 函数Unix 纪元指的是 1970 年 1 月 1 日 0 点,即协调世界时(UTC)。 time.time()函数会返回自Unix 纪元那一刻以来的秒数,是一个浮点值,这个数字称为 UNIX 纪元时间戳。由于英文(CUT,Coordinated Universal Time)...原创 2020-04-06 11:55:38 · 250 阅读 · 0 评论 -
说说如何利用 Python 实现 JSON 与 Python 对象之间的相互转换
JSON (JavaScript Object Notation)是 JavaScript 程序编写数据结构的原生方式,它可以将数据格式化,成为可供人阅读的字符串。Python 的 json 模块可以处理 JSON 格式的数据。但因为 JSON 是 JavaScript 体系,所以只能表示字符串、整型、浮点型、布尔型、列表、字典和 NoneType。1 JSON 字符串转为 Python 对...原创 2020-04-04 11:51:27 · 500 阅读 · 0 评论 -
说说如何利用 Python 处理 CSV 文件
CSV 表示 “Comma-Separated Values (逗号分隔的值) ” , CSV 文件是简化的电子表格,实际为纯文本文件。一个 CSV 文件,格式是这样的:因为 CSV 文件中的每个单元格都是以逗号分割,所以也许有人会对每行文本调用 split() 方法,来解析 CSV 文件。但 CSV 文件也有自己的转义字符,通过转义字符,允许逗号和其他字符作为值的一部分,但单纯使用 spl...原创 2020-04-04 10:12:37 · 580 阅读 · 0 评论 -
说说如何利用 Python 的 BeautifulSoup 模块解析 HTML 页面
BeautifulSoup 是 Python 的一个模块,用于从 HTML 页面中提取信息。首先在命令行中运行 pip install beautifulsoup4 安装该模块,模块的名称是 bs4。1 创建 BeautifulSoup 对象调用 bs4. BeautifulSoup () 函数时,需要传入需要解析的 HTML 字符串。 bs4. BeautifulSoup () 函数会返回...原创 2020-03-22 11:37:09 · 497 阅读 · 0 评论 -
说说如何利用 Python 的 requests 模块,从网络下载电子小说
利用 Python 的 requests 模块可以很容易从网络下载电子小说,甚至可以处理 https 连接!首先必须先安装该模块。通过命令行,运行 -》pip install request1 请求首先找一个电子书下载链接,形如:https://xiazai.xqishu.com/txt/%E9%80%A0%E5%8C%96%E5%9B%BE.txt, 这个 URL 地址指向了一个 t...原创 2020-03-21 12:09:28 · 1353 阅读 · 0 评论