Python
Dalam tutorial ini, Anda akan belajar tentang Python @property decorator; cara pythonic untuk menggunakan getter dan setter dalam pemrograman berorientasi objek.
Pemrograman Python memberi kita @property
bawaan dekorator yang membuat penggunaan pengambil dan penyetel lebih mudah dalam Pemrograman Berorientasi Objek.
Sebelum masuk ke detail tentang apa @property
dekorator adalah, pertama-tama mari kita membangun intuisi tentang mengapa itu diperlukan.
Mari kita asumsikan bahwa kita memutuskan untuk membuat kelas yang menyimpan suhu dalam derajat Celcius. Itu juga akan menerapkan metode untuk mengubah suhu menjadi derajat Fahrenheit. Salah satu caranya adalah sebagai berikut:
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
Kita dapat membuat objek dari kelas ini dan memanipulasi temperature
atribut sesuai keinginan kita:
# Basic method of setting and getting attributes in Python
class Celsius:
def __init__(self, temperature=0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
# Create a new object
human = Celsius()
# Set the temperature
human.temperature = 37
# Get the temperature attribute
print(human.temperature)
# Get the to_fahrenheit method
print(human.to_fahrenheit())
Keluaran
37 98.60000000000001
Tempat desimal ekstra saat dikonversi ke Fahrenheit adalah karena kesalahan aritmatika floating point. Untuk mempelajari lebih lanjut, kunjungi Python Floating Point Arithmetic Error.
Setiap kali kami menetapkan atau mengambil atribut objek apa pun seperti temperature
seperti yang ditunjukkan di atas, Python mencarinya di __dict__
. bawaan objek atribut kamus.
>>> human.__dict__
{'temperature': 37}
Oleh karena itu, man.temperature
secara internal menjadi man.__dict__['temperature']
.
Misalkan kita ingin memperluas kegunaan Celsius kelas yang ditentukan di atas. Kita tahu bahwa suhu benda apa pun tidak dapat mencapai di bawah -273,15 derajat Celcius (Nol Mutlak dalam Termodinamika)
Mari perbarui kode kita untuk menerapkan batasan nilai ini.
Solusi yang jelas untuk pembatasan di atas adalah dengan menyembunyikan atribut temperature
(jadikan pribadi) dan tentukan metode pengambil dan penyetel baru untuk memanipulasinya. Ini dapat dilakukan sebagai berikut:
# Making Getters and Setter methods
class Celsius:
def __init__(self, temperature=0):
self.set_temperature(temperature)
def to_fahrenheit(self):
return (self.get_temperature() * 1.8) + 32
# getter method
def get_temperature(self):
return self._temperature
# setter method
def set_temperature(self, value):
if value < -273.15:
raise ValueError("Temperature below -273.15 is not possible.")
self._temperature = value
Seperti yang bisa kita lihat, metode di atas memperkenalkan dua get_temperature()
baru dan set_temperature()
metode.
Selanjutnya, temperature
diganti dengan _temperature
. Garis bawah _
di awal digunakan untuk menunjukkan variabel pribadi dengan Python.
Sekarang, mari kita gunakan implementasi ini:
# Making Getters and Setter methods
class Celsius:
def __init__(self, temperature=0):
self.set_temperature(temperature)
def to_fahrenheit(self):
return (self.get_temperature() * 1.8) + 32
# getter method
def get_temperature(self):
return self._temperature
# setter method
def set_temperature(self, value):
if value < -273.15:
raise ValueError("Temperature below -273.15 is not possible.")
self._temperature = value
# Create a new object, set_temperature() internally called by __init__
human = Celsius(37)
# Get the temperature attribute via a getter
print(human.get_temperature())
# Get the to_fahrenheit method, get_temperature() called by the method itself
print(human.to_fahrenheit())
# new constraint implementation
human.set_temperature(-300)
# Get the to_fahreheit method
print(human.to_fahrenheit())
Keluaran
37 98.60000000000001 Traceback (most recent call last): File "<string>", line 30, in <module> File "<string>", line 16, in set_temperature ValueError: Temperature below -273.15 is not possible.
Pembaruan ini berhasil menerapkan pembatasan baru. Kami tidak lagi diperbolehkan menyetel suhu di bawah -273,15 derajat Celcius.
Catatan :Variabel pribadi sebenarnya tidak ada di Python. Hanya ada norma yang harus diikuti. Bahasa itu sendiri tidak menerapkan batasan apa pun.
>>> human._temperature = -300
>>> human.get_temperature()
-300
Namun, masalah yang lebih besar dengan pembaruan di atas adalah bahwa semua program yang mengimplementasikan kelas kami sebelumnya harus mengubah kodenya dari obj.temperature
ke obj.get_temperature()
dan semua ekspresi seperti obj.temperature = val
ke obj.set_temperature(val)
.
Pemfaktoran ulang ini dapat menyebabkan masalah saat menangani ratusan ribu baris kode.
Secara keseluruhan, pembaruan baru kami tidak kompatibel ke belakang. Di sinilah @property
datang untuk menyelamatkan.
Cara Pythonic untuk mengatasi masalah di atas adalah dengan menggunakan property
kelas. Berikut adalah bagaimana kami dapat memperbarui kode kami:
# using property class
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
# creating a property object
temperature = property(get_temperature, set_temperature)
Kami menambahkan print()
fungsi di dalam get_temperature()
dan set_temperature()
untuk mengamati dengan jelas bahwa mereka sedang dieksekusi.
Baris terakhir kode membuat objek properti temperature
. Sederhananya, properti melampirkan beberapa kode (get_temperature
dan set_temperature
) ke akses atribut anggota (temperature
).
Mari gunakan kode pembaruan ini:
# using property class
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
# creating a property object
temperature = property(get_temperature, set_temperature)
human = Celsius(37)
print(human.temperature)
print(human.to_fahrenheit())
human.temperature = -300
Keluaran
Setting value... Getting value... 37 Getting value... 98.60000000000001 Setting value... Traceback (most recent call last): File "<string>", line 31, in <module> File "<string>", line 18, in set_temperature ValueError: Temperature below -273 is not possible
Seperti yang kita lihat, kode apa pun yang mengambil nilai temperature
akan secara otomatis memanggil get_temperature()
alih-alih pencarian kamus (__dict__). Demikian pula, kode apa pun yang memberikan nilai ke temperature
akan secara otomatis memanggil set_temperature()
.
Kita bahkan dapat melihat di atas bahwa set_temperature()
dipanggil bahkan saat kita membuat objek.
>>> human = Celsius(37)
Setting value...
Dapatkah Anda menebak alasannya?
Alasannya adalah ketika sebuah objek dibuat, __init__()
metode dipanggil. Metode ini memiliki baris self.temperature = temperature
. Ekspresi ini secara otomatis memanggil set_temperature()
.
Demikian pula, akses apa pun seperti c.temperature
secara otomatis memanggil get_temperature()
. Inilah yang dilakukan properti. Berikut adalah beberapa contoh lagi.
>>> human.temperature
Getting value
37
>>> human.temperature = 37
Setting value
>>> c.to_fahrenheit()
Getting value
98.60000000000001
Dengan menggunakan property
, kita dapat melihat bahwa tidak ada modifikasi yang diperlukan dalam penerapan batasan nilai. Dengan demikian, implementasi kami kompatibel ke belakang.
Catatan :Nilai suhu aktual disimpan di _temperature
private pribadi variabel. temperature
atribut adalah objek properti yang menyediakan antarmuka ke variabel pribadi ini.
Dengan Python, property()
adalah fungsi bawaan yang membuat dan mengembalikan property
obyek. Sintaks dari fungsi ini adalah:
property(fget=None, fset=None, fdel=None, doc=None)
dimana,
fget
adalah fungsi untuk mendapatkan nilai dari atributfset
adalah fungsi untuk mengatur nilai atributfdel
adalah fungsi untuk menghapus atributdoc
adalah string (seperti komentar)Dilihat dari implementasinya, argumen fungsi ini bersifat opsional. Jadi, objek properti cukup dibuat sebagai berikut.
>>> property()
<property object at 0x0000000003239B38>
Objek properti memiliki tiga metode, getter()
, setter()
, dan deleter()
untuk menentukan fget
, fset
dan fdel
di kemudian hari. Artinya, baris:
temperature = property(get_temperature,set_temperature)
dapat dipecah menjadi:
# make empty property
temperature = property()
# assign fget
temperature = temperature.getter(get_temperature)
# assign fset
temperature = temperature.setter(set_temperature)
Kedua potongan kode ini setara.
Pemrogram yang akrab dengan Dekorator Python dapat mengenali bahwa konstruksi di atas dapat diimplementasikan sebagai dekorator.
Kami bahkan tidak dapat menentukan nama get_temperature
dan set_temperature
karena tidak diperlukan dan mencemari namespace kelas.
Untuk ini, kami menggunakan kembali temperature
name sambil mendefinisikan fungsi pengambil dan penyetel kami. Mari kita lihat bagaimana menerapkan ini sebagai dekorator:
# Using @property decorator
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
# create an object
human = Celsius(37)
print(human.temperature)
print(human.to_fahrenheit())
coldest_thing = Celsius(-300)
Keluaran
Setting value... Getting value... 37 Getting value... 98.60000000000001 Setting value... Traceback (most recent call last): File "", line 29, in File " ", line 4, in __init__ File " ", line 18, in temperature ValueError: Temperature below -273 is not possible
Implementasi di atas sederhana dan efisien. Ini adalah cara yang disarankan untuk menggunakan property
.
Python
String Python Dalam tutorial ini Anda akan belajar membuat, memformat, memodifikasi, dan menghapus string dengan Python. Selain itu, Anda akan diperkenalkan dengan berbagai operasi dan fungsi string. Video:String Python Apa itu String di Python? String adalah urutan karakter. Karakter hanyalah s
Set Python Dalam tutorial ini, Anda akan mempelajari segala sesuatu tentang set Python; bagaimana mereka dibuat, menambahkan atau menghapus elemen darinya, dan semua operasi yang dilakukan pada set dengan Python. Video:Diset dengan Python Set adalah kumpulan item yang tidak berurutan. Setiap eleme
Python strftime() Dalam artikel ini, Anda akan belajar mengonversi objek tanggal, waktu, dan waktu ke string yang setara (dengan bantuan contoh) Video:Tanggal dan Waktu dengan Python strftime() metode mengembalikan string yang mewakili tanggal dan waktu menggunakan objek tanggal, waktu atau datet
Python strptime() Dalam artikel ini, Anda akan belajar membuat objek datetime dari string (dengan bantuan contoh). Video:Tanggal dan Waktu dengan Python strptime() metode membuat objek datetime dari string yang diberikan. Catatan: Anda tidak dapat membuat datetime objek dari setiap string. Strin