Python小技巧(一)
有许许多多文章写了 Python 中的许多很酷的特性,例如变量解包、偏函数、枚举可迭代对象,但是关于 Python 还有很多要讨论的话题,因此在本文中,我将尝试展示一些我知道的和在使用的,但很少在其它文章提到过的特性。那就开始吧。
1、对输入的字符串“消毒”
对用户输入的内容“消毒”,这问题几乎适用于你编写的所有程序。通常将字符转换为小写或大写就足够了,有时你还可以使用正则表达式来完成工作,但是对于复杂的情况,还有更好的方法:
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() 函数,来生成更大的重映射表(remapping table),并用它来删除字符串中所有的重音。
2、对迭代器切片
如果你尝试直接对迭代器切片,则会得到 TypeError ,提示说该对象不可取下标(not subscriptable),但是有一个简单的解决方案:
import itertools
s = itertools.islice(range(50), 10, 20) # <itertools.islice object at 0x7f70fab88138>
for val in s:
...
使用itertools.islice,我们可以创建一个 islice 对象,该对象是一个迭代器,可以生成我们所需的内容。但是这有个重要的提醒,即它会消耗掉切片前以及切片对象 islice 中的所有元素。
3、跳过可迭代对象的开始
有时候你必须处理某些文件,它们以可变数量的不需要的行(例如注释)为开头。itertools 再次提供了简单的解决方案:
string_from_file = """
// Author: ...
// License: ...
//
// Date: ...
Actual content...
"""
import itertools
for line in itertools.dropwhile(lambda line:line.startswith("//"), string_from_file.split("\n")):
print(line)
这段代码仅会打印在初始的注释部分之后的内容。如果我们只想丢弃迭代器的开头部分(在此例中是注释),并且不知道有多少内容,那么此方法很有用。
4、仅支持关键字参数(kwargs)的函数
当需要函数提供(强制)更清晰的参数时,创建仅支持关键字参数的函数,可能会挺有用:
def test(*, a, b):
pass
test("value for a", "value for b") # TypeError: test() takes 0 positional arguments...
test(a="value", b="value 2") # Works...
如你所见,可以在关键字参数之前,放置单个 * 参数来轻松解决此问题。如果我们将位置参数放在 * 参数之前,则显然也可以有位置参数。
5、创建支持 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"</{name}>")
with tag("h1"):
print("This is Title.")
上面的代码段使用 contextmanager 装饰器实现了内容管理协议。tag 函数的第一部分(yield 之前)会在进入 with 语句时执行,然后执行 with 的代码块,最后会执行 tag 函数的剩余部分。
浙公网安备 33010602011771号