Python的禅宗vs带陈述的哲学思考
我不想简单地浪费你的时间,但是:当你使用Python的Python的禅宗vs带陈述的哲学思考,python,coding-style,indentation,with-statement,zen-of-python,Python,Coding Style,Indentation,With Statement,Zen Of Python,我不想简单地浪费你的时间,但是:当你使用Python的和语句时,你是否也想到了它真的与“Python的禅宗”的第五行“扁平比嵌套好”相反?任何开明的Python大师都能与我分享他们对此的一些见解吗? (我总是发现每次我使用with而不是f.close()…我的代码中都会弹出一个更高级别的缩进,而且我并不是不打算使用try:…最后:…无论如何,with的好处仍然让我难以捉摸,即使我越来越喜欢和理解Python了……) @GLGL(对不起,我找不到在注释中编写代码的方法): 是的,但是如果您以的方
和语句时,你是否也想到了它真的与“Python的禅宗”的第五行“扁平比嵌套好”相反?任何开明的Python大师都能与我分享他们对此的一些见解吗?
(我总是发现每次我使用with
而不是f.close()
…我的代码中都会弹出一个更高级别的缩进,而且我并不是不打算使用try:…最后:…
无论如何,with
的好处仍然让我难以捉摸,即使我越来越喜欢和理解Python了……)
@GLGL(对不起,我找不到在注释中编写代码的方法): 是的,但是如果您以的方式执行,您的代码将变成:
try:
with file(...) as f:
...
except IOError:
...
…使用just with而不使用
try
是人们在hacky“one use”代码类型中的最终做法,他们使用f.close()
而不是使用任何方式(这很糟糕,因为如果在f.close()
之前抛出异常,文件可能无法关闭),因此对于“hacky”编写代码的人不会将与一起使用,因为我不知道,我想他们只是觉得它太“花哨”,而且对于结构良好的代码来说,它无论如何也不会带来任何好处,所以在我看来,它没有实际的用例了。。。这是我真正思考的问题。你已经提到了:这样做更干净
f = file(...)
try:
# do work on file
finally:
f.close()
而不仅仅是在文件操作后关闭-如果发生异常,将无法访问该操作
如果将try/finally
与与进行比较,则缩进级别相同,因此不会丢失任何内容。但是,如果您执行异常处理,那么您还有一个缩进级别,这确实与所说的Zen点相反
OTOH,with
封装了东西,使使用它们更容易,更可读,这是禅宗的另一个方面
对我来说,似乎不可能总是完全遵循禅宗的每一个方面;有时你必须权衡一个和另一个。在这种情况下,您“丢失”了一级缩进,但获得了更好的可读性和可维护性。后者对我来说似乎是一个优势。请注意,Python的禅宗也说:
简单总比复杂好
复杂总比复杂好
及
可读性很重要
在with
语句中使用上下文管理器可以提供多种功能:
- 正确的行为,因为文件始终处于关闭状态
- 可读性(
以开放(..)作为f
是可以理解的)
您不能指着Python的Zen中的一项,争辩说所有Python代码必须始终满足所有项。例如,如果以可读且正确的方式解决特定问题的最小缩进级别为4,那么就这样吧:如果缩进级别为3会降低代码的可读性,那么就不要管代码(4是好的)
那么,什么是平的
import thirdparty
print "I Like Pie!"
vs
等等
Python的Zen不只是在代码上强制执行缩进限制。它鼓励您编写可读(从而更好)的代码。
如果您的with
语句位于只能由3层对象访问的函数中(etc,one.two.three.func()
),则这是一个问题
否则,三个缩进级别与任何缩进级别一样好。选择与
的原因是,您不需要手动配对相关操作(例如open(…)
/.close()
;但是与的构造更通用——不仅用于处理文件)。这一点很重要,即当第二个操作可能由于源代码中看不清楚的原因而无法执行时。你是在告诉机器替我照顾好它,而且机器比人好。通过这种方式,您可以消除组中可能难以发现的严重错误
顺便说一下,您应该使用open(…)
而不是文件(…)
。Python 3对文件(…)
一无所知,否则您将不得不在以后修复代码。是的,声明“扁平比嵌套好”,但这不是我们关心的唯一特性;它还说“简单比复杂好”。with
的美妙之处在于,它实际上遵守了这些原则中的两个原则,我将在下面解释
每当您发现自己在哲学上思考Python中的某个特性时,您都可能需要查阅相关资料,了解该特性背后的动机。在这种情况下,它在摘要中提前说明:
此PEP向Python语言添加了一个新语句“with”,以使其
可以排除try/finally语句的标准用法
分解出try/finally
语句可以使代码更简单、更可读
然而,这比提供一些简单的语法糖更深入。它建立了一个上下文管理器协议:
语句中紧跟在with关键字后面的表达式
是一个“上下文表达式”,因为该表达式提供了以下主要线索:
到运行时环境,上下文管理器为
语句体的持续时间
使用上下文管理器协议,API编写器可以帮助隐藏复杂性,并确保在多线程上下文中正确获取/释放资源
但是,
with
语句的真正美妙之处如示例12所示,其中说明:
“嵌套”上下文管理器,自动嵌套提供的
上下文从左到右,以避免过度缩进
使用nested()
上下文管理器,可以获取如下代码:
with a as x:
with b as y:
with c as z:
# Perform operation
把它变成这样:
with nested(a, b, c) as (x, y, z):
# Perform operation
注意,nested()
with a as x:
with b as y:
with c as z:
# Perform operation
with nested(a, b, c) as (x, y, z):
# Perform operation
with a as x, b as y, c as z:
# Perform operation
from itertools import izip
with open("/etc/passwd") as a, open("/etc/group") as b, open("/etc/shadow") as c:
for lines in izip(a,b,c):
print map(lambda x: x.split(':')[0], lines)