Python public attributes are better getter-setter

Goal

통상적인 게터-세터를 사용한 코드이지만, 파이써닉하지 않은 코드의 예시이다.

class OldResistor:
	def __init__(self, ohms):
		self._ohms = ohms

	def get_ohms(self):
		return self._ohms

	def set_ohms(self, ohms):
		return self._ohms = ohms

if __name__ == "__main__":
	r0 = OldResistor(50e-3)
	print(f"이전: {r0.get_ohms()}")
	
	r0.set_ohms(10e3)
	print(f"{r0.get_hms()}")  

공개 애트리뷰트를 이용하기

class Resitor:
	def __init__(self, ohms):
		self.ohms = ohms
		self.voltage = 0
		self.current = 0

if __name__ == "__main__":
	r1 = Resistor(50e-3)
	r1.ohms = 10e3
	r1.ohms += 5e3

property decorator 사용 하여 기능 수행하기

class VoltageResistance(Resistor):
	def __init__(self, ohms):
		super().__init__(ohms)
		self._voltage = 0

	@property
	def voltage(self):
		return self._voltage

	@voltage.setter
	def voltage(self, voltage):
		self._voltage = voltage
		self.current = self._voltage / self.ohms

if __name__ == "__main__":
	r2 = VoltageResistance(1e3)
	print(f"이전: {r2.current:.2f} 암페어")

	r2.voltage = 10
	print(f"이후: {r2.current:.2f} 암페어")

Property를 활용 하여 데이터 검증하기

class BoundedResistance(Resistor):
	def __init__(self, ohms):
		super().__init__(ohms)

	@property
	def ohms(self):
		return self._ohms

	@ohms.setter
	def ohms(self, ohms):
		if ohms <= 0:
			raise ValueError(f"저항 > 0이어야 합니다. 실제 값: {ohms}")
		self._ohms = ohms

if __name__ == "__main__":
	r3 = BoundedResistance(-5)
	r3.ohms = 0

# >> ValueError!

Summary