เริ่มต้นด้วยการตกแต่ง Python
Python decorator เป็นฟังก์ชั่นที่ช่วยเพิ่มฟังก์ชันเพิ่มเติมให้กับฟังก์ชั่นที่กำหนดไว้แล้ว
ใน Python ทุกอย่างเป็นวัตถุ ฟังก์ชั่นใน Python เป็นวัตถุชั้นหนึ่งซึ่งหมายความว่าพวกเขาสามารถอ้างอิงโดยตัวแปรเพิ่มในรายการที่ส่งผ่านเป็นข้อโต้แย้งไปยังฟังก์ชั่นอื่น ๆ ฯลฯ
พิจารณาข้อมูลโค้ดต่อไปนี้
def decorator_func(fun):
def wrapper_func():
print("Wrapper function started")
fun()
print("Given function decorated")
# Wrapper function add something to the passed function and decorator
# returns the wrapper function
return wrapper_func
def say_bye():
print("bye!!")
say_bye = decorator_func(say_bye)
say_bye()
# Output:
# Wrapper function started
# bye
# Given function decorated
ที่นี่เราสามารถพูดได้ว่าฟังก์ชั่นมัณฑนากรปรับเปลี่ยนฟังก์ชั่น say_hello ของเราและเพิ่มบรรทัดพิเศษของรหัสในนั้น
Python ไวยากรณ์สำหรับมัณฑนากร
def decorator_func(fun):
def wrapper_func():
print("Wrapper function started")
fun()
print("Given function decorated")
# Wrapper function add something to the passed function and decorator
# returns the wrapper function
return wrapper_func
@decorator_func
def say_bye():
print("bye!!")
say_bye()
เอาเป็นว่าสรุปทุกอย่างให้ดีกว่าสถานการณ์สมมติ แต่ก่อนหน้านี้เรามาพูดถึงโอ๊ะโอเบื้องต้น
Getters และ setters ใช้ในการเขียนโปรแกรมเชิงวัตถุหลายภาษาเพื่อให้แน่ใจว่าหลักการของการห่อหุ้มข้อมูล (ถูกมองว่าเป็นการรวมข้อมูลด้วยวิธีการที่ทำงานกับข้อมูลเหล่านี้)
แน่นอนว่าวิธีการเหล่านี้เป็นตัวเรียกใช้เพื่อดึงข้อมูลและตัวตั้งค่าสำหรับการเปลี่ยนแปลงข้อมูล
ตามหลักการนี้แอตทริบิวต์ของคลาสนั้นถูกทำให้เป็นส่วนตัวเพื่อซ่อนและปกป้องพวกเขาจากรหัสอื่น
Yup, @propertyนั้นเป็นวิธีการแบบ pythonic ในการใช้ getters และ setters
Python มีแนวคิดที่ดีที่เรียกว่าคุณสมบัติซึ่งทำให้ชีวิตของโปรแกรมเมอร์เชิงวัตถุง่ายขึ้นมาก
ให้เราสมมติว่าคุณตัดสินใจที่จะเรียนที่สามารถเก็บอุณหภูมิในหน่วยองศาเซลเซียสได้
class Celsius:
def __init__(self, temperature = 0):
self.set_temperature(temperature)
def to_fahrenheit(self):
return (self.get_temperature() * 1.8) + 32
def get_temperature(self):
return self._temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
self._temperature = value
Refactored Code นี่คือวิธีที่เราจะประสบความสำเร็จกับคุณสมบัติ
ใน Python คุณสมบัติ () เป็นฟังก์ชันในตัวที่สร้างและส่งคืนวัตถุคุณสมบัติ
วัตถุคุณสมบัติมีสามวิธี, getter (), setter () และลบ ()
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
def get_temperature(self):
print("Getting value")
return self.temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self.temperature = value
temperature = property(get_temperature,set_temperature)
ที่นี่
temperature = property(get_temperature,set_temperature)
อาจถูกทำลายได้
# make empty property
temperature = property()
# assign fget
temperature = temperature.getter(get_temperature)
# assign fset
temperature = temperature.setter(set_temperature)
ชี้ไปที่หมายเหตุ:
- get_temperature ยังคงเป็นคุณสมบัติแทนวิธีการ
ตอนนี้คุณสามารถเข้าถึงค่าอุณหภูมิโดยการเขียน
C = Celsius()
C.temperature
# instead of writing C.get_temperature()
เราสามารถดำเนินการต่อไปและไม่กำหนดชื่อget_temperatureและset_temperatureเนื่องจากไม่มีความจำเป็นและทำให้เนมสเปซคลาสสกปรก
วิธี pythonicที่จะจัดการกับปัญหาดังกล่าวคือการใช้@property
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):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self.temperature = value
คะแนนที่ควรทราบ -
- วิธีการที่ใช้สำหรับรับค่านั้นถูกตกแต่งด้วย "@property"
- วิธีการที่จะทำหน้าที่เป็น setter นั้นถูกตกแต่งด้วย "@ temperature.setter" หากฟังก์ชั่นนั้นถูกเรียกว่า "x" เราจะต้องตกแต่งด้วย "@ x.setter"
- เราเขียนวิธีการ "สอง" ที่มีชื่อเดียวกันและจำนวนพารามิเตอร์ที่แตกต่างกัน "อุณหภูมิ def (ตัวเอง)" และ "อุณหภูมิ def (ตัวเอง, x)"
อย่างที่คุณเห็นรหัสนั้นดูสง่างามน้อยลงอย่างแน่นอน
ทีนี้เรามาพูดถึงฉากจริงสำหรับชีวิตจริง
สมมติว่าคุณได้ออกแบบคลาสดังนี้:
class OurClass:
def __init__(self, a):
self.x = a
y = OurClass(10)
print(y.x)
ทีนี้มาลองสมมติว่าคลาสของเราได้รับความนิยมในหมู่ลูกค้าและพวกเขาเริ่มใช้มันในโปรแกรมของพวกเขาพวกเขาทำการมอบหมายทุกอย่างให้กับวัตถุ
และวันหนึ่งเป็นเวรเป็นกรรมลูกค้าที่เชื่อถือได้มาหาเราและแนะนำว่า "x" ต้องมีค่าระหว่าง 0 ถึง 1,000 นี่เป็นสถานการณ์ที่น่ากลัวจริงๆ!
เนื่องจากคุณสมบัติเป็นเรื่องง่าย: เราสร้างรุ่นคุณสมบัติของ "x"
class OurClass:
def __init__(self,x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
if x < 0:
self.__x = 0
elif x > 1000:
self.__x = 1000
else:
self.__x = x
นี่มันยอดเยี่ยมใช่มั้ย: คุณสามารถเริ่มต้นด้วยการติดตั้งที่ง่ายที่สุดเท่าที่จะเป็นไปได้และคุณสามารถโยกย้ายไปยังรุ่นคุณสมบัติได้ในภายหลังโดยไม่ต้องเปลี่ยนอินเตอร์เฟส ดังนั้นคุณสมบัติไม่ได้เป็นเพียงการแทนที่ตัวรับและตัวตั้งค่า!
คุณสามารถตรวจสอบการใช้งานได้ที่นี่