파이썬 데코레이터부터 시작하겠습니다.
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 함수를 수정하고 추가 코드 줄을 추가했다고 말할 수 있습니다.
데코레이터를위한 파이썬 문법
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()
사례 시나리오보다 모든 것을 마무리했지만 그 전에는 몇 가지 원칙에 대해 이야기 해 봅시다.
게터와 세터는 많은 객체 지향 프로그래밍 언어에서 데이터 캡슐화의 원칙을 보장하기 위해 사용됩니다 (이러한 데이터를 처리하는 메소드와 데이터를 묶는 것으로 나타납니다).
이 메소드는 물론 데이터를 검색하기위한 getter와 데이터를 변경하기위한 setter입니다.
이 원칙에 따라 클래스의 속성은 다른 코드로부터 숨기거나 보호하기 위해 비공개로 설정됩니다.
예, @property 는 기본적으로 게터와 세터를 사용 하는 pythonic 방법입니다.
파이썬은 속성이라는 훌륭한 개념을 가지고있어 객체 지향 프로그래머의 삶을 훨씬 단순하게 만듭니다.
온도를 섭씨로 저장할 수있는 클래스를 만들기로 결정했다고 가정 해 봅시다.
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
리팩토링 된 코드, 다음은 속성으로이를 달성 할 수있는 방법입니다.
파이썬에서, property ()는 프로퍼티 객체를 생성하고 반환하는 내장 함수입니다.
속성 개체에는 세 가지 메서드 인 getter (), setter () 및 delete ()가 있습니다.
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 temperature (self)"및 "def temperature (self, x)"를 사용하여 "two"메서드를 작성했습니다.
보시다시피 코드는 덜 우아합니다.
이제 실생활에 관한 실제 장면에 대해 이야기 해 봅시다.
다음과 같이 클래스를 설계했다고 가정 해 봅시다.
class OurClass:
def __init__(self, a):
self.x = a
y = OurClass(10)
print(y.x)
이제 우리 수업이 클라이언트들 사이에서 인기를 얻었고 프로그램에서 사용하기 시작했다고 가정합시다. 그들은 객체에 모든 종류의 과제를 수행했습니다.
그리고 운명적인 날, 신뢰할 수있는 고객이 우리에게 와서 "x"는 0에서 1000 사이의 값이어야한다고 제안했습니다. 이것은 정말로 끔찍한 시나리오입니다!
속성으로 인해 쉽습니다. "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
상상할 수있는 가장 간단한 구현으로 시작할 수 있으며 나중에 인터페이스를 변경하지 않고도 속성 버전으로 자유롭게 마이그레이션 할 수 있습니다! 따라서 속성은 게터와 세터를 대체하는 것이 아닙니다!
이 구현을 여기서 확인할 수 있습니다