백엔드 개발 파이썬 튜토리얼 Python 설명자 시작하기

Python 설명자 시작하기

Dec 05, 2016 pm 01:27 PM
python

나는 오랫동안 Flask 코드에 대해 글을 쓰지 않았습니다. 생각하면 정말 부끄럽습니다. 하지만 이번에도 Flask에 대해 글을 쓰지 않을 것입니다. 나 (넌 정말 나쁜 년이야, 할 수 있으면 나를 물어라)

이번에는 Python에서 매우 중요한 것, 즉 Descriptor에 대해 써보겠습니다

설명어에 대한 첫 소개

과거의 법칙, Talk는 싸다, 코드를 먼저 살펴보자

classPerson(object):
""""""

#----------------------------------------------------------------------
def__init__(self, first_name, last_name):
"""Constructor"""
 self.first_name = first_name
 self.last_name = last_name

#----------------------------------------------------------------------
 @property
deffull_name(self):
"""
 Return the full name
 """
return"%s %s"% (self.first_name, self.last_name)

if__name__=="__main__":
 person = Person("Mike","Driscoll")
 print(person.full_name)
# 'Mike Driscoll'
 print(person.first_name)
# 'Mike'

로그인 후 복사
로그인 후 복사

이 세대, 뭐 재산에 대해서는 다들 잘 아실 텐데, 혹시 모르시는 분들도 계시겠지만, 재산의 구현 메커니즘을 아시나요? 무엇이 명확하지 않습니까? 파이썬을 배워보는 것은 어떨까요? . . 농담입니다. 다음 코드를 살펴보겠습니다.

classProperty(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def__init__(self, fget=None, fset=None, fdel=None, doc=None):
 self.fget = fget
 self.fset = fset
 self.fdel = fdel
ifdocisNoneandfgetisnotNone:
 doc = fget.__doc__
 self.__doc__ = doc

def__get__(self, obj, objtype=None):
ifobjisNone:
returnself
ifself.fgetisNone:
raiseAttributeError("unreadable attribute")
returnself.fget(obj)

def__set__(self, obj, value):
ifself.fsetisNone:
raiseAttributeError("can't set attribute")
 self.fset(obj, value)

def__delete__(self, obj):
ifself.fdelisNone:
raiseAttributeError("can't delete attribute")
 self.fdel(obj)

defgetter(self, fget):
returntype(self)(fget, self.fset, self.fdel, self.__doc__)

defsetter(self, fset):
returntype(self)(self.fget, fset, self.fdel, self.__doc__)

defdeleter(self, fdel):
returntype(self)(self.fget, self.fset, fdel, self.__doc__)

로그인 후 복사

복잡해 보이지 않나요? 차근차근 살펴볼까요? 그러나 여기서 먼저 결론을 내립니다. 설명자는 __get__, __set__ 및 __delete__의 세 가지 특수 메서드를 구현하는 특수 개체입니다.

설명자 상세설명

부동산에 대해 이야기

위에서는 속성 구현 코드를 제공했는데 이제 이에 대해 자세히 설명하겠습니다

classPerson(object):
""""""

#----------------------------------------------------------------------
def__init__(self, first_name, last_name):
"""Constructor"""
 self.first_name = first_name
 self.last_name = last_name

#----------------------------------------------------------------------
 @property
deffull_name(self):
"""
 Return the full name
 """
return"%s %s"% (self.first_name, self.last_name)

if__name__=="__main__":
 person = Person("Mike","Driscoll")
 print(person.full_name)
# 'Mike Driscoll'
 print(person.first_name)
# 'Mike'

로그인 후 복사
로그인 후 복사

우선, 데코레이터에 대해 모르신다면 이 글을 읽어보시면 좋을 것 같습니다. 간단히 말해서, 공식적으로 코드를 실행하기 전에 우리 통역사가 데코레이터와 관련된 부분을 스캔할 것입니다. 클래스 데코레이터도 마찬가지입니다. 위에서 이 코드는

@Property
deffull_name(self):
"""
 Return the full name
 """
return"%s %s"% (self.first_name, self.last_name)
로그인 후 복사

은 이러한 프로세스, 즉 full_name=Property(full_name)를 트리거합니다. 그런 다음 나중에 객체를 인스턴스화한 후 person.full_name을 호출합니다. 이 프로세스는 실제로 person.full_name.__get__(person)과 동일하며 __get__() 메서드에 작성된 반환 self.fget(obj)을 트리거합니다. 위는 우리가 작성한 def full_name의 실행 코드입니다.

이때 동지들은 getter(), setter(), deleter()=의 구체적인 작동 메커니즘에 대해 생각해 볼 수 있습니다. =아직 궁금한 점이 있으시면 댓글로 편하게 토론해주세요.

설명자 정보

앞서 언급한 정의를 기억하세요. 설명자는 __get__, __set__ 및 __delete__라는 세 가지 특별한 메서드를 구현하는 특별한 종류의 객체입니다. 그런 다음 공식 Python 문서 설명에는 설명자의 중요성을 반영하기 위해 다음 단락이 있습니다. "설명자는 속성, 메서드, 정적 메서드, 클래스 메서드 및 super() 뒤에 있는 메커니즘입니다. Python 전체에서 사용됩니다. 버전 2.2에 도입된 새로운 스타일 클래스를 구현하기 위해 자체적으로 설명합니다. 간단히 말해서 설명자가 먼저 있고 그 다음이 air입니다. 새로운 스타일의 클래스에서는 속성, 메서드 호출, 정적 메서드, 클래스 메서드 등이 모두 설명자의 특정 사용을 기반으로 합니다.

자, 설명어가 왜 그렇게 중요한지 물어보고 싶을 수도 있습니다. 걱정하지 마시고 계속 시청해 보세요

설명자 사용

먼저 다음 코드를 살펴보세요

classA(object):#참고: Python 3.x 버전에서는 새 클래스를 사용하기 위해 객체 클래스에서 상속을 명시적으로 지정할 필요가 없습니다. Python 2.X(x> 2) 버전이 필요합니다

defa(self):
pass
if__name__=="__main__":
 a=A()
 a.a()
로그인 후 복사

모두들 a.a()라는 진술이 있다는 것을 알아차렸습니다. 이제 생각해 보세요. 이 메소드를 호출하면 어떻게 될까요?

알았나요? 아직 알아냈나요? 아니요? 알았어 계속하자

우선, 속성이 멤버이든 메서드이든 상관없이 속성을 호출할 때 __getattribute__() 속성을 호출하는 메서드를 트리거합니다. 호출이 구현되었습니다. 설명자 프로토콜은 호출 프로세스 type(a).__dict__['a'].__get__(b,type(b))를 생성합니다. 좋아, 여기에 또 다른 결론이 있습니다. "이러한 호출 프로세스에는 우선순위 순서가 있습니다. 호출하려는 속성이 데이터 설명자라면 이 속성이 인스턴스의 __dict__에 존재하는지 여부에 관계없이 사전에서 설명자의 __get__ 메서드가 먼저 호출됩니다. 호출하려는 속성이 데이터 설명자가 아닌 경우 인스턴스의 __dict__에 있는 기존 속성에 우선 순위를 부여합니다. 우리 클래스와 상위 클래스의 __dict__에 포함된 속성을 찾습니다. 속성이 존재하면 __get__() 메서드가 호출됩니다. 이해하기에는 조금 추상적인가요? 괜찮습니다. 곧 설명하겠지만 여기서는 먼저 데이터 설명자와 비데이터 설명자를 설명한 다음 예를 살펴봐야 합니다. 데이터 설명자와 비데이터 설명자는 무엇입니까? 실제로 설명자에서 __get__ 및 __set__ 프로토콜을 모두 구현하는 설명자는 __get__ 프로토콜만 구현된 경우 데이터 설명자가 아닙니다. 좋습니다. 이제 예를 살펴보겠습니다.

importmath
classlazyproperty:
def__init__(self, func):
 self.func = func

def__get__(self, instance, owner):
ifinstanceisNone:
returnself
else:
 value = self.func(instance)
 setattr(instance, self.func.__name__, value)
returnvalue
classCircle:
def__init__(self, radius):
 self.radius = radius
pass

 @lazyproperty
defarea(self):
 print("Com")
returnmath.pi * self.radius *2

deftest(self):
pass
if__name__=='__main__':
 c=Circle(4)
 print(c.area)

로그인 후 복사

好的,让我们仔细来看看这段代码,首先类描述符 @lazyproperty 的替换过程,前面已经说了,我们不在重复。接着,在我们第一次调用 c.area 的时候,我们首先查询实例 c 的 __dict__ 中是否存在着 area 描述符,然后发现在 c 中既不存在描述符,也不存在这样一个属性,接着我们向上查询 Circle 中的 __dict__ ,然后查找到名为 area 的属性,同时这是一个 non data descriptors ,由于我们的实例字典内并不存在 area 属性,那么我们便调用类字典中的 area 的 __get__ 方法,并在 __get__ 方法中通过调用 setattr 方法为实例字典注册属性 area 。紧接着,我们在后续调用 c.area 的时候,我们能在实例字典中找到 area 属性的存在,且类字典中的 area 是一个 non data descriptors ,于是我们不会触发代码里所实现的 __get__ 方法,而是直接从实例的字典中直接获取属性值。

描述符的使用

描述符的使用面很广,不过其主要的目的在于让我们的调用过程变得可控。因此我们在一些需要对我们调用过程实行精细控制的时候,使用描述符,比如我们之前提到的这个例子

classlazyproperty:
def__init__(self, func):
 self.func = func

def__get__(self, instance, owner):
ifinstanceisNone:
returnself
else:
 value = self.func(instance)
 setattr(instance, self.func.__name__, value)
returnvalue

def__set__(self, instance, value=0):
pass


importmath


classCircle:
def__init__(self, radius):
 self.radius = radius
pass

 @lazyproperty
defarea(self, value=0):
 print("Com")
ifvalue ==0andself.radius ==0:
raiseTypeError("Something went wring")

returnmath.pi * value *2ifvalue !=0elsemath.pi * self.radius *2

deftest(self):
pass

로그인 후 복사

利用描述符的特性实现懒加载,再比如,我们可以控制属性赋值的值

classProperty(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def__init__(self, fget=None, fset=None, fdel=None, doc=None):
 self.fget = fget
 self.fset = fset
 self.fdel = fdel
ifdocisNoneandfgetisnotNone:
 doc = fget.__doc__
 self.__doc__ = doc

def__get__(self, obj, objtype=None):
ifobjisNone:
returnself
ifself.fgetisNone:
raiseAttributeError("unreadable attribute")
returnself.fget(obj)

def__set__(self, obj, value=None):
ifvalueisNone:
raiseTypeError("You can`t to set value as None")
ifself.fsetisNone:
raiseAttributeError("can't set attribute")
 self.fset(obj, value)

def__delete__(self, obj):
ifself.fdelisNone:
raiseAttributeError("can't delete attribute")
 self.fdel(obj)

defgetter(self, fget):
returntype(self)(fget, self.fset, self.fdel, self.__doc__)

defsetter(self, fset):
returntype(self)(self.fget, fset, self.fdel, self.__doc__)

defdeleter(self, fdel):
returntype(self)(self.fget, self.fset, fdel, self.__doc__)

classtest():
def__init__(self, value):
 self.value = value

 @Property
defValue(self):
returnself.value

 @Value.setter
deftest(self, x):
 self.value = x

로그인 후 복사

如上面的例子所描述的一样,我们可以判断所传入的值是否有效等等。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP와 Python : 다른 패러다임이 설명되었습니다 PHP와 Python : 다른 패러다임이 설명되었습니다 Apr 18, 2025 am 12:26 AM

PHP는 주로 절차 적 프로그래밍이지만 객체 지향 프로그래밍 (OOP)도 지원합니다. Python은 OOP, 기능 및 절차 프로그래밍을 포함한 다양한 패러다임을 지원합니다. PHP는 웹 개발에 적합하며 Python은 데이터 분석 및 기계 학습과 같은 다양한 응용 프로그램에 적합합니다.

PHP와 Python 중에서 선택 : 가이드 PHP와 Python 중에서 선택 : 가이드 Apr 18, 2025 am 12:24 AM

PHP는 웹 개발 및 빠른 프로토 타이핑에 적합하며 Python은 데이터 과학 및 기계 학습에 적합합니다. 1.PHP는 간단한 구문과 함께 동적 웹 개발에 사용되며 빠른 개발에 적합합니다. 2. Python은 간결한 구문을 가지고 있으며 여러 분야에 적합하며 강력한 라이브러리 생태계가 있습니다.

Python vs. JavaScript : 학습 곡선 및 사용 편의성 Python vs. JavaScript : 학습 곡선 및 사용 편의성 Apr 16, 2025 am 12:12 AM

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

VScode 확장자가 악의적입니까? VScode 확장자가 악의적입니까? Apr 15, 2025 pm 07:57 PM

VS 코드 확장은 악의적 인 코드 숨기기, 취약성 악용 및 합법적 인 확장으로 자위하는 등 악성 위험을 초래합니다. 악의적 인 확장을 식별하는 방법에는 게시자 확인, 주석 읽기, 코드 확인 및주의해서 설치가 포함됩니다. 보안 조치에는 보안 인식, 좋은 습관, 정기적 인 업데이트 및 바이러스 백신 소프트웨어도 포함됩니다.

Python에서 비주얼 스튜디오 코드를 사용할 수 있습니다 Python에서 비주얼 스튜디오 코드를 사용할 수 있습니다 Apr 15, 2025 pm 08:18 PM

VS 코드는 파이썬을 작성하는 데 사용될 수 있으며 파이썬 애플리케이션을 개발하기에 이상적인 도구가되는 많은 기능을 제공합니다. 사용자는 다음을 수행 할 수 있습니다. Python 확장 기능을 설치하여 코드 완료, 구문 강조 및 디버깅과 같은 기능을 얻습니다. 디버거를 사용하여 코드를 단계별로 추적하고 오류를 찾아 수정하십시오. 버전 제어를 위해 git을 통합합니다. 코드 서식 도구를 사용하여 코드 일관성을 유지하십시오. 라인 도구를 사용하여 잠재적 인 문제를 미리 발견하십시오.

Windows 8에서 코드를 실행할 수 있습니다 Windows 8에서 코드를 실행할 수 있습니다 Apr 15, 2025 pm 07:24 PM

VS 코드는 Windows 8에서 실행될 수 있지만 경험은 크지 않을 수 있습니다. 먼저 시스템이 최신 패치로 업데이트되었는지 확인한 다음 시스템 아키텍처와 일치하는 VS 코드 설치 패키지를 다운로드하여 프롬프트대로 설치하십시오. 설치 후 일부 확장은 Windows 8과 호환되지 않을 수 있으며 대체 확장을 찾거나 가상 시스템에서 새로운 Windows 시스템을 사용해야합니다. 필요한 연장을 설치하여 제대로 작동하는지 확인하십시오. Windows 8에서는 VS 코드가 가능하지만 더 나은 개발 경험과 보안을 위해 새로운 Windows 시스템으로 업그레이드하는 것이 좋습니다.

터미널 VSCODE에서 프로그램을 실행하는 방법 터미널 VSCODE에서 프로그램을 실행하는 방법 Apr 15, 2025 pm 06:42 PM

vs 코드에서는 다음 단계를 통해 터미널에서 프로그램을 실행할 수 있습니다. 코드를 준비하고 통합 터미널을 열어 코드 디렉토리가 터미널 작업 디렉토리와 일치하는지 확인하십시오. 프로그래밍 언어 (예 : Python의 Python Your_file_name.py)에 따라 실행 명령을 선택하여 성공적으로 실행되는지 여부를 확인하고 오류를 해결하십시오. 디버거를 사용하여 디버깅 효율을 향상시킵니다.

PHP와 Python : 그들의 역사에 깊은 다이빙 PHP와 Python : 그들의 역사에 깊은 다이빙 Apr 18, 2025 am 12:25 AM

PHP는 1994 년에 시작되었으며 Rasmuslerdorf에 의해 개발되었습니다. 원래 웹 사이트 방문자를 추적하는 데 사용되었으며 점차 서버 측 스크립팅 언어로 진화했으며 웹 개발에 널리 사용되었습니다. Python은 1980 년대 후반 Guidovan Rossum에 의해 개발되었으며 1991 년에 처음 출시되었습니다. 코드 가독성과 단순성을 강조하며 과학 컴퓨팅, 데이터 분석 및 기타 분야에 적합합니다.

See all articles