Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Python

Menguasai Decorator @property Python: Getter dan Setter Bersih & Kompatibel Mundur

Menguasai Decorator @property Python

Temukan bagaimana decorator bawaan @property Python memungkinkan Anda menulis getter dan setter yang ringkas dan mudah dipelihara sambil menjaga API Anda tetap kompatibel mundur.

Decorator @property Python adalah alat yang kuat untuk enkapsulasi akses atribut. Ia memungkinkan Anda menentukan logika kustom yang berjalan setiap kali atribut dibaca atau ditulis, tanpa memaksa caller untuk mengubah kode mereka. Dalam bagian berikut kita akan melalui contoh dunia nyata—penanganan konversi suhu—tunjukkan cara memberlakukan batasan, dan menjelaskan mengapa @property adalah solusi idiomatik.


Sebuah Kelas Tanpa Getter dan Setter

Misalkan kita membutuhkan kelas sederhana yang menyimpan suhu dalam Celsius dan dapat mengonversi ke Fahrenheit:

class Celsius:
    def __init__(self, temperature=0):
        self.temperature = temperature
    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32

Menggunakannya sederhana:

# Create a new object
human = Celsius()
# Set the temperature
human.temperature = 37
# Read the temperature
print(human.temperature)
# Convert to Fahrenheit
print(human.to_fahrenheit())

Output

37 98.60000000000001

Hasil floating-point diharapkan karena representasi biner desimal. Saat Anda memeriksa human.__dict__, Anda akan melihat bahwa Python menyimpan nilai dalam entri dictionary biasa:

>>> human.__dict__
{'temperature': 37}

Menambahkan Batasan dengan Getter dan Setter

Objek dunia nyata sering memerlukan validasi. Misalnya, suhu tidak dapat di bawah nol mutlak (-273.15 °C). Salah satu cara yang sederhana adalah menyembunyikan atribut dan mengekspos metode getter/setter eksplisit:

class Celsius:
    def __init__(self, temperature=0):
        self.set_temperature(temperature)
    def to_fahrenheit(self):
        return (self.get_temperature() * 1.8) + 32
    # getter
    def get_temperature(self):
        return self._temperature
    # setter
    def set_temperature(self, value):
        if value < -273.15:
            raise ValueError("Temperature below -273.15 is not possible.")
        self._temperature = value

Sekarang kelas memberlakukan batas bawah, tetapi kode apa pun yang mengakses obj.temperature harus diperbarui untuk memanggil obj.get_temperature() dan obj.set_temperature(val). Itu adalah refactor besar untuk basis kode besar.

Selain itu, variabel "private" Python hanyalah konvensi penamaan—_temperature masih dapat diakses langsung, melanggar enkapsulasi. Inilah tempat @property muncul.


Menggunakan Kelas property

Python menawarkan kelas property yang mengaitkan fungsi getter dan setter ke nama atribut:

class Celsius:
    def __init__(self, temperature=0):
        self.temperature = temperature
    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32
    # getter
    def get_temperature(self):
        print("Getting value...")
        return self._temperature
    # setter
    def set_temperature(self, value):
        print("Setting value...")
        if value < -273.15:
            raise ValueError("Temperature below -273.15 is not possible")
        self._temperature = value
    # expose as a property
    temperature = property(get_temperature, set_temperature)

Dengan pengaturan ini, kode berikut berperilaku sama seperti kelas sederhana asli, tetapi dengan validasi di balik layar:

human = Celsius(37)
print(human.temperature) # triggers getter
print(human.to_fahrenheit()) # uses getter internally
human.temperature = -300 # triggers setter and raises ValueError

Output

Setting value... Getting value... 37 Getting value... 98.60000000000001 Setting value... Traceback (most recent call last): ... ValueError: Temperature below -273 is not possible

Perhatikan bagaimana kode yang mengakses temperature tetap tidak berubah; hanya implementasi dasar yang mendapatkan validasi.

Tip: Data aktual tinggal di _temperature; temperature hanyalah antarmuka yang nyaman dan aman.


The @property Decorator

Sementara kelas property bekerja, sintaks decorator Python menawarkan cara yang lebih bersih dan lebih mudah dibaca untuk mencapai hasil yang sama. Decorator secara otomatis membuat objek property dan mengaitkan getter dan setter ke nama atribut.

class Celsius:
    def __init__(self, temperature=0):
        self.temperature = temperature
    def to_fahrenheit(self):
        return (self.temperature * 1.8) + 32
    @property
    def temperature(self):
        print("Getting value...")
        return self._temperature
    @temperature.setter
    def temperature(self, value):
        print("Setting value...")
        if value < -273.15:
            raise ValueError("Temperature below -273 is not possible")
        self._temperature = value

Usage remains the same:

human = Celsius(37)
print(human.temperature)
print(human.to_fahrenheit())
# Attempting to set an invalid temperature
try:
    Celsius(-300)
except ValueError as e:
    print(e)

Output

Setting value... Getting value... 37 Getting value... 98.60000000000001 Setting value... Traceback (most recent call last): ... ValueError: Temperature below -273 is not possible

Menggunakan @property menjaga namespace tetap rapi, menghilangkan kebutuhan akan nama metode getter/setter terpisah, dan adalah pola yang direkomendasikan untuk sebagian besar pengembang Python.

Python

  1. Menguasai Tipe Data Python: Panduan Praktis
  2. Menguasai Operator Python: Panduan Komprehensif
  3. Menguasai Pernyataan Pass Python: Panduan Praktis
  4. Menguasai Argumen Fungsi Python: Posisi, Kata Kunci, dan Parameter Default
  5. Menguasai Kamus Python: Pembuatan, Manipulasi, dan Teknik Lanjutan
  6. Menguasai Warisan Python: Konsep, Sintaks, dan Contoh Praktis
  7. Menguasai Operator Overloading di Python: Panduan Praktis
  8. Menguasai Iterator Python: Cara Kerja dan Membuat Sendiri
  9. Penutupan (Closure) Python Dijelaskan: Cara Fungsi Bertingkat Mengambil Variabel
  10. Menguasai Decorator @property Python: Getter dan Setter Bersih & Kompatibel Mundur