2015-08-14 16 views
6

cách pythonic để là gì Pep-8-IFY chẳng hạn như với tuyên bố:Giữ 80 ký tự ký tự cho câu lệnh dài?

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 

tôi có thể làm điều này nhưng kể từ khi tempfile i/o không phải là với tuyên bố with, hiện nó tự động đóng sau khi có ? Là pythonic ?:

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 

Hoặc tôi có thể sử dụng dấu gạch chéo:

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 

Nhưng là PEP8 tuân-thể? Đó là pythonic?

+1

Có một phần trong [PEP8] (https://www.python.org/dev/peps/pep-0008/#maximum-line-length) về độ dài dòng tối đa – GP89

+1

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

+1

có thể trùng lặp của [Làm thế nào để phá vỡ một tuyên bố dài trong python] (http://stackoverflow.com/questions/16080049/how-to-break-a-long-with-statement-in-python) – mkrieger1

Trả lời

3

PEP 0008 does say it's ok để sử dụng dấu gạch chéo ngược cho một dòng with.

Các dấu gạch chéo ngược đôi khi vẫn có thể thích hợp. Ví dụ, dài, nhiều với báo cáo-không thể sử dụng tiếp tục ngầm, do đó, dấu gạch chéo ngược là chấp nhận được.

Mặc dù nó khuyên họ được thụt vào, vì vậy dòng của bạn nên được như thế này:

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 

Đó là khuyến cáo bạn giữ nó thụt vào một lượng khác biệt rõ rệt khoảng trống để các khối mã sau đây, do đó, nó rõ ràng hơn nơi có dòng kết thúc và khối bắt đầu.

Tuy nhiên bạn không thực sự cần sử dụng dấu gạch chéo nếu bạn gửi kèm theo các thông số trong ngoặc

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ều đó phụ thuộc vào sự sắp xếp câu chính xác của bạn tất nhiên và mileage của bạn có thể thay đổi vào việc có một khung ở cuối dòng là bất kỳ tốt hơn so với dấu gạch chéo ngược.

1

PEP-8 thực sự đưa ra ví dụ về hai tình huống tương tự:

Ví dụ 1 (trông dễ áp ​​dụng nhất, vì nó sử dụng with báo cáo):

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

Ví dụ 2:

class Rectangle(Blob): 

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

Có vẻ như slashes là một cách cho phép xử lý này (nhưng cuối cùng không cần thiết, nếu bạn bọc params tập tin của bạn trong ngoặc đơn).

3

PEP 8 không quá rõ ràng về điều đó. Nó chỉ đề cập đến tuyên bố with một lần cho một trường hợp ngoại lệ khi tiếp tục dấu gạch chéo ngược là không sao:

Dấu gạch chéo ngược đôi khi vẫn có thể thích hợp.Ví dụ, rất lâu, nhiều với -statements không thể sử dụng tiếp tục tiềm ẩn, vì vậy backslashes được chấp nhận:

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

Một cách để khắc phục những vấn đề này sẽ được thực sự đầu tiên thực hiện cuộc gọi hàm trả về người quản lý bối cảnh và sau đó chỉ cần sử dụng trực tiếp, như bạn đã gợi ý trong câu hỏi của bạn:

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

này hoạt động hoàn hảo (vì tuyên bố with chỉ sẽ gọi các phương thức quản lý bối cảnh của, bất kể nó đến từ đâu), và cũng có thể đóng xử lý một cách chính xác .

Tuy nhiên, điều này là không được phép explicitely trong PEP 8:

nhà quản lý Bối cảnh nên được gọi thông qua chức năng hoặc các phương pháp riêng biệt mỗi khi họ làm điều gì đó khác hơn là tiếp thu và giải phóng tài nguyên. Ví dụ:

Có:

with conn.begin_transaction(): 
    do_stuff_in_transaction(conn) 

Số:

with conn: 
    do_stuff_in_transaction(conn) 

Ví dụ thứ hai không cung cấp bất kỳ thông tin để chỉ ra rằng các __enter____exit__ phương pháp đang làm một cái gì đó khác hơn là đóng kết nối sau một giao dịch. Rõ ràng là quan trọng trong trường hợp này.

Vì vậy, cuối cùng, có vẻ là không có giải pháp thực sự mà được phép bởi PEP 8. Và vào thời điểm đó, tôi sẽ tranh luận, rằng nó hoàn toàn tốt đẹp để “vi phạm nó” và đi ngược lại nó: Nó chỉ một phong cách hướng dẫn.

Trong khi nó gợi ý nhiều quy tắc tốt, cũng có nhiều tình huống, trong đó đơn giản là không có ý nghĩa gì khi theo dõi chúng một cách nghiêm túc. Tôi cho rằng ví dụ bằng cách sử dụng dấu gạch chéo là khó có thể đọc được, và có lẽ bạn có thể đọc được nó tốt hơn rất nhiều nếu bạn cho phép dòng lâu hơn và chỉ phá vỡ đường dây một lần mỗi quản lý bối cảnh:

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 

Có, bạn có thể cần phải di chuyển cho điều này, nhưng ít nhất bạn có thể thấy rất rõ những gì đang xảy ra.

Một lựa chọn khác sẽ được thực sự khởi tạo các đối tượng trực tiếp trước khi 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 

Kể từ khi bạn làm điều đó trực tiếp trước khi with, nó phải là một ngoại lệ có thể chấp nhận từ PEP 8 quy tắc ở đây. Sau khi tất cả, nó cải thiện khả năng đọc, và đó là những gì đếm.

Btw. lưu ý rằng người quản lý ngữ cảnh không thể trả lại self trên __enter__, vì vậy bạn vẫn nên sử dụng cú pháp as để chỉ định giá trị trả lại của trình quản lý ngữ cảnh cho một biến.


Cuối cùng, một lựa chọn khác, mà sẽ làm việc cho tình hình cụ thể của bạn, sẽ được quấn cuộc gọi của bạn thành một chức năng riêng biệt:

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 

Vì vậy, về cơ bản, trừu tượng tất cả mọi thứ đi, do đó tuyên bố with có thể đọc lại được.

+1

Oh, a downvote bởi một zealot PEP 8? – poke

+0

PEP8 zealot, đẹp quá! – alvas

Các vấn đề liên quan