PEP 8对此不太清楚。它只提到with
声明一次例外时backslashe延续是好的:
反斜杠有时可能仍然适当。例如,长,多与-statements不能使用隐式的延续,所以反斜线是可以接受的:
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
克服的问题是确实先进行函数调用返回上下文管理器,然后一个办法只需要使用直接,因为你已经在你的问题建议:
file_1 = open('/path/to/some/file/you/want/to/read')
file_2 = open('/path/to/some/file/being/written', 'w')
with file_1, file_2:
file_2.write(file_1.read())
这工作完全(因为with
声明只会调用上下文管理的方法,不管它来自哪里),也正确关闭句柄。
然而,这明确地禁止在PEP 8:
上下文管理者应通过单独的函数或方法时,他们做的比获取和释放资源的其他东西调用。例如:
是:
with conn.begin_transaction():
do_stuff_in_transaction(conn)
号:
with conn:
do_stuff_in_transaction(conn)
后者例如不提供任何信息,表明__enter__
和__exit__
方法做其他的东西比关闭连接交易后。在这种情况下,明确是很重要的。
那么到底,似乎是已通过PEP 8.而在这一点上不允许有真正的解决方案,我认为,它是完美的罚款,以“侵犯其”去反对它:这只是一种风格指南。
虽然它提出了很多很好的规则,但也有许多情况下,严格遵守它们根本没有多大意义。我认为,用斜杠你的例子几乎没有可读的,你也许可以读它好多了,如果你允许更长的线和刚刚打破行每上下文管理器一次:
with tempfile.NamedTemporaryFile(prefix='malt_input.conll.', dir=self.working_dir, mode='w', delete=False) as input_file, \
tempfile.NamedTemporaryFile(prefix='malt_output.conll.', dir=self.working_dir, mode='w', delete=False) as output_file:
pass
是的,你可能需要滚动为此,但至少你可以清楚地看到发生了什么。
另一种方法是在with
前直接实际初始化的对象:
malt_input = tempfile.NamedTemporaryFile(prefix='malt_input.conll.', dir=self.working_dir, mode='w', delete=False)
malt_output = tempfile.NamedTemporaryFile(prefix='malt_output.conll.', dir=self.working_dir, mode='w', delete=False)
with malt_input as input_file, malt_output as output_file:
pass
既然你直接在with
之前做到这一点,它应该是从这里PEP 8规则可接受的例外。毕竟,它提高了可读性,这就是重中之重。
Btw。请注意,上下文管理器可能不会返回self
__enter__
,因此仍应使用as
语法将上下文管理器的返回值分配给变量。
最后,另外一个选择,这会为您的特定情况下工作,会来包装你的电话到一个单独的功能:
def namedTemp(prefix):
return tempfile.NamedTemporaryFile(prefix=prefix,
dir=self.working_dir, mode='w', delete=False)
with namedTemp('malt_input.conll.') as input_file, \
namedTemp('malt_output.conll.') as output_file:
pass
所以基本上,抽象的一切的,所以with
声明再次变得可读。
在[PEP8](https://www.python.org/dev/peps/pep-0008/#maximum-line-length)中有关于最大行长度的部分 – GP89
[Beyond PEP8](https:// www.youtube.com/watch?v=wf-BqAjZb8M)! – mkrieger1
可能重复的[如何在python中声明一个long](http://stackoverflow.com/questions/16080049/how-to-break-a-long-with-statement-in-python) – mkrieger1