@Pythonetc kompilasi, Juli 2018

Ini adalah koleksi kedua tips dan pemrograman Python dari umpan @pythonetc saya. Pilihan sebelumnya:


Bahasa reguler


Bahasa reguler adalah bahasa formal yang dapat direpresentasikan sebagai mesin negara yang terbatas . Dengan kata lain, untuk pemrosesan teks karakter demi karakter, Anda hanya perlu mengingat status saat ini, dan jumlah status tersebut terbatas.

Contoh sempurna: mesin yang memeriksa apakah inputnya prima seperti –3, 2.2, atau 001. Di awal artikel, mesin state hingga ditampilkan. Lingkaran ganda menunjukkan status akhir, di mana mesin dapat berhenti.

Mesin mulai dari posisi . Mungkin ia menemukan minus, lalu digit, dan kemudian pada posisi β‘’ ia memproses jumlah digit yang diperlukan. Setelah itu, pemisah desimal (β‘’ β†’ β‘£) dapat diperiksa, diikuti oleh satu digit (β‘£ β†’ β‘€) atau lebih (β‘€ β†’ β‘€).

Contoh klasik dari bahasa tidak beraturan adalah kumpulan ekspresi string dari bentuk:

ab
aaa-bbb
aaaaa-bbbbb


Secara formal, kita membutuhkan string yang berisi N instance dari, kemudian – , lalu - N instance dari b , di mana N adalah bilangan bulat lebih besar dari 0. Anda tidak dapat mengimplementasikan ini dengan mesin keadaan, karena Anda harus mengingat jumlah karakter yang Anda pikir Anda bisa dilakukan hanya menggunakan jumlah negara tak terbatas.

Ekspresi reguler hanya dapat menentukan bahasa reguler. Sebelum menggunakannya, pastikan bahwa string Anda bahkan dapat diproses menggunakan mesin negara. Misalnya, mereka tidak cocok untuk memproses JSON, XML, atau bahkan ekspresi aritmatika dengan tanda kurung.

Sangat lucu bahwa banyak mesin regex modern tidak teratur. Sebagai contoh, modul regex untuk Python mendukung rekursi (yang akan membantu dalam menyelesaikan masalah dengan aaa-bbb ).

Penjadwalan dinamis


Ketika Python membuat panggilan metode, ucapkan af(b, c, d) , pertama-tama harus memilih fungsi yang benar f . Berdasarkan polimorfisme, a menentukan apa yang akhirnya akan dipilih. Proses memilih metode biasa disebut pengiriman dinamis.

Python hanya mendukung polimorfisme pengiriman tunggal. Ini berarti bahwa hanya objek itu sendiri yang mempengaruhi pilihan objek (dalam contoh kita, a ). Dalam bahasa lain, tipe b , c dan d dapat diperhitungkan - mekanisme semacam itu disebut pengiriman ganda. Contoh yang mencolok adalah bahasa C #.

Namun, beberapa penjadwalan dapat ditiru menggunakan satu saja. Itulah mengapa templat desain pengunjung dibuat: menggunakan dua kali pengiriman tunggal untuk mensimulasikan ganda.

Ingat bahwa metode overloading (seperti pada Java dan C ++) bukan analog dari pengiriman ganda. Pengiriman dinamis berfungsi dalam runtime, dan kelebihan beban hanya dilakukan selama kompilasi.

Contoh-contoh ini akan membantu Anda lebih memahami topik:


Nama sebaris


Dengan Python, Anda dapat dengan mudah memodifikasi semua variabel standar yang tersedia di lingkup global:

 >>> print = 42 >>> print(42) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not callable 

Ini berguna jika modul Anda mendefinisikan fungsi yang namanya cocok dengan nama fungsi bawaan. Ini juga terjadi dalam situasi di mana Anda berlatih metaprogramming dan mengambil nilai string sewenang-wenang sebagai pengidentifikasi.

Tetapi bahkan jika Anda menduplikat nama beberapa fungsi bawaan, Anda mungkin perlu akses ke apa yang awalnya disebut. Itulah mengapa modul builtins ada:

 >>> import builtins >>> print = 42 >>> builtins.print(1) 1 

Juga di sebagian besar modul, variabel __builtins__ tersedia. Tapi ada satu trik. Pertama, ini adalah fitur implementasi cpython, dan biasanya tidak boleh digunakan sama sekali. Kedua, __builtins__ dapat merujuk ke builtins dan builtins.__dict__ , tergantung pada bagaimana modul saat ini dimuat.

strace


Terkadang aplikasi mulai berperilaku aneh dalam pertempuran. Alih-alih memulai kembali, Anda mungkin ingin memahami penyebab masalah sementara itu mungkin.

Solusi yang jelas adalah menganalisis tindakan program dan mencoba memahami bagian kode mana yang sedang dieksekusi. Pencatatan yang benar membuat tugas ini lebih mudah, tetapi log Anda mungkin tidak cukup detail karena arsitektur atau tingkat pencatatan yang dipilih dalam pengaturan.

Dalam kasus seperti itu, strace mungkin bermanfaat. Ini adalah utilitas Unix yang melacak panggilan sistem. Anda dapat menjalankannya sebelumnya - strace python script.py - tetapi biasanya lebih nyaman untuk terhubung ke aplikasi yang sudah berjalan: strace -p PID .

 $ cat test.py with open('/tmp/test', 'w') as f: f.write('test') $ strace python test.py 2>&1 | grep open | tail -n 1 open("/tmp/test", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3 

Setiap baris jejak berisi nama panggilan sistem, argumen dalam tanda kurung, dan nilai kembali. Karena beberapa argumen digunakan untuk mengembalikan hasil dari panggilan sistem, dan tidak meneruskan data ke sana, output baris dapat ditunda hingga panggilan sistem berakhir.

Dalam contoh ini, output dihentikan sampai penulisan ke STDIN selesai:

 $ strace python -c 'input()' read(0, 

Tuple literal


Salah satu bagian paling tidak konsisten dari sintaks Python adalah tuple literals.

Untuk membuat tuple, cukup dengan membuat daftar nilai yang dipisahkan oleh koma: 1, 2, 3 . Bagaimana dengan tupel elemen tunggal? Cukup tambahkan koma gantung: 1, ,. Terlihat jelek dan sering menyebabkan kesalahan, tetapi cukup logis.

Bagaimana dengan tuple kosong? Ini satu koma - ,? Tidak, ini () . Dan apa, kurung membuat tuple, seperti koma? Tidak, (4) bukan tupel, hanya 4 .

 In : a = [ ...: (1, 2, 3), ...: (1, 2), ...: (1), ...: (), ...: ] In : [type(x) for x in a] Out: [tuple, tuple, int, tuple] 

Untuk membingungkan hal-hal yang lebih sulit, tuple literal sering membutuhkan tanda kurung tambahan. Jika Anda memerlukan tuple menjadi satu-satunya argumen untuk fungsi, maka jelas f(1, 2, 3) tidak akan berfungsi - Anda harus menulis f((1, 2, 3)) .

Source: https://habr.com/ru/post/id419025/


All Articles