
Python memiliki 3 cara untuk memformat string, dan salah satunya lebih baik daripada yang lain. Tapi jangan maju dulu - format apa yang sedang kita bicarakan? Setiap kali kita ingin menyapa pengguna dengan nama, kita perlu memasukkan string dengan nama dalam string template. Sebagian besar entri log yang berguna juga mengandung nilai variabel. Dan ini sebuah contoh:
integer = 42 string = 'FORTY_TWO' print('string number %s, or simply %d' % (string, integer)) print('string number {}, or simply {}'.format(string, integer)) print(f'string number {string}, or simply {integer}')
Metode pertama, memformat dengan operator%, datang dalam Python dari C - ini meniru fungsi printf. Metode ini adalah yang pertama di python, dan tetap satu-satunya (dibahas dalam artikel) di Python versi 2.5 dan di bawah.
Cara kedua adalah metode str.format, yang termasuk dalam kelas string bawaan. Itu datang dengan Python 3.0, dan porting ke versi 2.6. Metode ini
direkomendasikan memiliki sintaksis yang lebih kaya.
Metode ketiga, f-string, muncul dalam Python versi 3.6. Sebagaimana dijelaskan dalam
PEP-0498 , penciptaan cara baru untuk memformat string dimotivasi oleh kekurangan metode yang ada, yang dicirikan oleh penulis sebagai rawan kesalahan, tidak cukup fleksibel, dan tidak elegan:
PEP ini didorong oleh keinginan untuk memiliki cara yang lebih sederhana untuk memformat string dengan Python. Cara memformat yang ada adalah rawan kesalahan, tidak fleksibel, atau rumit.
Jadi, kami memiliki tiga cara untuk menyelesaikan satu masalah. Tapi mungkin ini masalah selera dan preferensi pribadi? Mungkin, tetapi gaya kode Anda (terutama kode dalam proyek dengan sejumlah besar peserta) pasti akan mendapat manfaat dari keseragaman. Dalam kasus terbaik, Anda harus menggunakan satu metode memformat string, maka akan menjadi lebih mudah untuk membaca kode. Tetapi metode mana yang harus dipilih? Dan apakah ada perbedaan dalam kinerja kode?
Mari kita coba menjawab pertanyaan tentang kinerja secara eksperimental:
import timeit setup = """ integer = 42 string = 'FORTY_TWO' """.strip() percent_stmt ="'Number %s or simply %d' % (string, integer)" call_stmt = "'Number {} or simply {}'.format(string, integer)" fstr_stmt = """f'Number {string} or simply {integer}'""" def time(stmt): return f"{timeit.timeit(stmt, setup, number=int(1e7)):.3f}" print(f"Timing percent formating: | {time(percent_stmt)}") print(f"Timing call formating: | {time(call_stmt)}") print(f"Timing f-string formating: | {time(fstr_stmt)}")
Hasil di MacBook dengan Python 3.7:
Timing percent formating: | 2.025 Timing call formating: | 2.943 Timing f-string formating: | 1.348
Perbedaannya signifikan. Jadi sekarang, jalankan pencarian regex di ".format" dan tulis ulang ratusan ekspresi? Pada prinsipnya, tugas itu sederhana tetapi memakan waktu. Ditambah kesempatan untuk membuat kesalahan dan memasukkan bug ke dalam kode yang sebelumnya berfungsi! Tampaknya ada ruang untuk otomatisasi. Memang, ada pustaka yang dapat mengonversi sebagian besar ekspresi menjadi f-string:
flynt ,
pyupgrade .
Flynt mudah digunakan. Misalnya, jalankan konversi pada kode sumber flask:
38f9d3a65222:~ ikkamens$ git clone https://github.com/pallets/flask.git Cloning into 'flask'... ... Resolving deltas: 100% (12203/12203), done. 38f9d3a65222:~ ikkamens$ flynt flask Flynt run has finished. Stats: Execution time: 0.623s Files modified: 18 Expressions transformed: 43 Character count reduction: 241 (0.04%) _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. Please run your tests before commiting. Report bugs as github issues at: https://github.com/ikamensh/flynt Thank you for using flynt! Fstringify more projects and recommend it to your colleagues! _-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_. 38f9d3a65222:~ ikkamens$
Perlu juga dicatat kemungkinan konversi ekspresi yang menempati beberapa baris, dan pengumpulan statistik tentang perubahan yang dilakukan. Bendera --line_length XX mendefinisikan batas panjang garis setelah konversi. Flynt memungkinkan Anda untuk memanggil pyupgrade dengan flag --upgrade.
Pyupgrade mencakup lebih banyak fungsi, dan dapat membersihkan kode Anda dari banyak artefak Python 2 - seperti mewarisi dari objek, menentukan nama kelas dalam super, dan
banyak lagi . Pyupgrade dirancang untuk digunakan dengan
pra-komit , utilitas untuk memodifikasi kode secara otomatis sebelum melakukan.
Lebih baik mengonversi sumber dalam gita atau kontrol versi lainnya. Sebaiknya jalankan tes dan lihat sendiri perubahannya (menggunakan lingkungan git diff atau PyCharm). Selama kita hidup di antara mereka yang peduli, bahwa kode tersebut telah menjadi beberapa karakter lebih pendek, konversi proaktif juga akan menghemat waktu mereka. Lagipula, cepat atau lambat seseorang akan mulai melakukan dengan tangan mereka apa yang bisa dijadikan utilitas. F-string hanya berfungsi pada Python 3.6+, tetapi segera ini tidak akan menjadi masalah karena
versi lain akan menjadi usang .
Perlu dicatat bahwa metode .format klasik tidak akan berfungsi sepenuhnya. Jika Anda menggunakan templat yang sama untuk membuat pesan dengan variabel yang berbeda di tempat yang berbeda dalam kode, Anda harus menyimpan templat ini dalam variabel dan menggunakannya - prinsip "Jangan ulangi diri Anda" jauh lebih penting daripada memenangkan nanodetik dari memformat string.
Kesimpulan:
Kami melihat tiga metode pemformatan string yang tersedia di Python 3.6+, riwayat singkatnya, dan membandingkan kinerjanya. Kami juga memeriksa alat open-source untuk secara otomatis mengkonversi kode ke metode baru untuk memformat string, dan fungsi tambahannya. Jangan lupa hal-hal sederhana dalam kode Anda, dan semoga berhasil!