Saya melihat ini dalam kode seseorang. Apa artinya?
def __enter__(self):
return self
def __exit__(self, type, value, tb):
self.stream.close()
from __future__ import with_statement#for python2.5
class a(object):
def __enter__(self):
print 'sss'
return 'sss111'
def __exit__(self ,type, value, traceback):
print 'ok'
return False
with a() as s:
print s
print s
python
oop
with-statement
zjm1126
sumber
sumber
Jawaban:
Menggunakan metode ajaib ini (
__enter__
,__exit__
) memungkinkan Anda untuk mengimplementasikan objek yang dapat digunakan dengan mudah denganwith
pernyataan.Idenya adalah membuatnya mudah untuk membangun kode yang memerlukan beberapa kode 'cleandown' dieksekusi (anggap sebagai
try-finally
blok). Penjelasan lebih lanjut di sini .Contoh yang berguna bisa berupa objek koneksi basis data (yang kemudian secara otomatis menutup koneksi setelah pernyataan 'with' keluar dari lingkup):
Seperti dijelaskan di atas, gunakan objek ini dengan
with
pernyataan (Anda mungkin perlu melakukanfrom __future__ import with_statement
di bagian atas file jika Anda menggunakan Python 2.5).PEP343 - 'dengan' pernyataan ' memiliki langgan yang bagus juga.
sumber
__enter__
harus kembaliself
selalu karena hanya metode lain dari kelas yang dapat dipanggil pada konteksnya.def __enter__(self)
dalam PEP 343 dan tidak ada yang melakukannyareturn self
: python.org/dev/peps/pep-0343 . Mengapa menurut Anda begitu?self
objek seperti yang dijelaskan di sini: stackoverflow.com/questions/38281853/… 2) self.XYZ hanyalah bagian dari objek mandiri dan kembali menangani hanya untuk hal yang tampaknya tidak pantas bagi saya dari sudut pandang pemeliharaan. Saya lebih suka untuk kembali menangani untuk menyelesaikan objek dan kemudian menyediakan API publik untuk hanyaself
objek komponen tersebut , yang ingin saya paparkan kepada pengguna seperti diwith open(abc.txt, 'r') as fin: content = fin.read()
self
dari__enter__
, yaitu bagaimana Anda dapat memproses file sebagaif
di dalamwith open(...) as f
Jika Anda tahu apa itu manajer konteks , maka Anda tidak perlu apa-apa lagi untuk memahami
__enter__
dan__exit__
metode sulap. Mari kita lihat contoh yang sangat sederhana.Dalam contoh ini saya membuka myfile.txt dengan bantuan fungsi terbuka . The try / akhirnya memblokir memastikan bahwa bahkan jika pengecualian tak terduga terjadi myfile.txt akan ditutup.
Sekarang saya membuka file yang sama dengan pernyataan:
Jika Anda melihat kode, saya tidak menutup file & tidak ada blok coba / akhirnya . Karena dengan pernyataan otomatis menutup myfile.txt . Anda bahkan dapat memeriksanya dengan memanggil
print(fp.closed)
atribut - yang mengembalikanTrue
.Ini karena objek file (fp dalam contoh saya) yang dikembalikan oleh fungsi terbuka memiliki dua metode bawaan
__enter__
dan__exit__
. Ia juga dikenal sebagai manajer konteks.__enter__
Metode dipanggil di awal dengan blok dan__exit__
metode disebut di akhir. Catatan: dengan pernyataan hanya bekerja dengan objek yang mendukung konteks konteks protokol yaitu mereka miliki__enter__
dan__exit__
metode. Kelas yang menerapkan kedua metode ini dikenal sebagai kelas konteks manajer.Sekarang mari kita mendefinisikan kelas manajer konteks kita sendiri .
Saya harap sekarang Anda memiliki pemahaman dasar tentang keduanya
__enter__
dan__exit__
metode sihir.sumber
Anehnya, sulit untuk menemukan dokumen python untuk
__enter__
dan__exit__
metode dengan Googling, jadi untuk membantu orang lain di sini adalah tautannya:https://docs.python.org/2/reference/datamodel.html#with-statement-context-managers
https://docs.python.org/3/reference/datamodel.html#with-statement-context-managers
(detailnya sama untuk kedua versi)
Saya berharap penjelasan yang jelas tentang
__exit__
argumen metode. Ini kurang tetapi kita dapat menyimpulkan mereka ...Agaknya
exc_type
adalah kelas pengecualian.Dikatakan Anda tidak harus menaikkan kembali pengecualian yang diterima. Ini menyarankan kepada kita bahwa salah satu argumen mungkin merupakan contoh Pengecualian yang sebenarnya ... atau mungkin Anda harus membuat instance sendiri dari jenis dan nilai?
Kami dapat menjawab dengan melihat artikel ini:
http://effbot.org/zone/python-with-statement.htm
... begitu jelas
value
adalah contoh Pengecualian.Dan mungkin
traceback
adalah objek traceback Python .sumber
Selain jawaban di atas untuk mencontohkan pesanan doa, contoh menjalankan sederhana
Menghasilkan output:
Pengingat: saat menggunakan sintaks
with myclass() as mc
, variabel mc mendapatkan nilai yang dikembalikan oleh__enter__()
, dalam kasus di atasNone
! Untuk penggunaan seperti itu, perlu mendefinisikan nilai kembali, seperti:sumber
coba tambahkan jawaban saya (pemikiran saya untuk belajar):
__enter__
dan[__exit__]
keduanya adalah metode yang dipanggil saat masuk dan keluar dari badan " the with statement " ( PEP 343 ) dan implementasi keduanya disebut manajer konteks.pernyataan with bermaksud menyembunyikan kontrol aliran coba akhirnya klausa dan membuat kode tidak dapat dipahami.
sintaks dari pernyataan with adalah:
yang diterjemahkan ke (sebagaimana disebutkan dalam PEP 343):
coba beberapa kode:
dan sekarang coba secara manual (ikuti sintaks terjemahan):
hasil sisi server sama seperti sebelumnya
maaf untuk bahasa inggris saya yang buruk dan penjelasan saya yang tidak jelas, terima kasih ....
sumber
Ini disebut manajer konteks dan saya hanya ingin menambahkan bahwa pendekatan serupa ada untuk bahasa pemrograman lain. Membandingkannya bisa membantu dalam memahami manajer konteks dengan python. Pada dasarnya, manajer konteks digunakan ketika kita berhadapan dengan beberapa sumber daya (file, jaringan, database) yang perlu diinisialisasi dan pada titik tertentu, runtuh (dibuang). Di Java 7 dan di atas kami memiliki manajemen sumber daya otomatis yang mengambil bentuk:
Perhatikan bahwa Sesi perlu mengimplementasikan
AutoClosable
atau salah satu (banyak) sub-antarmuka-nya.Di C # , kami telah menggunakan pernyataan untuk mengelola sumber daya yang berbentuk:
Di mana
Session
harus menerapkanIDisposable
.Dalam python , kelas yang kita gunakan harus mengimplementasikan
__enter__
dan__exit__
. Jadi itu mengambil bentuk:Dan seperti yang ditunjukkan orang lain, Anda selalu dapat menggunakan pernyataan try / akhirnya dalam semua bahasa untuk menerapkan mekanisme yang sama. Ini hanya gula sintaksis.
sumber