วิธีการแก้ไขการเยื้องของ Python


264

ฉันมีรหัส Python ที่มีการเยื้องที่ไม่สอดคล้องกัน มีแท็บและช่องว่างจำนวนมากผสมกันเพื่อทำให้เรื่องแย่ลงและการเยื้องของพื้นที่ก็ไม่ได้ถูกสงวนไว้

รหัสทำงานได้ตามที่คาดหวัง แต่ก็รักษาได้ยาก

ฉันจะแก้ไขการเยื้อง (เช่นHTML Tidyแต่สำหรับ Python) โดยไม่ทำลายโค้ดได้อย่างไร


คุณสามารถตรวจสอบลิงค์นี้และระบุอินพุตของคุณเกี่ยวกับวิธีการใช้โมดูล reindent.py
user1050619

ตามที่ระบุไว้ด้านล่างโดย @ andy-hayden ดูที่คำถามที่เกี่ยวข้องนี้ - โดยทั่วไปautopep8ให้การเยื้องและอื่น ๆ อีกมากมาย: stackoverflow.com/questions/14328406/…
Pierz

2
นี่เป็นคำถามที่มีประโยชน์มากฉันพบว่าตัวเองต้องทำบ่อย มันไม่เกี่ยวกับ "การแนะนำเครื่องมือ" มากเท่ากับ "วิธีการใช้"
Andy Hayden

คำตอบ:


282

ใช้reindent.pyสคริปต์ที่คุณพบในTools/scripts/ไดเรกทอรีของการติดตั้ง Python ของคุณ:

เปลี่ยนไฟล์ Python (.py) เพื่อใช้การเยื้องแบบ 4 สเปซและไม่มีอักขระแท็บยาก รวมถึงตัดส่วนเกินและแท็บส่วนเกินออกจากปลายบรรทัดและลบบรรทัดว่างที่ท้ายไฟล์ ตรวจสอบให้แน่ใจว่าบรรทัดสุดท้ายลงท้ายด้วยการขึ้นบรรทัดใหม่

ดูที่สคริปต์นั้นสำหรับคำแนะนำการใช้งานโดยละเอียด


51
น่าเสียดายที่มันไม่ได้เป็นส่วนหนึ่งของการติดตั้ง Python ปกติบน Debian และ Ubuntu มันแบ่งออกเป็นpython-examplesแพ็คเกจ
ephemient

16
ยอดเยี่ยม ดังนั้นสิ่งที่ผู้ใช้ Debian และ Ubuntu จำเป็นต้องทำคือการรับแพ็คเกจนั้น อีกวิธีหนึ่งคือสคริปต์ที่ยังเป็นที่svn.python.org/view/python/trunk/Tools/scripts/...
Alex Martelli

9
@Shay Erlichmen: ลอง "python -tt yourscript.py"
nosklo

8
ผู้ใช้ Fedora / RedHat / CentOS ควรติดตั้งแพ็คเกจ "python-tools"
Cristian Ciupitu

26
เพียงเพื่อเพิ่มความคิดเห็นของ ephemient: เมื่อมีการติดตั้งคุณจะพบในpython-examples reindent /usr/share/doc/pythonX.X/examples/Tools/scripts/reindent.py
Larry Hastings

59

หากคุณกำลังใช้เป็นกลุ่ม:h retabดู

                                                        *: ret * *: retab *
: [range] ret [ab] [!] [new_tabstop]
                        แทนที่ลำดับทั้งหมดของ white-space ที่มี a
                        <Tab> กับสตริงใหม่ของ white-space โดยใช้ new
                        กำหนดค่า tabstop หากคุณไม่ได้ระบุใหม่
                        ขนาด tabstop หรือเป็นศูนย์, Vim ใช้ค่าปัจจุบัน
                        ของ 'tabstop'
                        ค่าปัจจุบันของ 'tabstop' จะถูกใช้เพื่อ
                        คำนวณความกว้างของแท็บที่มีอยู่
                        ด้วย!, Vim ยังแทนที่สตริงของปกติเท่านั้น
                        ช่องว่างด้วยแท็บตามความเหมาะสม
                        เมื่อเปิด 'expandtab' Vim จะแทนที่แท็บทั้งหมดด้วย
                        จำนวนช่องว่างที่เหมาะสม
                        คำสั่งนี้ตั้งค่า 'tabstop' เป็นค่าใหม่ที่กำหนด
                        และหากดำเนินการกับไฟล์ทั้งหมดซึ่งเป็นค่าเริ่มต้น
                        ไม่ควรทำการเปลี่ยนแปลงใด ๆ ที่มองเห็นได้
                        ระวัง: คำสั่งนี้แก้ไขอักขระ <Tab> ใด ๆ
                        ข้างในสตริงในโปรแกรม C ใช้ "\ t" เพื่อหลีกเลี่ยง
                        นี่มันเป็นนิสัยที่ดีอยู่ดี
                        ": retab!" อาจเปลี่ยนลำดับช่องว่างด้วย
                        อักขระ <Tab> ซึ่งสามารถทำให้ printf () ยุ่งเหยิง
                        {ไม่ใช่ใน Vi}
                        ไม่สามารถใช้ได้เมื่อ | + ex_extra | คุณลักษณะถูกปิดใช้งานที่
                        รวบรวมเวลา

ตัวอย่างเช่นถ้าคุณเพียงแค่พิมพ์

: เกษียณ

แท็บทั้งหมดของคุณจะถูกขยายเป็นช่องว่าง

คุณอาจต้องการ

: se และ "ชวเลขสำหรับ: ตั้ง expandtab

เพื่อให้แน่ใจว่าบรรทัดใหม่จะไม่ใช้แท็บตัวอักษร


หากคุณไม่ได้ใช้ Vim

perl -i.bak -pe "s / \ t / '' x (8-pos ()% 8) / เช่น" file.py

จะแทนที่แท็บด้วยช่องว่างโดยสมมติว่าแท็บหยุดทุก 8 ตัวอักษรในfile.py(ด้วยต้นฉบับจะไปfile.py.bakในกรณี) แทนที่ 8s ด้วย 4s หากแท็บหยุดทุก 4 ช่องว่างแทน


2
ทำงานได้ดี นี่เป็นวิธีที่ง่ายที่สุดในการแก้ไขการผสมการเยื้องของแท็บ
Srikant

แน่นอนว่าไม่ใช่วิธีที่ง่ายที่สุด
CONVID19

52

ฉันจะไปถึงautopep8เพื่อทำสิ่งนี้:

$ # see what changes it would make
$ autopep8 path/to/file.py --select=E101,E121 --diff

$ # make these changes
$ autopep8 path/to/file.py --select=E101,E121 --in-place

หมายเหตุ: E101 และ E121คือการเยื้อง pep8 (ฉันคิดว่าคุณสามารถส่ง--select=E1ต่อเพื่อแก้ไขปัญหาที่เกี่ยวข้องกับการเยื้องทั้งหมด - ที่ขึ้นต้นด้วย E1)

คุณสามารถใช้สิ่งนี้กับโครงการทั้งหมดของคุณโดยใช้การตั้งค่าสถานะแบบเรียกซ้ำ:

$ autopep8 package_dir --recursive --select=E101,E121 --in-place

ดูเพิ่มเติมเครื่องมือในการแปลงรหัสงูใหญ่จะเป็น PEP8 สอดคล้อง


นี้เป็นที่น่ากลัว ... ฉันได้รับการมองหาเครื่องมือเช่น rubocop ทับทิมสำหรับหลาม
OkezieE

1
autopep8ล้มเหลวหากไวยากรณ์ไม่ถูกต้อง คุณสามารถยืนยันได้ว่าใช้งานpython -tt <file.py>
Nishant

47

autopep8 -i script.py

ใช้autopep8

autopep8 ฟอร์แมตโค้ด Python โดยอัตโนมัติเพื่อให้เป็นไปตามPEP 8 nullstyleคำแนะนำ มันใช้pep8ยูทิลิตี้เพื่อตรวจสอบว่าส่วนใดของ nullcodeความต้องการที่จะจัดรูปแบบ autopep8มีความสามารถในการแก้ไขปัญหาส่วนใหญ่ nullformattingที่สามารถรายงานpep8ได้

pip install autopep8
autopep8 script.py    # print only
autopep8 -i script.py # write file

ฉันมีรหัสบรรทัดเดียวที่มี "import os" และ 4 ช่องว่างก่อนหน้า แต่ไม่ได้เยื้องที่หนึ่ง .... เหตุผลใด ๆ
pkm

3
@pkm 4 ช่องว่าง (หรือการเยื้องใด ๆ ที่เป็นทวีคูณของ 4) เป็นส่วนหนึ่งของ PEP8
rbaleksandar

13

การใช้ Vim นั้นไม่ควรเกี่ยวข้องมากกว่าการกดปุ่มEscจากนั้นพิมพ์ ...

:%s/\t/    /g

... บนไฟล์ที่คุณต้องการเปลี่ยน ที่จะแปลงแท็บทั้งหมดเป็นสี่ช่องว่าง หากคุณมีระยะห่างที่ไม่สอดคล้องเช่นกันนั่นจะยากขึ้น


11
คุณสามารถติดตาม coder ดั้งเดิมและใช้เทคนิคการสอบสวนขั้นสูงได้หรือไม่ ไม่มีอะไรที่เลวร้ายไปกว่าโค้ดที่เยื้องเข้าไป
Ben Hughes

3
@ Ben ไม่สอดคล้องเว้าเป็นอย่างน้อยปัญหาของเราจากผู้ชายคนนั้น :)
Shay Erlichmen


5

บนระบบที่เหมือน UNIX ส่วนใหญ่คุณสามารถเรียกใช้:

expand -t4 oldfilename.py > newfilename.py

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


1
โปรดทราบว่าการใช้ไฟล์เดียวกันนั้นใช้งานไม่ได้และทำให้คุณมีไฟล์ว่างเปล่า แต่คำตอบนี้ใช้งานได้จริงและฉันใช้มันเมื่อฉันต้องการแปลงแท็บเป็นช่องว่าง ใครช่วยอธิบาย downvote บ้าง ฉันจะขึ้น +1
S. Kerdel

มีวิธีใดที่เป็นไปได้ในการกู้คืนไฟล์ที่ถูกเขียนทับหรือไม่? เพียงแค่ใช้วิธีการดังกล่าวข้างต้นและคุ้มค่าวันของฉันของรหัสหายไปfacepalm ขอบคุณ
Simas

4

หากคุณขี้เกียจ (เช่นฉัน) คุณสามารถดาวน์โหลด Wingware Python IDE รุ่นทดลองซึ่งมีเครื่องมือแก้ไขอัตโนมัติสำหรับการเยื้องเยื้อง มันใช้งานได้ดีทีเดียว http://www.wingware.com/


4

สคริปต์ reindent ไม่ทำงานสำหรับฉันเนื่องจากโมดูลขาดหายไปบางส่วน อย่างไรก็ตามฉันพบsedคำสั่งนี้ซึ่งทำงานได้ดีสำหรับฉัน:

sed -r 's/^([  ]*)([^ ])/\1\1\2/' file.py

2
ตัวเลือกที่ผิดกฎหมาย -r
HelloWorld

2

ลองใช้ Emacs มันมีการสนับสนุนที่ดีสำหรับการเยื้องที่จำเป็นใน Python กรุณาตรวจสอบลิงค์นี้http://python.about.com/b/2007/09/24/emacs-tips-for-python-programmers.htm


2
python-mode นั้นดีสำหรับการเขียน Python แต่ไม่มีอะไรในลิงค์อธิบายวิธีการแก้ไขการเยื้องในไฟล์ที่มีอยู่
ephemient

5
Mx untabify จะเปลี่ยนแท็บให้เป็นพื้นที่ใน emacs
Paul Hildebrandt

ลิงก์เสีย (มีประสิทธิภาพ) มันเปลี่ยนเส้นทางไปยังหน้าที่มีชื่อ"ภาษาการเขียนโปรแกรม C สำหรับผู้เริ่มต้น" (!)
Peter Mortensen


0

ฉันมีทางออกที่ง่ายสำหรับปัญหานี้ คุณสามารถพิมพ์ ": retab" ก่อนแล้วจึง ": retab!" จากนั้นทุกอย่างจะเรียบร้อย


1
พิมพ์ " :retab" ในบริบทใด ในกลุ่ม ?
Peter Mortensen

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