介绍 Python 功能和小技巧的文章网上有无数篇,比如变量解压缩,partial 偏函数,枚举可迭代对象... 但关于 Python 我们能说的还有很多。所以今天我将向大家展示一些我知道和有使用过的特性,这些特性在其它文章或博客中很少被提及:

消毒字符串输入

对用户输入内容进行消毒几乎适用于你写的每一个程序。通常来说转换字符大小写的操作就足够了,有时候用 Regex 正则表达式就能完成,但对于比较复杂的情况,我们有更好的办法:

user_input = "This\nstring has\tsome whitespaces...\r\n"
character_map = {
ord('\n') : ' ',
ord('\t') : ' ',
ord('\r') : None
}
user_input.translate(character_map) # This string has some whitespaces... "

在这个例子中我们可以看到空格子字符"\n"和"\t"已被单个空格代替,而"\r"已经被删除。这是一个很简单的示例,但我们可以更进一步,并使用unicodedata包和它的 combining() 函数来重新生成映射。

迭代器切片

如果尝试对 Iterator 进行切片,则会出现 TypeError和"generator object is not subscriptable"的报错,但我们有一个简单的解决办法:

import itertools
s = itertools.islice(range(50), 10, 20) # <itertools.islice object at 0x7f70fab88138>
for val in s:
...

通过使用 itertools.islice我们可以创建一个 islice对象,该对象是产生所需项目的迭代器。不过这里需要注意的是,它会消耗所有的生成器项直到切片的开始为止,而且还会消耗 islice对象中的所有项。

跳过可迭代对象的开始部分

有时候你不得不去处理这样一些文件,它们的开头是毫无用处的行,比如注释之类的。itertools再一次地能在这里派上用场:

string_from_file = """
// Author: ...
// License: ...
//
// Date: ...
Actual content...
"""
import itertools
for line in itertools.dropwhile(lambda line: line.startswith("//"), string_from_file.split
print(line)

这个代码片段只会生成文件开始注释之后的部分。如果我们只想丢弃可迭代对象开头的某些项(比如这个例子中的注释部分),但不确定这个项的大小,这个方法很实用。

创建支持 with声明的对象

大家想必都知道如何用 with声明来打开文件或者获取锁,但我们能实现自己的 with声明吗?是的,实际上通过使用 enter和 exit我们就可以实现一个上下文管理器协议:

class Connection:
def __init__(self):
...
def __enter__(self):
# Initialize connection...
def __exit__(self, type, value, traceback):
# Close connection...
with Connection() as c:
# __enter__() executes
...
# conn.__exit__() executes

这是 Python 中实现上下文管理最常见的方法,但其实还有一种更简单的方法:

from contextlib import contextmanager
@contextmanager
def tag(name):
print(f"<{name}>")
yield
print(f"")
with tag("h1"):
print("This is Title.")

上面的代码片段使用 contextmanager管理器装饰器实现了内容管理协议 。进入 with块时,执行 tag()的第一部分(在 yield之前),然后再执行该块,最后执行 tag()剩下的部分。

用 slots节省内存

如果在你编写的程序中会创建某个类的大量实例,那么你肯定已经注意到你的程序会占用大量内存。这是因为 Python 使用 Dictionary 来表示类实例的属性,虽然它速度很快但内存效率却很低。大部分情况下这个问题并不那么严重,但如果它对你的程序来说是一个大问题,你可以尝试使用 slots:

class Person:
__slots__ = ["first_name", "last_name", "phone"]
def __init__(self, first_name, last_name, phone):
self.first_name = first_name
self.last_name = last_name
self.phone = phone

所以这里的情况就是当我们定义slots的属性时,Python 使用的是小型的固定大小的数组,而不是 dictionary,这就大大减少了每个实例所需的内存。使用 slots也有缺点——我们无法声明任何新属性,并且只能在 slots上使用它们。同样,带有 slots的类不能使用多重继承。

限制 CPU 和内存使用

如果你不是想通过优化程序来降低它的 CPU 和内存使用率,而是想简单粗暴地直接限制它为某个数字,那么 Python 中有一个库可以做到:

import signal
import resource
import os
# To Limit CPU time
def time_exceeded(signo, frame):
print("CPU exceeded...")
raise SystemExit(1)
def set_max_runtime(seconds):
# Install the signal handler and set a resource limit
soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard))
signal.signal(signal.SIGXCPU, time_exceeded)
# To limit memory usage
def set_max_memory(size):
soft, hard = resource.getrlimit(resource.RLIMIT_AS)
resource.setrlimit(resource.RLIMIT_AS, (size, hard))

这里我们看到了两种限制最大 CPU 运行时间和最大内存使用的方法。对于 CPU 限制,我们首先获得该特定资源( RLIMIT_CPU)的软限制与硬限制,然后使用参数指定的描述和闲钱获取的硬限制来设置它。最后,如果 CPU 时间被超出,我们将注册导致系统退出的信号。至于内存方面,我们再次获取软限制与硬限制,并使用带有 size 参数的 setrlimit和获取的硬限制对其进行设置。

控制可导入和不可导入的内容

有些语言对于到处成员变量,方法和接口有着非常明确的机制,比如 Golang,在 Go 中仅有以大写字母开头的成员才能被导出。另一方面,在 Python 中,所有内容都可以到处,除非我们使用 all:

def foo():
pass
def bar():
pass
__all__ = ["bar"]

根据上面的代码片段,我们可以看出只有 bar()会被导出。另外,我们可以将 all保留为空,并且从此模块导入时,不会输出任何 AttributeError。

比较运算符的简便方法

Python 中有很多比较运算符:lt , le , gt 和 ge,但有没有更容易的方法呢?functools.total_ordering就可以办到:

from functools import total_ordering
@total_ordering
class Number:
def __init__(self, value):
self.value = value
def __lt__(self, other):
return self.value < other.value
def __eq__(self, other):
return self.value == other.value
print(Number(20) > Number(3))
print(Number(1) < Number(5))
print(Number(15) >= Number(15))
print(Number(10) <= Number(2))

那么它实际上是怎么工作的呢?total_ordering装饰器用于简化为我们的类实现实力顺序的过程。只需要定义 lt 和 eq,这也是映射剩余操作所需的最低要求,也是装饰器的工作——它为我们填补了这个空缺。在学习Python的过程中,往往因为没有资料或者没人指导从而导致自己不想学下去了,因此我特意准备了个群 592539176 ,群里有大量的PDF书籍、教程都给大家免费使用!不管是学习到哪个阶段的小伙伴都可以获取到自己相对应的资料!

总结

上述的特性与操作都不一定是你在日常 Python 编程中常用到的,但其中一些时不时会让你感到头疼。上面所提供的解决方案大多简化了很多任务,这些任务用较为常见的方法处理都会比较冗长无聊。另外要指出的一点是,所有的这些功能都是 Python 标准库的一部分。在我看来,其中一些功能类似于“标准库中的非标准功能”,因此每当你想要在 Python 中实现某些功能时,首先去标准库里找一找,如果没有这个功能,那肯定是你找得不够仔细,如果实在是没有,再去找相关的第三方库。

关于 Python_你一定没读过的8个技巧的更多相关文章

  1. hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

    题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个 ...

  2. PAT 甲级 1023 Have Fun with Numbers (20 分)(permutation是全排列题目没读懂)

    1023 Have Fun with Numbers (20 分)   Notice that the number 123456789 is a 9-digit number consisting ...

  3. 读>>>>白帽子讲Web安全<<<<摘要→我推荐的一本书→1

      <白帽子讲Web安全>吴翰清著 刚开始看这本书就被这本书吸引,感觉挺不错,给大家推荐下,最近读这本书,感觉不错的精华就记录下, 俗话说>>>好脑袋不如一个烂笔头< ...

  4. c++中ifstream读文件的问题(关于eof())

    今天帮别人找BUG,是一段关于c++读写文件的问题,使用的是ifstream与outstream类,关于ofstream与ifstream的用法,此处不再獒述,见代码: #include<ios ...

  5. Linux中的读函数与块高速缓存

    为了提高Linux块设备读写的效率,Unix会在内存中建立块高速缓存,块高速缓存存储了系统最近读的数据块和刚刚写入的数据块,也就是说IO访问其实是和块高速缓存打交道的(直接IO除外),块高速缓存会适时 ...

  6. [No000016D]把知识种进脑子:像读教材一样读书

    读书,常常是书读一遍,过后脑子却空白一片.旁人问起感受,只能以不错.很好作答.更有甚者,有时翻阅豆瓣才发现一本书竟早已「读过」,这事儿可真叫尴尬.为了对付这症状,我笔记也做过,思维导图也画过,奈何只是 ...

  7. POJ1410_还是没考虑全面——线段是否与矩形有共同的垂直投影

    题意如题目 有几个点1.怪我没读好题目:给出的矩形两个端点不一定都是左上右下,但是肯定能勾勒出一个矩形. 2.现在才发现很多线段相交的判断我都没有仔细考虑这一个问题 bool ssinsert(Poi ...

  8. Codeforces Round #589 (Div. 2) (e、f没写)

    https://codeforces.com/contest/1228/problem/A A. Distinct Digits 超级简单嘻嘻,给你一个l和r然后寻找一个数,这个数要满足的条件是它的每 ...

  9. Python_面试题_更新中

    Python-面试题 线上操作系统 centos py2和py3的区别 每种数据类型,列举你了解的方法 3 or 9 and 8 字符串的反转 is 和 == 的区别? git流程 v = (1) / ...

随机推荐

  1. Codeforces Round #451 (Div. 2) A B C D E

    Codeforces Round #451 (Div. 2) A Rounding 题目链接: http://codeforces.com/contest/898/problem/A 思路: 小于等于 ...

  2. 【搞定面试官】try中有return,finally还会执行吗?

    本篇文章我们主要探讨 一下如果try {}语句中有return,这种情况下finally语句还会执行吗?其实JVM规范是对这种情况有特殊规定的,那我就先上代码吧! public class Final ...

  3. 转:SSL 握手协议详解

    SSL 握手协议详解 RSA作为身份认证,ECDHE来交换加密密钥,AES/DES等作为加密. 如果RSA来加解密,那么身份认证后,直接用认证后的RSA公钥解密.不需要再额外交换加密密钥了. 相关报文 ...

  4. CodeForces-Round524 A~D

    A. Petya and Origami time limit per test  1 second   memory limit per test  256 megabytes input stan ...

  5. ACM-ICPC 2018 焦作赛区网络预赛 B题 Mathematical Curse

    A prince of the Science Continent was imprisoned in a castle because of his contempt for mathematics ...

  6. io流函数略解(java_input流)[二]

    背景 在写这篇随笔之前,已经写了io流函数略解(java_File)(一),主要是总结了File的一些操作,以及一些源码介绍. 在Io实际应用中,实际上运用在如果会操作File,实际上很难写出一点能实 ...

  7. vue2.5 + element UI el-table 导出Excel

    安装依赖 npm install --save xlsx file-saver 新建excelHelper.js \src\utils\目录下新建excelHelper.js文件 import Vue ...

  8. Python3 模块基础

    目录 模块 什么是模块 模块的四种形式 导入模块 import 模块 from 模块 import 方法 循环导入 模块搜索路径 Python文件的两种用途 包 什么是包 为什么要有包 包的使用 绝对 ...

  9. 【NodeJS】nvm

    [NodeJS]nvm node多版本管理 NVM_HOME=C:\env\nvm NVM_SYMLINK=C:\env\nodejs 查看版本 nvm v 查看当前使用的node版本 nvm cur ...

  10. 【Git】学习开始

    [Git]学习开始 转载:https://www.cnblogs.com/yangchongxing/p/10172683.html 在线电子书籍:https://git-scm.com/book/z ...