ฉันจะแบ่งสายยาว ๆ ใน Python ได้อย่างไร?


176

คุณจะจัดรูปแบบเส้นยาวเช่นนี้อย่างไร ฉันต้องการให้กว้างไม่เกิน 80 อักขระ:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

นี่คือตัวเลือกที่ดีที่สุดของฉันหรือไม่

url = "Skipping {0} because its thumbnail was already in our system as {1}."
logger.info(url.format(line[indexes['url']], video.title))

1
ดูเหมือนว่าเป็นตัวเลือกที่ดี คุณไม่ชอบอะไรเกี่ยวกับเรื่องนี้?
Hamish Grubijan

2
ส่วนตัวเล็ก ๆ น้อย ๆ ใช่ไหม? :)
Adam Woś

1
เกี่ยวข้อง: stackoverflow.com/questions/1940710/… (การต่อสตริงในไพ ธ อน)
jldupont

14
คุณสามารถบันทึกอักขระโดยการลบ 'ใน "มัน" ที่ไม่ถูกต้อง
jball

2
indexes: พหูพจน์ที่ถูกต้องของมีindex indices
Scruffy

คำตอบ:


336

นั่นเป็นการเริ่มต้น ไม่ใช่วิธีปฏิบัติที่ไม่ถูกต้องในการกำหนดสตริงที่ยาวกว่าของคุณนอกโค้ดที่ใช้ เป็นวิธีแยกข้อมูลและพฤติกรรม ตัวเลือกแรกของคุณคือการรวมตัวอักษรสตริงเข้าด้วยกันโดยปริยายด้วยการทำให้พวกมันอยู่ติดกัน:

("This is the first line of my text, "
"which will be joined to a second.")

หรือด้วยการต่อเนื่องที่สิ้นสุดบรรทัดซึ่งค่อนข้างบอบบางกว่านี้เล็กน้อยตามที่ได้ผล:

"This is the first line of my text, " \
"which will be joined to a second."

แต่นี่ไม่ใช่:

"This is the first line of my text, " \ 
"which will be joined to a second."

ดูความแตกต่าง? ไม่มี? คุณจะไม่ทำเมื่อมันเป็นรหัสของคุณ

ข้อเสียของการเข้าร่วมโดยนัยคือใช้งานได้กับตัวอักษรสตริงเท่านั้นไม่ใช่กับสตริงที่นำมาจากตัวแปรดังนั้นสิ่งต่างๆจะมีขนดกน้อยลงเมื่อคุณปรับโครงสร้าง นอกจากนี้คุณสามารถแก้ไขการจัดรูปแบบบนสตริงที่รวมกันโดยรวมเท่านั้น

หรือคุณสามารถเข้าร่วมอย่างชัดเจนโดยใช้ตัวดำเนินการเรียงต่อกัน ( +):

("This is the first line of my text, " + 
"which will be joined to a second.")

ชัดแจ้งได้ดีกว่าโดยปริยายเช่นเดียวกับที่เซนของไพ ธ อนพูด แต่สิ่งนี้สร้างสามสายอักขระแทนที่จะเป็นหนึ่งสายและใช้หน่วยความจำมากเป็นสองเท่า: มีสองสายที่คุณเขียนรวมทั้งสองสายที่รวมเข้าด้วยกัน ต้องรู้ว่าเมื่อไหร่ที่จะไม่สนใจเซน ข้อเสียคือคุณสามารถใช้การจัดรูปแบบกับวัสดุย่อยใด ๆ แยกกันในแต่ละบรรทัดหรือกับล็อตทั้งหมดจากนอกวงเล็บ

ในที่สุดคุณสามารถใช้สตริงที่มีการเสนอราคาสามรายการ:

"""This is the first line of my text
which will be joined to a second."""

นี่เป็นสิ่งที่ฉันชอบบ่อยครั้งแม้ว่าพฤติกรรมของมันจะแตกต่างกันเล็กน้อยเนื่องจากขึ้นบรรทัดใหม่และช่องว่างนำหน้าในบรรทัดถัดไปจะปรากฏในสตริงสุดท้ายของคุณ คุณสามารถกำจัดบรรทัดใหม่ด้วยแบ็กสแลชที่กำลังหลบหนี

"""This is the first line of my text \
which will be joined to a second."""

ปัญหานี้มีปัญหาเดียวกันกับเทคนิคเดียวกันข้างต้นในรหัสที่ถูกต้องนั้นจะแตกต่างจากรหัสที่ไม่ถูกต้องโดยช่องว่างที่มองไม่เห็น

สิ่งใดที่ "ดีที่สุด" ขึ้นอยู่กับสถานการณ์เฉพาะของคุณ แต่คำตอบนั้นไม่ใช่แค่สุนทรียภาพ แต่เป็นพฤติกรรมที่แตกต่างกันอย่างหนึ่ง


26
คอมไพเลอร์ CPython ปรับการดำเนินการตามตัวอักษรให้ได้มากที่สุดซึ่งหมายความว่าการเพิ่มตัวอักษรสตริงสองรายการจะทำให้เกิดตัวอักษรสตริงเดียวในไบต์เท่านั้น
Ignacio Vazquez-Abrams

2
ในขณะที่คำตอบทั้งหมดที่ฉันได้รับนั้นมีประโยชน์ แต่คุณก็ช่วยให้ฉันเข้าใจทุกวิธีในการแบ่งสาย ปัญหาของบรรทัด "\" ที่ลงท้ายว่ามีช่องว่างหรือไม่
Gattster

1
ฉันไม่เห็นความแตกต่างที่นี่ แต่ส่วนใหญ่เป็นเพราะการระบายสีไวยากรณ์ดั้งเดิมของ SO (บางรหัสที่ดีอย่างสมบูรณ์นั้นแทบอ่านไม่ได้บน SO แต่เพียงเพราะมันไม่ได้อยู่ในภาษาที่มีไวยากรณ์ใกล้เคียงกับ C. ) ไม่ใช่เรื่องผิดปกติที่จะทำให้บรรณาธิการของคุณเน้นแถบช่องว่างต่อท้ายเนื่องจากพวกเขาไม่ค่อยมีประโยชน์ . :-)
Ken

1
@KhurshidAlam คุณสามารถใช้คำพูดเดียวที่จะมีสตริงที่หรือหนีราคาคู่ภายในสายของคุณหรือใช้คำพูดสองสาม' """ปัญหาของสายอักขระที่มีเครื่องหมายคำพูดจะเหมือนกันไม่ว่าคุณจะใช้บรรทัดเดียวหรือหลายบรรทัดเพื่อกำหนดสตริงตัวอักษร
hugovdberg

1
ตัวแก้ไขของฉันลบช่องว่างต่อท้ายเสมอ ฉันแนะนำให้คุณเปิดใช้งานการตั้งค่าเดียวกัน +แน่นอนแล้วช่องว่างในการขึ้นบรรทัดใหม่ยังคงเป็นส่วนหนึ่งของสตริงดังนั้นฉันสิ้นสุดการใช้
ThaJay

46

ตัวอักษรของสตริงที่ต่อเนื่องกันจะถูกรวมเข้าด้วยกันโดยคอมไพเลอร์และนิพจน์ที่วงเล็บถูกพิจารณาว่าเป็นโค้ดบรรทัดเดียว:

logger.info("Skipping {0} because it's thumbnail was "
  "already in our system as {1}.".format(line[indexes['url']],
  video.title))

11

โดยส่วนตัวแล้วฉันไม่ชอบการแขวนบล็อกแบบเปิดดังนั้นฉันจึงจัดรูปแบบเป็น:

logger.info(
    'Skipping {0} because its thumbnail was already in our system as {1}.'
    .format(line[indexes['url']], video.title)
)

โดยทั่วไปแล้วฉันจะไม่ต้องลำบากใจมากเกินไปที่จะสร้างรหัสให้พอดีภายในบรรทัด 80 คอลัมน์ มันคุ้มค่าที่จะรักษาความยาวบรรทัดให้อยู่ในระดับที่สมเหตุสมผล แต่ขีด จำกัด ที่ยาก 80 เป็นเรื่องในอดีต


8
มันไม่ใช่เรื่องของอดีต ไลบรารีมาตรฐานของ Python ยังคงใช้ PEP8 เป็นแนวทางในการออกแบบดังนั้นกฎยังคงมีอยู่และผู้คนจำนวนมาก (รวมตัวเอง) ติดตามมัน มันเป็นสถานที่ที่สะดวกในการวาดเส้น
Devin Jeanpierre

3
ฉันสงสัยว่าหลายโครงการยังคงปฏิบัติตามกฎถ่าน 80 ตัว สำหรับขนาดหน้าต่างเฉลี่ยที่ฉันใช้ฉันคิดว่า 100-120 มีประสิทธิภาพมากกว่าสำหรับฉันมากกว่า 80 ตัวอักษร
Gattster

1
ใช่นั่นเป็นเรื่องของความยาวบรรทัดที่ฉันใช้ด้วยเช่นกัน [สยองขวัญ! sacrilege!] ฉันใช้ฟอนต์แบบสัดส่วนดังนั้นความยาวบรรทัดที่แน่นอนจึงไม่สำคัญนัก มันเป็นกรณีของจำนวนตรรกะในบรรทัดเดียวที่อ่านได้มากกว่าจำนวนตัวอักษรเช่น ... ถ้าฉันมีข้อมูลจำนวนมากที่ไม่มีใครต้องการอ่านฉันมีความสุขที่ได้ปล่อยให้มันล้น 120.
bobince

แบบอักษรตามสัดส่วนสำหรับรหัส - ฉันอยู่กับคุณพี่ชาย ตัดสินโดยความรังเกียจทุกคนที่ฉันเคยทำงานด้วยมีให้สำหรับพวกเขาว่าโลกยังไม่พร้อม
jlarcombe

4
~ 80 ตัวอักษรทำให้ง่ายขึ้นในการกระจายไฟล์ 2 ไฟล์แบบเคียงข้างกันบนหน้าจอเดียวกัน นอกจากนี้หากคุณทำการดีบั๊กระหว่างเกิดเหตุฉุกเฉินบนคอนโซลของเซิร์ฟเวอร์คุณจะประทับใจกับจำนวนอักขระสูงสุด 80 ตัว! :)
มิก T

4

คุณสามารถใช้โมดูล textwrap เพื่อทำลายมันในหลายบรรทัด

import textwrap
str="ABCDEFGHIJKLIMNO"
print("\n".join(textwrap.wrap(str,8)))

ABCDEFGH
IJKLIMNO

จากเอกสาร :

textwrap wrap (ข้อความ [, width [, ... ]])
ตัดย่อหน้าเดียวในข้อความ (สตริง) เพื่อให้ทุกบรรทัดมีความยาวอักขระที่มีความกว้างสูงสุด ส่งคืนรายการของบรรทัดเอาต์พุตโดยไม่มีบรรทัดใหม่สุดท้าย

อาร์กิวเมนต์คำหลักที่เลือกระบุได้สอดคล้องกับแอตทริบิวต์ของTextWrapperเอกสารด้านล่าง 70ค่าเริ่มต้นของความกว้าง

ดูTextWrapper.wrap()วิธีการสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการทำงานของ wrap ()


2

สำหรับใครที่ยังเป็นความพยายามที่จะเรียกร้อง.format()ในสายยาวและไม่สามารถที่จะใช้บางส่วนของความนิยมมากที่สุดเทคนิคสตริงห่อโดยไม่ทำลายต่อมา.format(โทรคุณสามารถทำแทนstr.format("", 1, 2) "".format(1, 2)วิธีนี้ช่วยให้คุณสามารถทำลายสตริงด้วยเทคนิคใดก็ได้ที่คุณต้องการ ตัวอย่างเช่น:

logger.info("Skipping {0} because its thumbnail was already in our system as {1}.".format(line[indexes['url']], video.title))

เป็นไปได้

logger.info(str.format(("Skipping {0} because its thumbnail was already"
+ "in our system as {1}"), line[indexes['url']], video.title))

มิฉะนั้นความเป็นไปได้เพียงอย่างเดียวก็คือการใช้การต่อเนื่องแบบสิ้นสุดบรรทัดซึ่งโดยส่วนตัวแล้วฉันไม่ใช่แฟนของ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.