English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Python은面向对象的程序员의 생활을 더 간편하게 만드는 great concept로 알려진 attribute를 가지고 있습니다.
property는 무엇인지 정의하고 충분히 이해하기 전에, 먼저 사용이 필요한 이유를 이해해야 합니다.
추정해 보면,객체를 생성하십시오.온도를 켈빈도로 저장하는 클래스입니다. 또한 온도를 화씨 온도로 변환하는 메서드를 구현할 것입니다. 다음은 그 중 하나입니다.
class Celsius: def __init__(self, temperature = 0): self.temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32
이 클래스에서 객체를 생성하고 필요에 따라 속성temperature을 조작할 수 있습니다. Python shell에서 이를 시도해 보세요.
>>> # 新对象创建 >>> man = Celsius() >>> # 温度 설정 >>> man.temperature = 37 >>> # 温度 >>> man.temperature 37 >>> # 华氏度 >>> man.to_fahrenheit() 98.60000000000001
화씨 온도로 변환할 때, 추가적인 소수점 자리수는 부호 연산 오류(예: Python 인터프리터에서)1.1 + 2.2)를 할당하거나 검색할 때마다
위와 같이, 우리가 언제든지 어떤 객체 속성(예:)temperaturePython은 객체의 __dict__ 딕셔너리에서 검색합니다.
>>> man.__dict__ {'temperature': 37}
따라서, man.temperature는 man.__dict__['temperature']로 변경됩니다.
지금, 우리의 강의가 고객들 사이에서 인기가 많으며, 그들은 프로그램에서 이를 사용하기 시작했습니다. 그들은 객체에 다양한 할당을 했습니다.
그런 다음, 신뢰할 수 있는 고객이 우리에게 찾아와, 온도가 아래보다 낮지 않아야 한다고 제안했습니다.-273켈빈도(열역학 전공 학생들은 실제로는 켈빈도라고 할 수 있습니다)-273.15켈빈도(열역학 전공 학생들은 실제로는 켈빈도라고 할 수 있습니다),절대영도로도 알려져 있습니다. 그는 이 값을 제한 조건으로 실현하도록 요구했습니다. 고객 만족도를 추구하는 회사로서 이 제안을 들어 기쁜 마음으로 출시했습니다.1.01버전(존재하는 클래스의 업그레이드)
해결할 수 있는 한 가지 명확한 방법은 속성temperature(을 비공개로 설정)을 숨기고 새로운 getter와 setter 인터페이스를 정의하여对其进行 작업하는 것입니다. 이를 다음과 같이 할 수 있습니다.
class Celsius: def __init__(self, temperature = 0): self.set_temperature(temperature) def to_fahrenheit(self): return(self.get_temperature()) * 1.8) + 32 # new update def get_temperature(self): return self._temperature def set_temperature(self, value): if value < -273: raise ValueError("-273도는 불가능 self._temperature = value
위에서 get_temperature()와 set_temperature()가 새로운 메서드를 정의했음을 볼 수 있으며, _temperature를 temperature로 대체했습니다. 밑줄 (_)으로 시작하는 것은 Python에서의 프라이빗 변수를 의미합니다.
>>> c = Celsius(-277) Traceback (most recent call last): ... ValueError: Temperature below -273 is not possible >>> c = Celsius(37) >>> c.get_temperature() 37 >>> c.set_temperature(10) >>> c.set_temperature(-300) Traceback (most recent call last): ... ValueError: Temperature below -273 is not possible
이 업데이트는 새로운 제한을 성공적으로 구현했습니다. 더 이상 온도를 설정할 수 없도록 허용되지 않습니다.-273.
주의하세요, Python에서는 프라이빗 변수가 없습니다. 몇 가지 규칙을 따르면 됩니다. 언어 자체에는 제한이 없습니다.
>>> c._temperature = -300 >>> c.get_temperature() -300
하지만 이는 큰 문제가 아닙니다. 이 업데이트의 가장 큰 문제는 프로그램에서 이전 클래스를 구현한 모든 클라이언트가 obj.temperature을 obj.get_temperature()로 수정하고, 모든 할당(예: obj.temperature = val을 obj.set_temperature(val)로 수정했습니다.
이 리팩토링은 고객에게 수십만 라인의 코드의 문제를 가져올 수 있습니다.
결론적으로, 우리의 새로운 업데이트는 역후_COMPATIBLE하지 않습니다. 이것이 @property가 작동하는 곳입니다.
Python에서 이 문제를 처리하는 방법은 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("가져온 값") return self._temperature def set_temperature(self, value): if value < -273: raise ValueError("하둘273도는 불가능 print("설정 값") self._temperature = value temperature = property(get_temperature, set_temperature)
이제 실행하면 셸에서 다음과 같은 코드가 출력됩니다.
>>> c = Celsius()
get temperature()와 set temperature()에 print() 함수를 추가하여 실행 상황을 명확히 볼 수 있도록 했습니다.
코드의 마지막 줄에서 property 객체 temperature를 생성합니다. 간단히 말해, 속성은 코드(temperature를 가져오는 get_temperature와 set_temperature)를 멤버 속성 접근(temperature)에 추가합니다.
온도 값을 검색하는 모든 코드는 자동으로 get_temperature()를 호출하며(__dict__) 딕셔너리 검색을 대신합니다. 또한, 온도 값을 할당하는 모든 코드는 자동으로 set_temperature()를 호출합니다. 이는 Python의 매우 재미있는 기능입니다.
위에서 볼 수 있듯이 객체를 생성할 때도 set_temperature()가 호출됩니다.
왜 그런지 궁금하지 않으신가요?
이유는 객체를 생성할 때 __init__() 메서드가 호출되기 때문입니다. 이 메서드의 줄은 self.temperature = temperature입니다. 이 할당은 자동으로 set_temperature()로 호출됩니다.
>>> c.temperature 값 가져오기 0
또한, c.temperature와 같은 어떤 접근도 자동으로 get_temperature()를 호출합니다. 이것이 속성의 역할입니다. 여기에는 몇 가지 예제가 있습니다.
>>> c.temperature = 37 값 설정 >>> c.to_fahrenheit() 값 가져오기 98.60000000000001
속성을 사용하면 클래스를 수정하고 값 제약을 구현할 수 있지만 클라이언트 코드를 변경하지 않아도 됩니다. 따라서 우리의 구현은 후려 compatibile입니다.
마지막으로 주의해야 할 것은 실제 온도 값이 __temperature라는 비공개 변수에 저장되고, temperature 속성은 이 비공개 변수와의 인터페이스를 제공하는 속성 객체라는 점입니다.
Python에서 property()는 내장 함수로, 속성 객체를 생성하고 반환합니다. 이 함수의 서명은 다음과 같습니다.
property(fget=None, fset=None, fdel=None, doc=None)
fget는 속성 값을 얻는 함수이며, fset은 속성 값을 설정하는 함수이고, fdel은 속성을 제거하는 함수입니다. doc은 문자열(예: 주석)입니다. 이러한 함수는 구현에서 선택 사항입니다. 따라서 속성 객체를 간단하게 다음과 같은 방식으로 생성할 수 있습니다.
>>> property() <property object at 0x0000000003239B38>
속성 객체는 getter()、setter() 및 deleter() 세 가지 메서드를 가지고 있으며, 이는 나중에 fget、fset 및 fdel로 지정됩니다. 이는 다음과 같은 의미를 가집니다.
temperature = property(get_temperature, set_temperature)
이것도 분해될 수 있습니다.
# 공백 속성 생성 temperature = property() # fget 설정 temperature = temperature.getter(get_temperature) # fset 설정 temperature = temperature.setter(set_temperature)
이 두 구문은 동일합니다.
안전파이썬의 데코레이터프로그래머는 위의 구조를 데코레이터로 구현할 수 인식할 수 있습니다.
우리는 이름 get_temperature, set_temperature를 정의하지 않고도 더 나아갈 수 있습니다. 이들은 불필요하며 클래스 이름 공간에 영향을 미칩니다. 이를 위해 우리는 getter와 setter 함수 정의할 때 이름 temperature을 재사용했습니다. 이는 가능합니다.
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("가져온 값") return self._temperature @temperature.setter def temperature(self, value): if value < -273: raise ValueError("하둘273도는 불가능 print("설정 값") self._temperature = value
위의 구현은 속성을 만드는 간단한 방법과 권장 방법입니다. 파이썬에서 속성을 찾을 때, 이러한 유형의 구조를 만날 가능성이 높습니다.
좋아, 오늘은 이렇게 할게.