Saya menemukan with
pernyataan Python untuk pertama kalinya hari ini. Saya telah menggunakan Python ringan selama beberapa bulan dan bahkan tidak tahu keberadaannya! Mengingat statusnya yang agak tidak jelas, saya pikir patut bertanya:
- Untuk apa
with
pernyataan Python dirancang untuk digunakan? - Untuk apa Anda menggunakannya?
- Apakah ada gotcha yang perlu saya ketahui, atau anti-pola umum yang terkait dengan penggunaannya? Adakah kasus yang lebih baik digunakan
try..finally
daripadawith
? - Mengapa tidak digunakan lebih luas?
- Kelas perpustakaan standar apa yang kompatibel dengannya?
with
dokumentasi Python 3.Jawaban:
Saya percaya ini sudah dijawab oleh pengguna lain sebelum saya, jadi saya hanya menambahkannya demi kelengkapan:
with
pernyataan tersebut menyederhanakan penanganan pengecualian dengan merangkum persiapan umum dan tugas pembersihan dalam apa yang disebut manajer konteks . Rincian lebih lanjut dapat ditemukan di PEP 343 . Misalnya,open
pernyataan itu sendiri adalah manajer konteks, yang memungkinkan Anda membuka file, tetap membuka selama eksekusi dalam kontekswith
pernyataan di mana Anda menggunakannya, dan tutup segera setelah Anda meninggalkan konteks, tidak peduli apakah Anda telah meninggalkannya karena pengecualian atau selama aliran kontrol reguler. Thewith
pernyataan demikian dapat digunakan dengan cara yang mirip dengan pola RAII di C ++: beberapa sumber daya diperoleh olehwith
pernyataan dan dirilis ketika Anda meninggalkanwith
konteks.Beberapa contoh adalah: membuka file menggunakan
with open(filename) as fp:
, memperoleh kunci menggunakanwith lock:
(di manalock
merupakan instance darithreading.Lock
). Anda juga dapat membuat manajer konteks sendiri menggunakancontextmanager
dekoratorcontextlib
. Misalnya, saya sering menggunakan ini ketika saya harus mengubah direktori saat ini sementara dan kemudian kembali ke tempat saya sebelumnya:Berikut adalah contoh lain yang sementara dialihkan
sys.stdin
,sys.stdout
dansys.stderr
ke beberapa file lain menangani dan mengembalikannya nanti:Dan akhirnya, contoh lain yang membuat folder sementara dan membersihkannya ketika meninggalkan konteks:
sumber
with
pernyataan itu dirancang untuk mengisi variabel dengan data sampai instruksi di bawahnya selesai, dan kemudian membebaskan variabel?with open('myScript.py', 'r') as f: pass
. Aku diharapkan dapat memanggil variabelf
untuk melihat isi teks dokumen, karena ini adalah apa yang akan muncul jika dokumen tersebut ditugaskan untukf
melalui biasaopen
pernyataan:f = open('myScript.py').read()
. Tapi bukannya aku berikut:<_io.TextIOWrapper name='myScript.py' mode='r' encoding='cp1252'>
. Apa artinya?with
tidak menghapus kebutuhan untukread
file yang sebenarnya. Thewith
panggilanopen
- tidak tahu apa yang perlu Anda lakukan dengan itu - Anda mungkin ingin melakukan mencari misalnya.with
Pernyataan ini dapat mengisi variabel dengan data atau membuat beberapa perubahan lain ke lingkungan sampai instruksi di bawahnya selesai, dan kemudian melakukan segala jenis pembersihan yang diperlukan. Jenis pembersihan yang dapat dilakukan adalah hal-hal seperti menutup file yang terbuka, atau seperti @Tamas miliki dalam contoh ini, mengubah direktori kembali ke tempat Anda sebelumnya, dll. Karena Python memiliki pengumpulan sampah, membebaskan variabel tidak penting gunakan kasing.with
umumnya digunakan untuk jenis pembersihan lainnya.Saya akan menyarankan dua kuliah yang menarik:
1. The
with
pernyataan digunakan untuk membungkus eksekusi blok dengan metode yang didefinisikan oleh manajer konteks. Ini memungkinkantry...except...finally
pola penggunaan umum untuk dienkapsulasi agar nyaman digunakan kembali.2. Anda dapat melakukan sesuatu seperti:
ATAU
ATAU (Python 3.1)
ATAU
3. Saya tidak melihat Antipattern di sini.
Mengutip Menyelam ke Python :
4. Saya kira itu terkait dengan kebiasaan programmer untuk menggunakan
try..catch..finally
pernyataan dari bahasa lain.sumber
with
.with
Pernyataan Python adalah dukungan bahasa bawaan dariResource Acquisition Is Initialization
idiom yang biasa digunakan dalam C ++. Hal ini dimaksudkan untuk memungkinkan akuisisi dan pelepasan sumber daya sistem operasi yang aman.The
with
Pernyataan menciptakan sumber daya dalam lingkup / blok. Anda menulis kode menggunakan sumber daya di dalam blok. Ketika blok keluar sumber daya dilepaskan dengan bersih terlepas dari hasil kode dalam blok (yaitu apakah blok keluar secara normal atau karena pengecualian).Banyak sumber daya di pustaka Python yang mematuhi protokol yang diperlukan oleh
with
pernyataan dan dapat digunakan dengan itu out-of-the-box. Namun siapa pun dapat membuat sumber daya yang dapat digunakan dalam pernyataan with dengan mengimplementasikan protokol yang terdokumentasi dengan baik: PEP 0343Gunakan setiap kali Anda memperoleh sumber daya dalam aplikasi Anda yang harus dilepaskan secara eksplisit seperti file, koneksi jaringan, kunci dan sejenisnya.
sumber
Sekali lagi untuk kelengkapan, saya akan menambahkan kasus penggunaan saya yang paling berguna untuk
with
pernyataan.Saya melakukan banyak komputasi ilmiah dan untuk beberapa kegiatan saya membutuhkan
Decimal
perpustakaan untuk perhitungan presisi yang sewenang-wenang. Beberapa bagian dari kode saya, saya perlu presisi tinggi dan untuk sebagian besar bagian lain saya perlu kurang presisi.Saya mengatur presisi default saya ke angka rendah dan kemudian gunakan
with
untuk mendapatkan jawaban yang lebih tepat untuk beberapa bagian:Saya sering menggunakan ini dengan Uji Hypergeometrik yang membutuhkan pembagian angka besar yang menghasilkan faktorial. Ketika Anda melakukan perhitungan skala genom, Anda harus berhati-hati terhadap kesalahan pembulatan dan luapan.
sumber
Contoh dari antipattern mungkin menggunakan
with
loop dalam ketika akan lebih efisien untuk memilikiwith
loop luarsebagai contoh
vs.
Cara pertama adalah membuka dan menutup file untuk masing-masing
row
yang dapat menyebabkan masalah kinerja dibandingkan dengan cara kedua dengan membuka dan menutup file hanya sekali.sumber
Lihat PEP 343 - Pernyataan 'dengan' , ada bagian contoh di akhir.
sumber
poin 1, 2, dan 3 dicakup dengan cukup baik:
4: ini relatif baru, hanya tersedia di python2.6 + (atau python2.5 menggunakan
from __future__ import with_statement
)sumber
Pernyataan with bekerja dengan apa yang disebut manajer konteks:
http://docs.python.org/release/2.5.2/lib/typecontextmanager.html
Idenya adalah untuk menyederhanakan penanganan pengecualian dengan melakukan pembersihan yang diperlukan setelah meninggalkan blok 'with'. Beberapa built-in python sudah berfungsi sebagai manajer konteks.
sumber
Contoh lain untuk dukungan out-of-the-box, dan yang mungkin agak membingungkan pada awalnya ketika Anda terbiasa dengan cara
open()
berperilaku built-in , adalahconnection
objek modul database populer seperti:The
connection
objek adalah manajer konteks dan dengan demikian dapat digunakan out-of-the-box dalamwith-statement
, namun ketika menggunakan catatan di atas bahwa:Ini berarti bahwa programmer harus berhati-hati untuk menutup koneksi sendiri, tetapi memungkinkan untuk memperoleh koneksi, dan menggunakannya secara berganda
with-statements
, seperti yang ditunjukkan dalam dokumen psycopg2 :Dalam contoh di atas, Anda akan mencatat bahwa
cursor
objekpsycopg2
juga adalah manajer konteks. Dari dokumentasi yang relevan tentang perilaku:sumber
Dalam python umumnya pernyataan " with " digunakan untuk membuka file, memproses data yang ada dalam file, dan juga untuk menutup file tanpa memanggil metode close (). Pernyataan "dengan" membuat pengecualian penanganan lebih sederhana dengan menyediakan kegiatan pembersihan.
Bentuk umum dengan:
catatan: tidak perlu menutup file dengan memanggil close () setelah file-var.close ()
sumber