分享6个隐藏的Python功能
本文介绍了6个鲜为人知但极具实用价值的Python功能。内容涵盖链式比较运算符、就地变量交换、enumerate遍历、循环else子句、字典get默认值以及正则表达式注释和iter哨兵用法。这些技巧有助于编写更简洁、高效且符合Python设计哲学的代码,适合希望提升Python编程水平的开发者参考。
此前曾介绍过Python中一些较少使用的特性,今天为大家整理并分享6个相对隐蔽但实用的Python功能,供各位学习参考。
Python的设计哲学强调“Simple is better than complex”(简单优于复杂),这也是推荐Python作为初学者首选语言的原因之一。许多初学者容易受其他编程语言影响,例如将Java风格带入Python。在Java中,为内部变量定义get和set方法以保障封装性是常见做法,但在Python中并不推荐。Python通过单下划线约定(如self.__name)暗示内部变量不应直接访问,但这并非强制限制,仍可直接访问。若需对变量进行额外操作,建议使用@property装饰器进行封装,直接访问会引发错误。关于类与对象的详细内容将在后续章节展开。
在Python交互环境中输入import this,可查看到以下内容:
The Zen of Python, by Tim Peters Beautiful is better than ugly. 优美胜于丑陋 Explicit is better than implicit. 明了胜于晦涩 Simple is better than complex. 简单胜过复杂 Complex is better than complicated. 复杂胜过凌乱 Flat is better than nested. 扁平胜于嵌套 Sparse is better than dense. 间隔胜于紧凑
上述内容为Python的设计哲学,虽未完全列出,但在编写Python代码时建议遵循这些原则。
第一个功能。
若需编写代码判断变量a是否大于2且小于10,多数人可能使用a > 2 && a < 10。在Python中,可直接使用2 < a < 10实现链式比较。
a = 5 # 可以这样 print(2 < a < 10) # 也可以这样 print(10 > a <= 9)
True True
另一个广为人知的技巧是无需中间变量即可就地交换值。
a = 2 b = 3 print(a, b) # 直接交换 a, b = b, a print(a, b)
2 3 3 2
第二个功能。
通常需使用for循环遍历序列中的值并执行操作。在其他语言中,代码可能如下所示:
a = ['a', 'b', 'c', 'd', 'e'] for(int i = 0; i < len(a); i++): print(a[i])
在Python中,许多人会利用range生成序列并遍历a的长度。
a = ['a', 'b', 'c', 'd', 'e'] # 对a的长度使用range生成一个序列,然后遍历 for i in range(len(a)): print(a[i])
a b c d e
实际上,可直接使用enumerate方法,它将返回序列的下标和对应值。
a = ['a', 'b', 'c', 'd', 'e'] # 对a的长度使用range生成一个序列,然后遍历 for i in enumerate(a): print(i) # 或者这样 for index, value in enumerate(a): print(index, value)
(0, 'a') (1, 'b') (2, 'c') (3, 'd') (4, 'e') 0 a 1 b 2 c 3 d 4 e
第三个功能。
一般情况下,循环语句与条件判断语句相互独立,if后接else,for后接in。然而,循环语句后也可跟随else子句。for之后接else的含义是:执行完循环后,再执行else中的语句。
for i in foo:
if i == 0:
break
else:
print("i was never 0")
除了for循环,while和try/except之后也可跟随else子句。
第四个功能。
熟悉字典的开发者知道,若需获取字典中某键的值,可使用d['key']。若key不存在,将抛出异常。为避免此问题,可使用d.get('key'),当key不存在时默认返回None,从而无需处理异常。此外,还可使用d.get('key', 0),其中第二个参数指定key不存在时返回的替代值。
第五个功能。
正则表达式常令人头疼,若能添加注释以便理解代码逻辑,将极大提升可读性。在Python中,可实现如下方式:
# 对每一个规则使用引号括起来
pattern = (
"^" # beginning of string
"M{0,4}" # thousands - 0 to 4 M's
"(CM|CD|D?C{0,3})" # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
# or 500-800 (D, followed by 0 to 3 C's)
"(XC|XL|L?X{0,3})" # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
# or 50-80 (L, followed by 0 to 3 X's)
"(IX|IV|V?I{0,3})" # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
# or 5-8 (V, followed by 0 to 3 I's)
"$" # end of string
)
print(pattern)
# 然后bapattern放入对应的re匹配方法中。
^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
第六个功能。
在上一篇关于迭代器和生成器的文章中提到,iter()函数可生成迭代器,随后可使用循环或next方法获取值。实际上,iter还接受第二个参数,其作用是在迭代过程中遇到该参数时停止。示例如下:
def seek_next_line(f): for c in iter(lambda: f.read(1),'\n'): pass
上述代码中,从文件对象f中循环读取,若遇到\n则停止读取。
其他技巧如使用生成器表达式、利用拆包方法等,此前已有提及,此处不再赘述。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









