2015-08-14 68 views
6

什么是对Python的方式PEP-8-IFY如用声明:保留80个字符的保证金长期与声明?

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 

我能做到这一点,但因为临时文件I/O是不与with声明,不是自动关闭后用?是Python的?:

intemp = tempfile.NamedTemporaryFile(prefix='malt_input.conll.', dir=self.working_dir, mode='w', delete=False) 

outtemp = tempfile.NamedTemporaryFile(prefix='malt_output.conll.', dir=self.working_dir, mode='w', delete=False) 

with intemp as input_file, outtemp as output_file: 
    pass 

或者我可以使用斜线:

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 

不过是PEP8遵守,能?那是pythonic?

+1

在[PEP8](https://www.python.org/dev/peps/pep-0008/#maximum-line-length)中有关于最大行长度的部分 – GP89

+1

[Beyond PEP8](https:// www.youtube.com/watch?v=wf-BqAjZb8M)! – mkrieger1

+1

可能重复的[如何在python中声明一个long](http://stackoverflow.com/questions/16080049/how-to-break-a-long-with-statement-in-python) – mkrieger1

回答

3

PEP 0008 does say it's ok使用反斜杠作为with行。

反斜杠有时可能仍然适用。例如,long,multiple with -statements不能使用隐式延续,所以反斜杠是可以接受的。

虽然建议他们被缩进,所以你行应该是这样的:

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行结束并且块开始。

但是你实际上并不需要如果用方括号中的参数用斜线

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 

但这取决于当然您的确切语句布置,而且你可以在是否具有支架变化在一行的结尾是比反斜杠更好的。

1

PEP-8实际上给出了两个类似情况的例子:

例1(看起来最适用,因为它使用with语句):

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()) 

例2:

class Rectangle(Blob): 

    def __init__(self, width, height, 
       color='black', emphasis=None, highlight=0): 

它看起来像斜线是处理这种(但最终不必要的,如果你用括号包装你的文件参数)的允许的方式。

3

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声明再次变得可读。

+1

哦,一个由PEP 8狂热者冷静下来? – poke

+0

PEP8狂​​热者,不错! – alvas