Làm cách nào tôi có thể ngắt dòng (tiếp tục dòng) trong Python?


1076

Tôi có một dòng mã dài mà tôi muốn chia ra giữa nhiều dòng. Tôi sử dụng cái gì và cú pháp là gì?

Ví dụ: thêm một chuỗi các chuỗi,

e = 'a' + 'b' + 'c' + 'd'

và có hai dòng như thế này:

e = 'a' + 'b' +
    'c' + 'd'

Câu trả lời:


1212

Dòng này là gì? Bạn chỉ có thể có các đối số trên dòng tiếp theo mà không có bất kỳ vấn đề nào:

a = dostuff(blahblah1, blahblah2, blahblah3, blahblah4, blahblah5, 
            blahblah6, blahblah7)

Nếu không, bạn có thể làm một cái gì đó như thế này:

if a == True and \
   b == False

Kiểm tra hướng dẫn phong cách để biết thêm thông tin.

Từ dòng ví dụ của bạn:

a = '1' + '2' + '3' + \
    '4' + '5'

Hoặc là:

a = ('1' + '2' + '3' +
    '4' + '5')

Lưu ý rằng hướng dẫn kiểu nói rằng sử dụng tiếp tục ngầm với dấu ngoặc đơn được ưu tiên, nhưng trong trường hợp cụ thể này, chỉ cần thêm dấu ngoặc đơn xung quanh biểu thức của bạn có lẽ là cách sai.


35
Trên thực tế, bạn có sở thích của hướng dẫn phong cách chính xác ngược. Tiếp tục ngầm được ưu tiên, dấu gạch chéo rõ ràng chỉ được sử dụng nếu cần thiết.
Carl Meyer

35
Carl: Tôi không đồng ý, đây là từ hướng dẫn: Cách gói hàng dài ưa thích là sử dụng tiếp tục dòng ngụ ý của Python bên trong dấu ngoặc đơn, dấu ngoặc và dấu ngoặc nhọn. Nếu cần, bạn có thể thêm một cặp dấu ngoặc đơn xung quanh một biểu thức, nhưng đôi khi sử dụng dấu gạch chéo ngược có vẻ tốt hơn.
Jerub

15
Phần quan trọng của trích dẫn hướng dẫn kiểu là "Nếu cần, bạn có thể thêm một cặp dấu ngoặc đơn xung quanh một biểu thức, nhưng đôi khi sử dụng dấu gạch chéo ngược có vẻ tốt hơn." Hướng dẫn phong cách không nói rằng bạn nên thêm dấu ngoặc đơn, nó để nó theo phán đoán của người viết.
Tony Meyer

23
Có lẽ PEP-8 đã thay đổi kể từ khi những bình luận này được thêm vào, vì giờ đây khá rõ ràng rằng các dấu ngoặc đơn nên được thêm vào để bọc các dòng dài: "Các dòng dài có thể bị phá vỡ trên nhiều dòng bằng cách gói các biểu thức trong ngoặc đơn."
Daniel

46
PEP8 thực sự đã thay đổi vào năm 2010 - "đôi khi sử dụng dấu gạch chéo ngược có vẻ tốt hơn" đã biến mất.
e100

230

Từ PEP 8 - Hướng dẫn kiểu cho mã Python :

Cách gói hàng dài ưa thích là sử dụng tiếp tục dòng ngụ ý của Python bên trong dấu ngoặc đơn, dấu ngoặc và dấu ngoặc. Các dòng dài có thể được chia thành nhiều dòng bằng cách gói các biểu thức trong ngoặc đơn. Chúng nên được sử dụng theo sở thích để sử dụng dấu gạch chéo ngược để tiếp tục dòng.

Dấu gạch chéo ngược có thể vẫn thích hợp vào các thời điểm. Ví dụ: dài, nhiều câu lệnh có thể sử dụng tiếp tục ngầm định, do đó dấu gạch chéo ngược đượ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 trường hợp như vậy là với tuyên bố khẳng định.

Hãy chắc chắn để thụt dòng tiếp tục một cách thích hợp. Vị trí ưa thích để ngắt xung quanh toán tử nhị phân là sau toán tử, không phải trước toán tử. Vài ví dụ:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

PEP8 hiện khuyến nghị quy ước ngược lại (để phá vỡ các hoạt động nhị phân) được sử dụng bởi các nhà toán học và nhà xuất bản của họ để cải thiện khả năng đọc.

Phong cách phá vỡ của Donald Knuth trước một toán tử nhị phân sắp xếp các toán tử theo chiều dọc, do đó giảm khối lượng công việc của mắt khi xác định các mục nào được thêm và trừ.

Từ PEP8: Nên ngắt dòng trước hay sau toán tử nhị phân? :

Donald Knuth giải thích quy tắc truyền thống trong loạt Máy tính và Sắp chữ của mình: "Mặc dù các công thức trong một đoạn luôn bị phá vỡ sau các hoạt động và quan hệ nhị phân, các công thức được hiển thị luôn bị phá vỡ trước các hoạt động nhị phân" [3].

Theo truyền thống từ toán học thường dẫn đến mã dễ đọc hơn:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

Trong mã Python, được phép phá vỡ trước hoặc sau toán tử nhị phân, miễn là quy ước nhất quán cục bộ. Đối với mã mới, phong cách của Knuth được đề xuất.

[3]: TeXBook của Donald Knuth, trang 195 và 196


3
Lưu ý về khuyến nghị đã thay đổi trong năm 2010: "Các dòng dài có thể bị phá vỡ ... bằng cách gói các biểu thức trong ngoặc đơn. Chúng nên được sử dụng để ưu tiên sử dụng dấu gạch chéo ngược ..." và tất cả dấu gạch chéo ngược đã bị xóa khỏi ví dụ mã.
e100

1
@ e100: đọc văn bản in đậm ở trên: The preferred way .. is by using Python's implied line continuation inside parenthesesđó là điều tương tự như by wrapping expressions in parentheses. Tôi đã cập nhật ví dụ
jfs 17/03/2016

10
Nhưng lưu ý rằng "đôi khi sử dụng dấu gạch chéo ngược có vẻ tốt hơn" cũng đã biến mất.
e100


6
Vào năm 2015, hướng dẫn về phong cách đã được cập nhật để thực sự thích phá vỡ trước các nhà khai thác nhị phân sau khi nghiên cứu của Donald Knuth do những cải tiến về khả năng đọc.
J2C

70

Điều nguy hiểm trong việc sử dụng dấu gạch chéo ngược để kết thúc một dòng là nếu khoảng trắng được thêm vào sau dấu gạch chéo ngược (tất nhiên, rất khó nhìn thấy), dấu gạch chéo ngược không còn làm như bạn nghĩ.

Xem Thành ngữ Python và Thành ngữ chống đối (đối với Python 2 hoặc Python 3 ) để biết thêm.


8
Đây là một lý do mà thật tuyệt khi có thể nhìn thấy khoảng trắng ở cuối tốt hơn; tức là một cái gì đó như set list listchars=trail:·trong vim. :)
Beau

25

Đặt một \ở cuối dòng của bạn hoặc gửi tuyên bố trong parens ( .. ). Từ IBM :

b = ((i1 < 20) and
     (i2 < 30) and
     (i3 < 40))

hoặc là

b = (i1 < 20) and \
    (i2 < 30) and \
    (i3 < 40)

24

Bạn có thể ngắt dòng ở giữa dấu ngoặc đơn và dấu ngoặc nhọn. Ngoài ra, bạn có thể nối ký tự dấu gạch chéo ngược \vào một dòng để ngắt nó một cách rõ ràng:

x = (tuples_first_value,
     second_value)
y = 1 + \
    2

20

Từ miệng ngựa: Tham gia đường dây rõ ràng

Hai hoặc nhiều dòng vật lý có thể được nối thành các dòng logic bằng cách sử dụng các ký tự dấu gạch chéo ngược ( \), như sau: khi một dòng vật lý kết thúc bằng dấu gạch chéo ngược không phải là một phần của chuỗi ký tự hoặc nhận xét, nó được nối với dòng sau tạo thành một dòng logic duy nhất , xóa dấu gạch chéo ngược và ký tự cuối dòng sau. Ví dụ:

if 1900 < year < 2100 and 1 <= month <= 12 \
   and 1 <= day <= 31 and 0 <= hour < 24 \
   and 0 <= minute < 60 and 0 <= second < 60:   # Looks like a valid date
        return 1

Một dòng kết thúc bằng dấu gạch chéo ngược không thể mang bình luận. Dấu gạch chéo ngược không tiếp tục bình luận. Dấu gạch chéo ngược không tiếp tục mã thông báo ngoại trừ chuỗi ký tự (nghĩa là mã thông báo khác với chuỗi ký tự chuỗi không thể được phân chia trên các dòng vật lý bằng cách sử dụng dấu gạch chéo ngược). Dấu gạch chéo ngược là bất hợp pháp ở nơi khác trên một dòng bên ngoài một chuỗi ký tự.


7
-1 vì ví dụ là IMO không phổ biến. Thay vào đó, các điều kiện phức hợp hoàn toàn có thể có dấu ngoặc kèm theo, điều này thực tế hơn (để chỉnh sửa hoặc tự động sửa lại) và thành ngữ.
u0b34a0f6ae

4

Nó có thể không phải là cách Pythonic, nhưng tôi thường sử dụng một danh sách với hàm nối để viết một chuỗi dài, như các truy vấn SQL:

query = " ".join([
    'SELECT * FROM "TableName"',
    'WHERE "SomeColumn1"=VALUE',
    'ORDER BY "SomeColumn2"',
    'LIMIT 5;'
])

2

Lấy từ Hướng dẫn của Hitchhiker về Python ( Tiếp tục dòng ):

Khi một dòng mã logic dài hơn giới hạn được chấp nhận, bạn cần chia nó thành nhiều dòng vật lý. Trình thông dịch Python sẽ nối các dòng liên tiếp nếu ký tự cuối cùng của dòng là dấu gạch chéo ngược. Điều này hữu ích trong một số trường hợp, nhưng thường nên tránh vì tính dễ vỡ của nó: một khoảng trắng được thêm vào cuối dòng, sau dấu gạch chéo ngược, sẽ phá vỡ mã và có thể có kết quả không mong muốn.

Một giải pháp tốt hơn là sử dụng dấu ngoặc đơn xung quanh các yếu tố của bạn. Còn lại với dấu ngoặc đơn không được tiết lộ ở cuối dòng, trình thông dịch Python sẽ nối dòng tiếp theo cho đến khi dấu ngoặc đơn được đóng. Các hành vi tương tự giữ cho niềng răng xoăn và vuông.

Tuy nhiên , thường xuyên hơn không, việc phải phân chia một dòng logic dài là một dấu hiệu cho thấy bạn đang cố gắng làm quá nhiều việc cùng một lúc, điều này có thể cản trở khả năng đọc.

Như đã nói, đây là một ví dụ xem xét nhiều lần nhập (khi vượt quá giới hạn dòng, được xác định trên PEP-8 ), cũng được áp dụng cho các chuỗi nói chung:

from app import (
    app, abort, make_response, redirect, render_template, request, session
)

1

Nếu bạn muốn ngắt dòng của mình vì một chuỗi chữ dài, bạn có thể chia chuỗi đó thành từng mảnh:

long_string = "a very long string"
print("a very long string")

sẽ được thay thế bởi

long_string = (
  "a "
  "very "
  "long "
  "string"
)
print(
  "a "
  "very "
  "long "
  "string"
)

Đầu ra cho cả hai câu lệnh in:

a very long string

Lưu ý dấu ngoặc trong ảnh hưởng.

Cũng lưu ý rằng việc ngắt các chuỗi ký tự thành các phần cho phép chỉ sử dụng tiền tố bằng chữ trên các phần của chuỗi:

s = (
  "2+2="
  f"{2+2}"
)

0

Sử dụng toán tử tiếp tục dòng tức là "\"

Ví dụ:

# Ex.1

x = 1
s =  x + x**2/2 + x**3/3 \
       + x**4/4 + x**5/5 \
       + x**6/6 + x**7/7 \
       + x**8/8
print(s)
# 2.7178571428571425


----------


# Ex.2

text = ('Put several strings within parentheses ' \
        'to have them joined together.')
print(text)


----------


# Ex.3

x = 1
s =  x + x**2/2 \
       + x**3/3 \
       + x**4/4 \
       + x**6/6 \
       + x**8/8
print(s)
# 2.3749999999999996
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.