Python实用基础技巧:元组参数、命名切片与上下文管理器
本文总结Python中几项实用但常被忽视的基础技巧。涵盖利用元组简化startswith/endswith判断、通过start参数控制enumerate索引、使用slice对象命名切片提升代码可读性、在with语句中同时管理多个资源,以及for/while/try语句中else子句的正确使用场景与异常处理规范。
前言
本文整理并介绍了Python中几项实用且常被忽视的基础技巧,旨在为读者提供参考与学习价值。以下是具体内容的详细介绍。
1. startswith()和endswith()支持元组参数
在判断字符串是否以特定前缀或后缀开头/结尾时,若需匹配多个值,可直接将待检测的值组合为元组,作为startswith()或endswith()方法的参数。
# bad
if image.endswith('.jpg') or image.endswith('.png') or image.endswith('.gif'):
pass
# good
if image.endswith(('.jpg', '.png', '.gif')):
pass
# bad
if url.startswith('http:') or url.startswith('https:') or url.startswith('ftp:'):
pass
# good
if url.startswith(('http:', 'https:', 'ftp:')):
pass
2. enumerate()设置start参数指定索引起始值
在使用enumerate()进行迭代并需要获取索引时,可通过start参数指定索引的起始数值,从而避免手动调整索引值。
# bad for index, v in enumerate(data): print(index+1, v) # good for index, v in enumerate(data, start=1): print(index, v)
3. 对切片进行命名
当代码中大量出现硬编码的切片索引时,可读性会显著降低。通过为切片命名可以有效解决这一问题。
record = '....................100.................513.25......' # bad cost = int(record[20:23]) * float(record[40:46]) # good SHARES = slice(20, 23) PRICE = slice(40, 46) cost = int(record[SHARES]) * float(record[PRICE])
一般而言,代码中若存在大量硬编码索引值,将导致可读性和可维护性变差。内置的slice()函数可用于创建切片对象,该对象可应用于任何支持切片操作的场景。例如:
>>> items = [0, 1, 2, 3, 4, 5, 6] >>> a = slice(2, 4) >>> items[2:4] [2, 3] >>> items[a] [2, 3] >>> items[a] = [-2, -3] >>> items [0, 1, -2, -3, 4, 5, 6] >>> del items[a] >>> items [0, 1, 4, 5, 6] >>>
4. 上下文管理器可同时管理多个资源
假设需要读取一个文件的内容,处理后写入另一个文件。为了写出符合Python风格的代码,通常会使用上下文管理器,并可能写出如下代码:
with open('input.txt', 'r') as source:
with open('output.txt', 'w') as target:
target.write(source.read())
虽然上述写法已不错,但上下文管理器支持同时管理多个资源,因此上面的代码可以优化为:
with open('input.txt', 'r') as source, open('output.txt', 'w') as target:
target.write(source.read())
5. else子句的用法
Python中的else子句不仅可用于if语句,还可用于for、while以及try语句中。
对于for循环或while循环,仅当循环正常结束(即未通过break语句、return语句或异常退出)时,才会执行else块。
举例说明:
>>> for i in range(3):
... print(i)
... else:
... print('Iterated over everything')
...
0
1
2
Iterated over everything
>>>
如上所示,当for循环正常结束时,会执行随后的else块。
>>> for i in range(3):
... if i == 2:
... break
... print(i)
... else:
... print('Iterated over everything')
...
0
1
>>>
反之,若for循环因break语句提前结束,则不会执行后续的else块。
对于try语句,仅当try块中未抛出异常时,才会执行else块。初看之下,可能觉得在try/except块中使用else子句并无必要。毕竟,在以下代码片段中,只有当dangerous_call()不抛出异常时,after_call()才会执行,对吗?
try:
dangerous_call()
after_call()
except OSError:
log('OSError...')
然而,after_call()不应放在try块中。为了保持代码清晰明确,try块中应仅包含可能抛出预期异常的语句。因此,更推荐的写法如下:
try:
dangerous_call()
except OSError:
log('OSError...')
else:
after_call()
此时逻辑更为清晰:try块专门用于防护dangerous_call()可能引发的错误,而非after_call()。同时需明确,只有当try块不抛出异常时,才会执行after_call()。但需注意一点:else子句中抛出的异常不会被前面的except子句捕获,这意味着若after_call()抛出异常,将不会被之前的except块处理。
如需了解更多Python技巧,可参考此文:https://www.jb51.net/article/137695.htm
总结
以上就是本文的全部内容,希望这些技巧对您的学习或工作有所助益。如有疑问,欢迎留言交流,感谢支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













