Python 고급 문법 4: 클래스 대상과 실례 대상의 접근 속성의 차이와property 속성

9687 단어
1. 정태적 방법과 유형적 방법, 그리고 실례적 방법을 다시 논한다.
  • 1.1, 클래스 속성, 실례 속성은 정의와 사용에서 차이가 있지만 가장 본질적인 차이는 메모리에 저장된 위치가 다르다는 것이다.
  • 실례 속성은 대상에 속한다
  • 클래스 속성은 클래스
    class Province(object):
          #  
          country = ' '
    
          def __init__(self, name):
                #  
                self.name = name
    
    
    #  
    obj = Province(' ')
    #  
    print(obj.name)
    #  
    Province.country
    
    에 속한다. 상기 코드에서 알 수 있듯이 [실례 속성은 대상을 통해 접근해야 한다] [클래스 속성은 클래스를 통해 접근한다]. 사용에서 실례 속성과 클래스 속성의 귀속이 다르다는 것을 알 수 있다.
  • 클래스 속성은 메모리에 한 부만 저장
  • 실례 속성은 각 대상에 한 부씩 저장해야 한다
  • 응용 장면: 클래스를 통해 실례 대상을 만들 때 각 대상이 같은 이름의 속성을 필요로 한다면 클래스 속성을 사용하고 하나의 기가
  • 를 사용한다.
  • 1.2 실례 방법, 정적 방법과 유형 방법(클래스 안의 세 가지 방법은 호출 방식이 다르다는 데 차이가 있다)
  • 실례 방법: 대상에서 호출;최소한self 매개 변수;실례적인 방법을 실행할 때 이 방법을 호출한 대상을self에 자동으로 부여한다.
  • 클래스 방법: 클래스에서 호출;최소한cls 매개 변수;클래스 방법을 실행할 때, 자동으로 이 방법의 클래스를 cls에 할당합니다.
  • 정적 방법: 클래스에서 호출;기본 매개 변수 없음;
    class Foo(object):
         def __init__(self, name):
               self.name = name
    
    def ord_func(self):
         """  , self  """
         # print(self.name)
         print(' ')
    
    @classmethod
    def class_func(cls):
         """  , cls  """
         print(' ')
    
    @staticmethod
    def static_func():
         """   , """
         print(' ')
    
    
    f = Foo(" ")
    #  
    f.ord_func()
    
    #  
    Foo.class_func()
    
    #  
    Foo.static_func()
    
  • 공통점: 모든 방법이 클래스에 속하기 때문에 메모리에도 한 부만 저장
  • 차이점: 방법 호출자가 다르고 호출 방법이 자동으로 전송되는 파라미터가 다르다.



  • 2. property 속성
  • 2.1,property 속성이 무엇인지, 방법명에 property를 더하면property 속성이고 호출에 있어서dog.rundog.eat()
    class Dog(object):
    
          def eat(self):
                print(" ")
    
          #  property 
          @property
          def run(self):
                print(" ")
    
    dog = Dog()
    dog.eat()  #  
    dog.run    #  property 
    
    보다 낫다.
  • property 속성의 정의와 호출은 몇 가지를 주의해야 한다.
  • 정의할 때 실례적인 방법에 @property 장식기를 추가합니다.그리고self 매개 변수가 하나밖에 없음
  • 호출 시 괄호 필요 없음
     :dog.eat() 
    property :dog.run
    

  • 2.2,property 속성은 두 가지 방식이 있다
  • 장식기 즉: 방법에 장식기를 적용
  • 클래스 속성: 클래스에서 정의된 값이property 대상인 클래스 속성
  • 2.2.1 장식기 방식은 클래스의 실례적인 방법에 @property 장식기를 응용한다. 파이톤의 클래스는 고전 클래스와 신식 클래스가 있고 신식 클래스의 속성은 고전 클래스의 속성보다 풍부하다.(클래스가 Object에 이어지면 이 클래스는 신식 클래스)
  • 클래식 클래스, @property 장식기
    class Goods:
       @property
       def price(self):
            return "laowang"
    # ###############   ###############
    obj = Goods()
    result = obj.price  #   @property   price  , 
    print(result)
    
  • 신식 클래스, 세 가지 @property 장식기
    # ###############   ###############
    class Goods:
          """python3 object 
           python2、3 , python3 @xxx.setter  @xxx.deleter
          """
          @property
          def price(self):
               print('@property')
    
          @price.setter
          def price(self, value):
               print('@price.setter')
    
          @price.deleter
          def price(self):
               print('@price.deleter')
    
    # ###############   ###############
    obj = Goods()
    obj.price          #   @property   price  , 
    obj.price = 123    #   @price.setter   price  ,   123  
    del obj.price      #   @price.deleter   price  
    
    주의
  • 고전 클래스의 속성은 하나의 접근 방식만 있고 @property에 의해 수식되는 방법
  • 신식 클래스의 속성은 세 가지 접근 방식이 있고 각각 @property, @ 방법 이름 세 개에 대응한다.setter, @ 메소드 이름.deleter 수식 방법
  • 신식 클래스에 세 가지 접근 방식이 있기 때문에 우리는 그들의 몇 가지 속성의 접근 특징에 따라 각각 세 가지 방법을 같은 속성에 대해 정의할 수 있다. 즉, 얻기, 수정, 삭제
    class Goods(object):
    
         def __init__(self):
             #  
             self.original_price = 100
             #  
             self.discount = 0.8
    
         @property
         def price(self):
             #   =   *  
             new_price = self.original_price * self.discount
             return new_price
    
         @price.setter
         def price(self, value):
             self.original_price = value
    
         @price.deleter
         def price(self):
             del self.original_price
    
    obj = Goods()
    obj.price         #  
    obj.price = 200   #  
    del obj.price     #  
    
  • 2.2.2 클래스 속성 방식, 창설 값은property 대상의 클래스 속성입니다. 저는 이 방식을 비교적 좋아합니다.
  • 방식으로 창설property 할 때 클래식 클래스와 신식 클래스는 다를 것이 없다
    class Person:
       def get_name(self):
          return 'laowang'
    
       BAR = property(get_name)
    
    obj = Person()
    reuslt = obj.BAR  #  get_bar , 
    print(reuslt)
    
  • property 방법 중 개
  • 첫 번째 매개 변수는 방법명, 호출 . 시 자동 트리거 실행 방법
  • 두 번째 매개 변수는 방법명, 호출 . = XXX시 자동 트리거 실행 방법
  • 세 번째 매개 변수는 방법명, 호출del . 시 자동 트리거 실행 방법
  • 네 번째 파라미터는 문자열이고 호출 . .__doc__이며 이 파라미터는 이 속성의 설명 정보
  • 이다.
    class Person(object):
    
         def __init__(self,name):
              self.name = name
    
         def get_name(self): 
              return self.name
    
         def set_name(self,new_name):
    
              self.name = new_name
              print(" :%s"%self.name)
    
         def del_name(self):
              del  self.name
    
         BAR = property(get_name,set_name,del_name," ...")
    
    
    person = Person(" ")
    person.BAR      #  :get_name
    person.BAR = " " #  :set_name ,  " "  
    
    person.del_name  #  :del_name 
    
    desc = Person.BAR.__doc__   #  : ...
    
    print(" :%s"%desc)
    
    클래스 속성 방식으로property 속성을 만드는 데 3가지 접근 방식이 있기 때문에 우리는 그들의 몇 가지 속성의 접근 특징에 따라 각각 세 가지 방법을 같은 속성에 대해 정의할 수 있다. 얻기, 수정, 삭제, 다음과 같은 상품의 가격
    class Goods(object):
    
        def __init__(self):
            #  
            self.original_price = 100
            #  
            self.discount = 0.8
    
        def get_price(self):
            #   =   *  
            new_price = self.original_price * self.discount
            return new_price
    
        def set_price(self, value):
            self.original_price = value
    
        def del_price(self):
            del self.original_price
    
        PRICE = property(get_price, set_price, del_price, ' ...')
    
    obj = Goods()
    obj.PRICE         #  
    obj.PRICE = 200   #  
    del obj.PRICE     #  
    
  • 2.3. Django 프레임워크에property 속성(이해)이 적용되었고WEB 프레임워크 Django의 보기에서request.POST는 클래스 속성을 사용하는 방식으로 생성된 속성
    class WSGIRequest(http.HttpRequest):
          def __init__(self, environ):
               script_name = get_script_name(environ)
               path_info = get_path_info(environ)
               if not path_info:
                  # Sometimes PATH_INFO exists, but is empty (e.g. accessing
                  # the SCRIPT_NAME URL without a trailing slash). We really need to
                  # operate as if they'd requested '/'. Not amazingly nice to force
                  # the path like this, but should be harmless.
                  path_info = '/'
               self.environ = environ
               self.path_info = path_info
               self.path = '%s/%s' % (script_name.rstrip('/'), path_info.lstrip('/'))
               self.META = environ
               self.META['PATH_INFO'] = path_info
               self.META['SCRIPT_NAME'] = script_name
               self.method = environ['REQUEST_METHOD'].upper()
               _, content_params = cgi.parse_header(environ.get('CONTENT_TYPE', ''))
               if 'charset' in content_params:
                       try:
                           codecs.lookup(content_params['charset'])
                       except LookupError:
                           pass
                       else:
                           self.encoding = content_params['charset']
               self._post_parse_error = False
               try:
                    content_length = int(environ.get('CONTENT_LENGTH'))
               except (ValueError, TypeError):
                    content_length = 0
               self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
               self._read_started = False
               self.resolver_match = None
    
           def _get_scheme(self):
               return self.environ.get('wsgi.url_scheme')
    
           def _get_request(self):
               warnings.warn('`request.REQUEST` is deprecated, use `request.GET` or '
                   '`request.POST` instead.', RemovedInDjango19Warning, 2)
               if not hasattr(self, '_request'):
                     self._request = datastructures.MergeDict(self.POST, self.GET)
               return self._request
    
            @cached_property
            def GET(self):
                  # The WSGI spec says 'QUERY_STRING' may be absent.
                  raw_query_string = get_bytes_from_wsgi(self.environ, 'QUERY_STRING', '')
                  return http.QueryDict(raw_query_string, encoding=self._encoding)
    
            # ###############    ###############
           def _get_post(self):
                 if not hasattr(self, '_post'):
                     self._load_post_and_files()
                 return self._post
    
           # ###############    ###############
           def _set_post(self, post):
                 self._post = post
    
           @cached_property
           def COOKIES(self):
                 raw_cookie = get_str_from_wsgi(self.environ, 'HTTP_COOKIE', '')
                 return http.parse_cookie(raw_cookie)
    
           def _get_files(self):
                 if not hasattr(self, '_files'):
                     self._load_post_and_files()
                 return self._files
    
           # ###############    ###############
           POST = property(_get_post, _set_post)
    
    FILES = property(_get_files)
    REQUEST = property(_get_request)
    
  • 종합하여 서술하다.
  • property 속성을 정의하는 것은 모두 두 가지 방식이 있는데 그것이 바로 [장식기]와 [클래스 속성]이고 [장식기] 방식은 고전 클래스와 신식 클래스에 따라 다르다.
  • property 속성을 사용하여 호출자가 데이터를 얻는 절차를 간소화할 수 있음
  • 좋은 웹페이지 즐겨찾기