일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 파이썬 동시성
- hyperledger fabric
- 파이썬 강좌
- play 강좌
- 이더리움
- 파이썬 데이터분석
- 플레이프레임워크
- CORDA
- Play2
- Akka
- akka 강좌
- 엔터프라이즈 블록체인
- 블록체인
- 파이썬
- Adapter 패턴
- 안드로이드 웹뷰
- 하이브리드앱
- Hyperledger fabric gossip protocol
- 주키퍼
- 하이퍼레저 패브릭
- 스칼라 강좌
- 스칼라
- Golang
- 그라파나
- 파이썬 머신러닝
- 스칼라 동시성
- play2 강좌
- Play2 로 웹 개발
- Actor
- 스위프트
- Today
- Total
HAMA 블로그
파이썬에서 @property 에 대해 알아보자. 본문
@property 이야기
private 와 public
파이썬에서는 클래스 캡슐화에 필요한 접근지정자를 잘 안쓰는 편이다. 어떤 부분에서는 public 을 권장하는 느낌도 든다. public 이 훨씬 편하니깐~ㅎㅎ (예를들어 시작은 그냥 public 변수를 사용하게 하다가 먼가 제약이 필요할 때 쯤이면 아래 공부할 @property 등으로 처리한다 ) 제약보다는 자유도/책임감을 높히는 방향의 언어인 파이썬 답다.
먼저 말해두는데 파이썬에서 접근지정자는 없다. 즉 아래와 같이 코딩해도 에러가 안난다는 뜻이다
class Test:
def __init__(self):
self.public_field = 5
self.__private_field = 6
self._protected_field = 7
def __private_method(self):
pass
if __name__ == '__main__':
t = Test()
t.public_field = 10
t.__private_field = 11
t._protected_field = 12
다만, __ 가 앞에 있으면 private, _ 한개짜리는 protected 혹은 둘 다 "웬만하면 직접 접근하지 마세요" 로 약속은 한다. 그냥 같이 개발하는 사람에게 정보 제공 정도이지 언어 자체에서 강제한다는게 아니다. 메소드도 마찬가지.
get , set
아래 처럼 get,set 함수를 만들어서 처리 할 수도 있으며
class Test:
def __init__(self):
self.color = "red"
def set_color(self,clr):
self.color = clr
def get_color(self):
return self.color
if __name__ == '__main__':
t = Test()
t.set_color("blue")
print(t.get_color())
( 아 물론 저기에서도 t.set_color("blue") 대신해 t.color = "blue" 해도 된다. )
@property
@property 를 이용하여 이렇게도 가능하다. 코드를 보면 뭐 이런거구나 하고 바로 알 수 있을 것이다.
class Test:
def __init__(self):
self.__color = "red"
@property
def color(self):
return self.__color
@color.setter
def color(self,clr):
self.__color = clr
if __name__ == '__main__':
t = Test()
t.color = "blue"
print(t.color)
물론 강제적인 접근지정자가 존재하지 않으니
t = Test()
t.__color = "blue"
print(t.__color)
이렇게 해두 되지만 -.-;;
get 역할을 하는 어노테이션은 @property 이고, set역할을 하는 어노테이션은 @color.setter 이다.
다른 예를 또 보자
@property 의 파워~
아래와 같은 클래스가 있다고 해보자
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
섭씨 -273 도 이하로 혹시 내려가는 값을 입력받으면 안되기 때문에, temperature 변수를 public 으로 만들지 않고, _temperature 식으로 만들었으며, get,set 을 추가하였다.
하지만 위에 언급했다시피 파이썬에서 private 는 강제가 아니다. 따라서
if __name__ == '__main__':
c = Celsius()
c._temperature = -300
print(c.get_temperature())
계산 같은 얘기 반복하지만, 이렇게도 물론 가능하다.
@Property 를 사용해서는
class Celsius:
def __init__(self):
pass
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 를 사용하는 목적을 간단하게 정리해보면
1. 변수를 변경 할 때 어떠한 제한을 두고 싶어서
2. get,set 함수를 만들지 않고 더 간단하게 접근하게 하기 위해서
3. 하위호환성에 도움이 됨.
4. 등등
이 있다.
하위 호환성에 대해서는 아래에서 자세히 보도록 하자.
하위 호환성
만약 내가 만든 클래스를 누군가가 사용한다고 치자.
처음 만든 클래스는 get,set 도 없었으며, 변수에 직접 접근해서 사용하는거 였다고 치자.
class Celsius:
def __init__(self, temperature=0):
self.temperature = temperature
def to_fahrenheit(self):
return (self. temperature * 1.8) + 32
c = Celsius() c.temperature = 10
class Celsius:
def __init__(self):
pass
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
이렇게 수정하면 사용자는 전혀 코드를 바꾸지도 않아도, temperature 를 사용 할 때 자연스럽게 -273의 제약을 받게 된다.
부록: @property 는 무엇인가?
temperature = property(get_temperature,set_temperature)
내장 함수인 property가 있으며, 인자로 get, set함수가 들어간다. 이걸 편하게 사용하도록한게 @property이다.
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)
레퍼런스:
Effective Python
'Python' 카테고리의 다른 글
파이썬 동시성 프로그래밍 - (1) 쓰레드 (0) | 2017.04.27 |
---|---|
파이썬 더블 언더스코어: Magic Method [펌] (0) | 2017.04.26 |
Functools 의 Partial 이란? (0) | 2017.04.17 |
파이선 가상환경 콘다 시작하기 - pip , virtualenv, conda (0) | 2017.04.13 |
Numpy, Pandas, SciPy, Scikit-learn, Matplotlib 정리 (0) | 2017.04.12 |