Kiat-kiat Python yang berguna yang belum pernah Anda temui sebelumnya. Bagian 2

Kami baru-baru ini menerbitkan terjemahan dari materi tersebut, yang memberikan tips yang berguna untuk programmer Python. Materi itu memiliki sekuel yang kami berikan kepada Anda hari ini.



Penamaan slice menggunakan fungsi slice


Bekerja dengan banyak nilai yang diberikan oleh indeks dapat dengan cepat berubah menjadi berantakan - baik dalam hal dukungan maupun dalam hal keterbacaan kode. Salah satu cara untuk memperbaiki situasi adalah dengan menggunakan konstanta untuk nilai yang ditentukan oleh indeks. Tetapi ada cara yang lebih baik untuk menulis kode kualitas:

#       ID First Name   Last Name line_record = "2    John Smith" ID = slice(0, 8) FIRST_NAME = slice(9, 21) LAST_NAME = slice(22, 27) name = f"{line_record[FIRST_NAME].strip()} {line_record[LAST_NAME].strip()}" # name == "John Smith" 

Dalam contoh ini, Anda bisa melihat bahwa dengan memberikan nama irisan menggunakan fungsi slice , dan menggunakan nama-nama ini untuk mendapatkan fragmen string, kami dapat menyingkirkan indeks kusut. Anda dapat mempelajari lebih lanjut tentang objek slice dengan menggunakan atribut .step , .stop dan .step .

Meminta kata sandi dari pengguna selama eksekusi program


Banyak alat atau skrip baris perintah memerlukan nama pengguna dan kata sandi untuk berfungsi. Jika Anda harus menulis program seperti itu, Anda mungkin menemukan modul getpass :

 import getpass user = getpass.getuser() password = getpass.getpass() #   ... 

Paket yang sangat sederhana ini memungkinkan Anda untuk meminta kata sandi pengguna, serta mendapatkan nama pengguna dengan mengambil nama yang digunakannya untuk masuk. Namun, ketika bekerja dengan kata sandi, Anda harus sadar bahwa tidak semua sistem mendukung penyembunyian kata sandi. Python akan mencoba memberi tahu Anda. Jika ini terjadi, Anda akan melihat peringatan yang sesuai di baris perintah.

Menemukan kecocokan dekat dalam string


Sekarang mari kita bicara tentang fitur yang sedikit lebih misterius dari pustaka standar Python. Misalkan Anda berada dalam situasi di mana Anda perlu, menggunakan konsep seperti jarak Levenshtein , untuk menemukan kata-kata dalam daftar yang terlihat seperti jalur input tertentu. Masalah ini dapat diatasi dengan menggunakan modul difflib .

 import difflib difflib.get_close_matches('appel', ['ape', 'apple', 'peach', 'puppy'], n=2) # returns ['apple', 'ape'] 

Metode difflib.get_close_matches yang terbaik, "cukup baik" cocok. Argumen pertama dari metode ini menentukan string pencarian, argumen kedua menentukan daftar di mana pencarian dilakukan. Metode ini dapat memberikan argumen opsional n , yang menentukan jumlah maksimum kecocokan yang dikembalikan. Metode ini juga mendukung cutoff argumen bernama opsional (secara default diatur ke 0.6 ), yang memungkinkan Anda untuk menetapkan nilai ambang batas untuk mengevaluasi kecocokan.

Bekerja dengan Alamat IP


Jika Anda harus menulis program Python untuk bekerja dengan jaringan, ini berarti modul ipaddress bisa sangat berguna bagi Anda. Salah satu opsi untuk menggunakannya adalah membuat daftar alamat IP dari serangkaian alamat yang ditentukan dalam format CIDR (Classless Inter-Domain Routing, classless addressing).

 import ipaddress net = ipaddress.ip_network('74.125.227.0/29') #      IPv6 # IPv4Network('74.125.227.0/29') for addr in net:    print(addr) # 74.125.227.0 # 74.125.227.1 # 74.125.227.2 # 74.125.227.3 # ... 

Fitur lain yang bermanfaat dari modul ini adalah memeriksa alamat IP untuk kepemilikannya pada jaringan tertentu:

 ip = ipaddress.ip_address("74.125.227.3") ip in net # True ip = ipaddress.ip_address("74.125.227.12") ip in net # False 

Modul ipaddress memiliki banyak fitur menarik lainnya yang tidak saya bicarakan di sini. Baca lebih lanjut tentang dia di sini . Benar, dengan menggunakan modul ini, pertimbangkan batasan-batasan mengenai kerja sama dengan modul lain yang terkait dengan pemrograman jaringan. Misalnya, Anda tidak dapat menggunakan instance IPv4Network sebagai string alamat. Objek serupa untuk ini pertama-tama harus dikonversi ke string menggunakan str .

Debugging program di baris perintah


Jika Anda salah satu dari mereka yang tidak ingin menggunakan IDE dan menulis kode dalam Vim atau Emacs, maka Anda mungkin berada dalam situasi di mana Anda akan memerlukan debugger seperti yang ada di IDE. Dan tahukah Anda? Anda sudah memiliki debugger seperti itu. Untuk menggunakannya, jalankan saja program menggunakan struktur seperti python3.8 -i . Bendera -i memungkinkan, setelah menyelesaikan program, untuk meluncurkan shell interaktif. Dengan menggunakannya, Anda dapat memeriksa variabel dan memanggil fungsi. Ini adalah fitur yang menarik, tetapi bagaimana dengan debugger nyata (pdb)? Mari kita bereksperimen dengan program sederhana berikut, yang kodenya ada di file script.py :

 def func():    return 0 / 0 func() 

Jalankan dengan perintah python3.8 -i script.py dan dapatkan yang berikut:

 #   ... Traceback (most recent call last):  File "script.py", line 4, in <module>    func()  File "script.py", line 2, in func    return 0 / 0 ZeroDivisionError: division by zero >>> import pdb >>> pdb.pm() #      > script.py(2)func() -> return 0 / 0 (Pdb) 

Kami melihat tempat program di mana kecelakaan itu terjadi. Tetapkan breakpoint:

 def func():    breakpoint() # import pdb; pdb.set_trace()    return 0 / 0 func() 

Jalankan kembali skrip.

script.py(3)func()
-> return 0 / 0
(Pdb) #
(Pdb) step
ZeroDivisionError: division by zero
> script.py(3)func()
-> return 0 / 0
(Pdb)

Dalam kebanyakan situasi, perintah print dan hasil penelusuran cukup untuk debugging skrip, tetapi kadang-kadang untuk mengatasi kegagalan yang kompleks, Anda perlu menggali ke dalam program dan memahami esensi dari apa yang terjadi. Dalam kasus seperti itu, breakpoint ditetapkan dalam kode dan program diperiksa. Misalnya, mereka melihat argumen fungsi, mengevaluasi ekspresi, memeriksa nilai-nilai variabel, atau, seperti yang ditunjukkan di atas, cukup lakukan eksekusi kode langkah-demi-langkah. Pdb adalah pembungkus Python yang berfungsi penuh. Dalam shell ini, Anda dapat melakukan hampir semua hal. Dalam perjalanannya, beberapa perintah debugger spesifik akan berguna, yang mana bantuan dapat ditemukan di sini .

Mendeklarasikan beberapa konstruktor dalam sebuah kelas


Function overloading adalah salah satu fitur yang banyak digunakan dalam berbagai bahasa pemrograman, tetapi tidak dalam Python. Dan meskipun Anda tidak bisa membebani fungsi biasa dengan Python, kita bisa menggunakan sesuatu seperti konstruktor yang berlebihan menggunakan metode kelas:

 import datetime class Date:    def __init__(self, year, month, day):        self.year = year        self.month = month        self.day = day    @classmethod    def today(cls):        t = datetime.datetime.now()        return cls(t.year, t.month, t.day) d = Date.today() print(f"{d.day}/{d.month}/{d.year}") # 14/9/2019 

Dalam situasi yang sama, alih-alih menggunakan metode kelas, Anda mungkin tergoda untuk meletakkan semua logika konstruktor alternatif di __init__ dan menyelesaikan masalah menggunakan *args , **kwargs dan banyak if . Hasilnya mungkin kode yang berfungsi, tetapi kode ini akan sulit dibaca dan dipelihara. Di sini saya akan merekomendasikan menempatkan logika minimum dalam __init__ dan melakukan semua operasi dalam metode / konstruktor yang terpisah. Dengan pendekatan ini, kami akan memiliki kode bersih yang sesuai untuk pembuat kode ini dan siapa pun yang akan menggunakan kode ini.

Hasil panggilan fungsi caching menggunakan dekorator


Pernahkah Anda menulis fungsi yang melakukan beberapa operasi baca / tulis yang panjang, atau lebih tepatnya penghitungan rekursif yang lambat? Pada saat yang sama, apakah Anda berpikir bahwa hasil caching tidak akan merusak fungsi seperti itu? Anda dapat men-cache (memoize) hasil panggilan fungsi menggunakan dekorator lru_cache dari modul functools :

 from functools import lru_cache import requests @lru_cache(maxsize=32) def get_with_cache(url):    try:        r = requests.get(url)        return r.text    except:        return "Not Found" for url in ["https://google.com/",            "https://martinheinz.dev/",            "https://reddit.com/",            "https://google.com/",            "https://dev.to/martinheinz",            "https://google.com/"]:    get_with_cache(url) print(get_with_cache.cache_info()) # CacheInfo(hits=2, misses=4, maxsize=32, currsize=4) 

Dalam contoh ini, kami menjalankan permintaan GET yang hasilnya di-cache (hingga 32 hasil dapat di-cache). Di sini Anda dapat melihat bahwa kami mendapatkan informasi tentang fungsi cache menggunakan metode cache_info . Dekorator juga memberi kami metode clear_cache , yang digunakan untuk clear_cache cache. Di sini saya juga ingin mencatat bahwa caching tidak dapat digunakan dengan fungsi yang memiliki efek samping, atau dengan fungsi yang membuat objek bisa berubah dengan setiap panggilan.

Menemukan barang yang paling sering ditemukan di objek iterable


Berada dalam daftar unsur-unsur seperti itu yang ditemukan di dalamnya lebih sering daripada yang lain adalah tugas yang sangat umum. Anda dapat menyelesaikannya, misalnya, menggunakan for dan kamus, yang akan mengumpulkan informasi tentang jumlah elemen yang identik. Namun pendekatan semacam itu hanya buang-buang waktu. Faktanya adalah Anda dapat memecahkan masalah tersebut menggunakan kelas Counter dari modul collections :

 from collections import Counter cheese = ["gouda", "brie", "feta", "cream cheese", "feta", "cheddar",          "parmesan", "parmesan", "cheddar", "mozzarella", "cheddar", "gouda",          "parmesan", "camembert", "emmental", "camembert", "parmesan"] cheese_count = Counter(cheese) print(cheese_count.most_common(3)) # : [('parmesan', 4), ('cheddar', 3), ('gouda', 2)] 

Mekanisme internal kelas Counter didasarkan pada kamus yang menyimpan korespondensi elemen dan jumlah entri dalam daftar. Oleh karena itu, objek yang sesuai dapat digunakan sebagai objek dict biasa:

 print(cheese_count["mozzarella"]) # : 1 cheese_count["mozzarella"] += 1 print(cheese_count["mozzarella"]) # : 2 

Selain itu, ketika bekerja dengan Counter , kami dapat menggunakan metode update(more_words) , yang digunakan untuk menambahkan elemen baru ke penghitung. Fitur lain yang berguna dari Counter adalah bahwa itu memungkinkan Anda untuk menggunakan operasi matematika (penambahan dan pengurangan) ketika bekerja dengan instance kelas ini.

Ringkasan


Saya pikir sebagian besar tips yang diberikan hari ini dapat digunakan oleh mereka yang menulis dengan Python hampir setiap hari. Saya harap Anda menemukan di antara mereka sesuatu yang bermanfaat bagi Anda.

Pembaca yang budiman! Apakah Anda tahu ada trik pemrograman Python yang menarik? Jika demikian, silakan bagikan.

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


All Articles