Saya tertarik dengan cara menggunakan @property
Python. Saya sudah membaca dokumen python dan contohnya di sana, menurut saya, hanyalah kode mainan:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Saya tidak tahu manfaat apa yang bisa saya dapatkan dari membungkus yang _x
diisi dengan dekorator properti. Mengapa tidak menerapkan saja sebagai:
class C(object):
def __init__(self):
self.x = None
Saya pikir, fitur properti mungkin berguna dalam beberapa situasi. Tapi ketika? Bisakah seseorang tolong beri saya beberapa contoh dunia nyata?
Terima kasih.
python
oop
properties
python-decorators
xiao 啸
sumber
sumber
Jawaban:
Contoh lain adalah validasi / penyaringan atribut yang ditetapkan (memaksa mereka untuk berada dalam batas atau dapat diterima) dan evaluasi malas dari istilah yang kompleks atau berubah dengan cepat.
Perhitungan kompleks yang tersembunyi di balik atribut:
Validasi:
sumber
Satu use case sederhana adalah dengan menetapkan atribut instance read only, seperti yang Anda tahu memimpin nama variabel dengan satu garis bawah
_x
pada python biasanya berarti itu pribadi (penggunaan internal) tetapi kadang-kadang kita ingin dapat membaca atribut instance dan tidak menulis jadi kita bisa gunakanproperty
untuk ini:sumber
c._x
, jika pengguna menginginkannya. Python sebenarnya tidak memiliki atribut pribadi.Lihatlah artikel ini untuk penggunaan yang sangat praktis. Singkatnya, ini menjelaskan bagaimana dengan Python Anda biasanya dapat membuang metode pengambil / penyetel eksplisit, karena jika Anda membutuhkannya pada tahap tertentu Anda dapat menggunakan
property
untuk implementasi yang mulus.sumber
Satu hal yang saya gunakan untuk itu adalah caching nilai yang lambat untuk dicari, tetapi tidak berubah, disimpan dalam database. Ini bersifat umum untuk situasi apa pun di mana atribut Anda memerlukan perhitungan atau operasi panjang lainnya (mis. Pemeriksaan basis data, komunikasi jaringan) yang hanya ingin Anda lakukan sesuai permintaan.
Ini ada di aplikasi web di mana setiap tampilan halaman yang diberikan mungkin hanya memerlukan satu atribut tertentu dari jenis ini, tetapi objek yang mendasarinya sendiri mungkin memiliki beberapa atribut seperti itu - menginisialisasi mereka semua pada konstruksi akan sia-sia, dan properti memungkinkan saya untuk fleksibel di mana atributnya malas dan mana yang tidak.
sumber
@cached_property
ini?Membaca melalui jawaban dan komentar, tema utama tampaknya adalah jawaban yang sepertinya tidak ada contoh sederhana namun bermanfaat. Saya telah memasukkan yang sangat sederhana di sini yang menunjukkan penggunaan sederhana
@property
dekorator. Ini adalah kelas yang memungkinkan pengguna untuk menentukan dan mendapatkan pengukuran jarak menggunakan berbagai unit yang berbeda, yaituin_feet
atauin_metres
.Pemakaian:
sumber
Properti hanyalah abstraksi di sekitar bidang yang memberi Anda lebih banyak kontrol pada cara-cara bidang tertentu dapat dimanipulasi dan untuk melakukan perhitungan middleware. Beberapa penggunaan yang terlintas dalam pikiran adalah validasi dan inisialisasi sebelumnya serta pembatasan akses
sumber
Ya, untuk contoh asli yang diposkan, properti akan bekerja persis sama dengan hanya memiliki variabel instan 'x'.
Ini adalah hal terbaik tentang properti python. Dari luar, mereka bekerja persis seperti variabel instan! Yang memungkinkan Anda untuk menggunakan variabel instan dari luar kelas.
Ini berarti contoh pertama Anda sebenarnya bisa menggunakan variabel instan. Jika semuanya berubah, dan kemudian Anda memutuskan untuk mengubah implementasi Anda dan properti berguna, antarmuka ke properti akan tetap sama dari kode di luar kelas. Perubahan dari variabel instan ke properti tidak berdampak pada kode di luar kelas.
Banyak bahasa dan kursus pemrograman lain akan menginstruksikan bahwa seorang programmer tidak boleh mengekspos variabel instan, dan sebagai gantinya menggunakan 'getter' dan 'setter' untuk nilai apa pun untuk diakses dari luar kelas, bahkan kasus sederhana seperti dikutip dalam pertanyaan.
Kode di luar kelas dengan banyak bahasa (misalnya Java) digunakan
Dan ketika mengimplementasikan kelas ada banyak 'getter' dan 'setter' yang melakukan persis seperti contoh pertama Anda: mereplikasi variabel instance sederhana. Getter dan setter ini diperlukan karena jika implementasi kelas berubah, semua kode di luar kelas perlu diubah. Tapi properti python memungkinkan kode di luar kelas sama dengan variabel instan. Jadi kode di luar kelas tidak perlu diubah jika Anda menambahkan properti, atau memiliki variabel instance sederhana. Jadi tidak seperti kebanyakan bahasa Berorientasi Objek, untuk contoh sederhana Anda, Anda dapat menggunakan variabel instan alih-alih 'getter' dan 'setter' yang benar-benar tidak diperlukan, aman dalam pengetahuan bahwa jika Anda mengubah ke properti di masa depan, kode menggunakan kelasmu tidak perlu berubah.
Ini berarti Anda hanya perlu membuat properti jika ada perilaku kompleks, dan untuk kasus sederhana yang sangat umum di mana, seperti yang dijelaskan dalam pertanyaan, hanya variabel instan yang diperlukan, Anda bisa menggunakan variabel instan.
sumber
fitur bagus lain dari properti dibandingkan menggunakan setter dan getter sehingga mereka memungkinkan Anda untuk terus menggunakan OP = operator (misalnya + =, - =, * = dll) pada atribut Anda sambil tetap mempertahankan validasi, kontrol akses, caching, dll yang setter dan getter akan memasok.
misalnya jika Anda menulis kelas
Person
dengan settersetage(newage)
, dan pengambilgetage()
, maka untuk menambah usia Anda harus menulis:tetapi jika Anda membuat
age
properti, Anda bisa menulis yang jauh lebih bersih:sumber
Jawaban singkat untuk pertanyaan Anda, adalah bahwa dalam contoh Anda, tidak ada manfaatnya. Anda mungkin harus menggunakan formulir yang tidak melibatkan properti.
Alasan properti ada, adalah bahwa jika kode Anda berubah di masa mendatang, dan Anda tiba-tiba perlu berbuat lebih banyak dengan data Anda: nilai cache, melindungi akses, meminta beberapa sumber daya eksternal ... apa pun, Anda dapat dengan mudah memodifikasi kelas Anda untuk menambahkan getter dan setters untuk data tanpa mengubah antarmuka, sehingga Anda tidak perlu menemukan di mana-mana dalam kode Anda di mana data itu diakses dan mengubahnya juga.
sumber
Sesuatu yang banyak orang tidak perhatikan pada awalnya adalah Anda dapat membuat subclass properti Anda sendiri. Ini saya temukan sangat berguna untuk mengekspos atribut objek hanya baca atau atribut yang dapat Anda baca dan tulis tetapi tidak menghapus. Ini juga merupakan cara terbaik untuk membungkus fungsionalitas seperti pelacakan modifikasi ke bidang objek.
sumber
attr = reader('_attr')
baris atau semacam prechecking sepertiattr = if self.__isValid(value): reader('_attr')
. Saran?attr = reader('_attr')
keattr = accessor('_attr')
. Terima kasih