Python的禅宗vs带陈述的哲学思考

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的禅宗”的第五行“扁平比嵌套好”相反?任何开明的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)