Python 언어 학습 (5) (대상 을 대상 으로 하 는 기초 & 진급, 정수 비교 와 내장 목록)

13242 단어 python 학습
대상 기반
  • 대상 을 대상 으로 프로 그래 밍: 데이터 구조 와 처리 방법 으로 대상 (object) 을 구성 하고 같은 행위 의 대상 을 클래스 (class) 로 요약 하 며 클래스 의 패 키 징 (encapsulation) 을 통 해 내부 디 테 일 을 숨 기 고 계승 (inheritance) 을 통 해 클래스 의 특 화 (specialization) 와 일반화 (genealization) 를 실현 하 며 다 중 (polymorphism) 을 통 해대상 유형 에 기반 한 동적 분 파 를 실현 하 다.
  • 쉽게 말 하면 클래스 는 대상 의 청사진 과 템 플 릿 이 고 대상 은 클래스 의 실례 이다.
  • python 에 서 는 class 키워드 정의 류 를 사용 할 수 있 으 며, 클래스 에 서 는 함수 정의 방법 을 통 해 코드 는 다음 과 같 습 니 다.
  • class Student(object):
    
        # __init__                      
        #                  name age    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def study(self, course_name):
            print('%s    %s.' % (self.name, course_name))
    
        # PEP 8                      
        #                      (    )
        def watch_movie(self):
            if self.age < 18:
                print('%s    《   》.' % self.name)
            else:
                print('%s           .' % self.name)
    
  • 클래스 를 정의 하면 대상 을 만 들 고 대상 에 게 메 시 지 를 보 낼 수 있 습 니 다.
  • def main():
        #               
        stu1 = Student('  ', 38)
        #     study  
        stu1.study('Python    ')
        #     watch_av  
        stu1.watch_movie()
        stu2 = Student('   ', 15)
        stu2.study('    ')
        stu2.watch_movie()
    
    
    if __name__ == '__main__':
        main()
    
  • python 에서 속성 과 방법의 접근 권한 은 두 가지 만 있 습 니 다. 공개 와 개인 입 니 다.속성 이 개인 적 이 기 를 원한 다 면 속성 이름 을 붙 일 때 두 개의 밑줄 로 시작 할 수 있 습 니 다. 코드 는 다음 과 같 습 니 다.
  • class Test:
    
        def __init__(self, foo):
            self.__foo = foo
    
        def __bar(self):
            print(self.__foo)
            print('__bar')
    
    
    def main():
        test = Test('hello')
        # AttributeError: 'Test' object has no attribute '__bar'
        test.__bar()
        # AttributeError: 'Test' object has no attribute '__foo'
        print(test.__foo)
    
    
    if __name__ == "__main__":
        main()
    
  • 그러나 사실 python 은 문법 적 으로 사유 성 을 엄 격 히 보장 하지 않 고 개인 적 인 속성 과 방법 으로 이름 을 바 꾸 어 방문 을 방해 할 뿐 이름 을 바 꾸 는 규칙 을 알 면 접근 할 수 있 습 니 다. 코드 는 다음 과 같 습 니 다.
  • class Test:
    
        def __init__(self, foo):
            self.__foo = foo
    
        def __bar(self):
            print(self.__foo)
            print('__bar')
    
    
    def main():
        test = Test('hello')
        test._Test__bar()
        print(test._Test__foo)
    
    
    if __name__ == "__main__":
        main()
    

    대상 을 향 해 승급
  • 실제 개발 에서 속성 을 사유 로 설정 하 는 것 을 권장 하지 않 기 때문에 하위 클래스 에 접근 할 수 없습니다.그러나 속성 을 외부 에 직접 노출 하 는 것 도 문제 가 있다. 속성 명 을 단일 밑줄 로 시작 하 는 것 을 권장 한다. 이렇게 하면 사유 로 설정 되 지 않 을 뿐만 아니 라 보 호 받 는 것 임 을 나 타 낼 수 있 으 므 로 이 속성 을 방문 할 때 신중 해 야 한다.이러한 속성 에 접근 하려 면 속성의 getter (접근 기) 와 setter (수정 기) 방법 으로 해당 하 는 작업 을 할 수 있 습 니 다.@ property 포장 기 를 사용 하여 getter 와 setter 방법 을 포장 하여 속성 에 대한 접근 을 안전 하고 편리 하 게 할 수 있 습 니 다.
  • class Person(object):
    
        def __init__(self, name, age):
            self._name = name
            self._age = age
    
        #     - getter  
        @property
        def name(self):
            return self._name
    
        #     - getter  
        @property
        def age(self):
            return self._age
    
        #     - setter  
        @age.setter
        def age(self, age):
            self._age = age
    
        def play(self):
            if self._age <= 16:
                print('%s      .' % self._name)
            else:
                print('%s      .' % self._name)
    
    
    def main():
        person = Person('   ', 12)
        person.play()
        person.age = 22
        person.play()
        # person.name = '   '  # AttributeError: can't set attribute
    
    
    if __name__ == '__main__':
        main()
    
  • python 은 동적 언어 로 프로그램 이 실 행 될 때 대상 에 게 새로운 속성 이나 방법 을 연결 할 수 있 고 이미 연 결 된 것 을 풀 수 있 습 니 다.단, 사용자 정의 형식 을 제한 할 대상 이 일부 속성 만 연결 할 수 있다 면 클래스 에서 정의 할 수 있 습 니 다slots_변수 로 완성,slots_의 한정 은 현재 클래스 의 대상 에 게 만 적용 되 며, 하위 클래스 에 대해 서 는 작용 하지 않 습 니 다.
  • class Person(object):
    
        #   Person      _name, _age _gender  
        __slots__ = ('_name', '_age', '_gender')
    
    def main():
        person = Person('   ', 22)
        person._gender = ' '
        # AttributeError: 'Person' object has no attribute '_is_gay'
        # person._is_gay = True
    
  • 클래스 에서 정의 하 는 방법 은 대상 방법, 정적 방법 과 클래스 방법 등 을 포함한다.
  • 대상 방법 은 대상 에 게 보 내 는 메시지 이 고 정적 방법 은 클래스 만 정의 하면 클래스 의 인 스 턴 스 를 만 들 지 않 아 도 사용 할 수 있 으 며 클래스 자체 가 아 닌 특정한 대상 에 속한다.
  • from math import sqrt
    
    
    class Triangle(object):
    
        def __init__(self, a, b, c):
            self._a = a
            self._b = b
            self._c = c
    
        @staticmethod #     
        def is_valid(a, b, c):
            return a + b > c and b + c > a and a + c > b
    
        def perimeter(self):
            return self._a + self._b + self._c
    
        def area(self):
            half = self.perimeter() / 2
            return sqrt(half * (half - self._a) *
                        (half - self._b) * (half - self._c))
    
    
    def main():
        a, b, c = 3, 4, 5
        #                      
        if Triangle.is_valid(a, b, c):
            t = Triangle(a, b, c)
            print(t.perimeter())
            #                                  
            # print(Triangle.perimeter(t))
            print(t.area())
            # print(Triangle.area(t))
        else:
            print('       .')
    
    
    if __name__ == '__main__':
        main()
    
  • 클래스 방법 첫 번 째 매개 변 수 는 cls 로 약 정 됩 니 다. 현재 클래스 와 관련 된 정 보 를 대표 하 는 대상 (클래스 자체 도 하나의 대상 이 고 클래스 의 메타 데이터 대상 이 라 고도 함) 입 니 다. 이 매개 변 수 를 통 해 클래스 와 관련 된 정 보 를 얻 고 클래스 의 대상 을 만 들 수 있 습 니 다.
  • from time import time, localtime, sleep
    
    
    class Clock(object):
        """    """
    
        def __init__(self, hour=0, minute=0, second=0):
            self._hour = hour
            self._minute = minute
            self._second = second
    
        @classmethod #    
        def now(cls):
            ctime = localtime(time())
            return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)
    
        def run(self):
            """  """
            self._second += 1
            if self._second == 60:
                self._second = 0
                self._minute += 1
                if self._minute == 60:
                    self._minute = 0
                    self._hour += 1
                    if self._hour == 24:
                        self._hour = 0
    
        def show(self):
            """    """
            return '%02d:%02d:%02d' % \
                   (self._hour, self._minute, self._second)
    
    
    def main():
        #                 
        clock = Clock.now()
        while True:
            print(clock.show())
            sleep(1)
            clock.run()
    
    
    if __name__ == '__main__':
        main()
    
  • 류 와 류 사이 에는 세 가지 관계 가 있다. is - a, has - a 와 use - a.is - a 관 계 는 바로 계승 또는 일반화, 예 를 들 어 학생 - 사람.has - a 관 계 는 관련, 예 를 들 어 부서 - 직원.전체 와 부분의 관련 이 있다 면, 즉 집합 관계 이다.만약 에 전체적으로 부분의 생명주기 (전체 와 부분 은 분리 할 수 없 는 것 이 고 함께 있 으 면서 도 동시에 소멸 하 는 것), 즉 합성 관 계 를 책임 진다 면 가장 강 한 관련 관계 에 속한다.use - a 관 계 는 운전 자의 운전 방법 과 같은 의존 이다. 그 중에서 매개 변 수 는 자동차 에 사용 된다.
  • 대상 을 대상 으로 하 는 세 가지 특성: 포장, 계승 과 다 형.패키지: 숨 길 수 있 는 모든 디 테 일 을 숨 기 고 외부 에 만 간단 한 인 터 페 이 스 를 제공 합 니 다.대상 을 만 든 후 호출 방법 만 있 으 면 실행 할 수 있 습 니 다. 방법의 이름과 들 어 오 는 매개 변수 만 알 고 방법 내부 의 실현 세부 사항 을 알 필요 가 없습니다.계승: 다른 클래스 에서 속성 과 방법 을 직접 계승 하여 중복 코드 의 작성 을 줄 입 니 다.정 보 를 제공 하 는 부모 클래스 는 초 클래스 또는 기본 클래스 라 고도 부른다.정 보 를 계승 하 는 것 은 자 류 로 파생 또는 파생 류 라 고도 부른다.자 류 는 부류 의 속성 과 방법 을 계승 할 수 있 을 뿐만 아니 라 자신의 것 도 정의 할 수 있다. 실제 개발 에 서 는 부류 의 대상 으로 부류 의 대상, 즉 리 씨 교체 원칙 을 대체 하 는 경우 가 많다.다 중: 하위 클래스 는 부모 클래스 의 방법 에 대해 새로운 실현 버 전 을 제시 하고 방법 재 작성 (override) 이 라 고 부 르 며 부모 클래스 의 같은 행 위 를 하위 클래스 에서 서로 다른 버 전 으로 만 듭 니 다.이 하위 클래스 를 거 쳐 다시 쓰 는 방법 을 호출 할 때, 서로 다른 하위 클래스 의 대상 은 서로 다른 행동, 즉 다 중 (poly - morphism) 을 나타 낸다.
  • from abc import ABCMeta, abstractmethod
    
    
    class Pet(object, metaclass=ABCMeta):
        """  """
    
        def __init__(self, nickname):
            self._nickname = nickname
    
        @abstractmethod
        def make_voice(self):
            """    """
            pass
    
    
    class Dog(Pet):
        """ """
    
        def make_voice(self):
            print('%s:    ...' % self._nickname)
    
    
    class Cat(Pet):
        """ """
    
        def make_voice(self):
            print('%s:  ... ...' % self._nickname)
    
    
    def main():
        pets = [Dog('  '), Cat('  '), Dog('  ')]
        for pet in pets:
            pet.make_voice()
    
    
    if __name__ == '__main__':
        main()
    
  • 상기 코드 에서 Pet 류 를 추상 류 로 처리 합 니 다. 즉, 대상 을 만 들 수 없고 다른 류 로 만 계승 할 수 있 습 니 다.python 은 문법 적 인 측면 에서 추상 류 에 대한 지원 을 제공 하지 않 았 지만 abc 모듈 의 ABCMeta 메타 클래스 와 abstractmethod 포장 기 를 통 해 추상 류 의 효 과 를 얻 을 수 있 습 니 다. 만약 에 하나의 유형 에 추상 적 인 방법 이 존재 한다 면 예화 할 수 없습니다.Dog 와 Cat 하위 클래스 는 각각 Pet 클래스 의 Makevoice 추상 적 인 방법 은 서로 다른 재 작성 을 했 고 main 함수 에서 이 방법 을 호출 할 때 다 중 행 위 를 나 타 냈 다.

  • 정수 비교
  • python 에서 두 개의 정 수 를 비교 할 때 두 가지 연산 자가 있 습 니 다. = = is 와 비교 하 는 것 은 두 개의 id 값 이 같 습 니까? 즉, 같은 주 소 를 가리 키 는 지 여부 입 니 다. = = =두 내용 이 같 는 지 비교 하여 실제로 호출 되 었 습 니 다eq_() 방법.
  • 모순 1 코드 는 다음 과 같다.
  • def main():
        x = y = -1
        while True:
            x += 1
            y += 1
            if x is y:
                print('%d is %d' % (x, y))
            else:
                print('Attention! %d is not %d' % (x, y))
                break
    
        x = y = 0
        while True:
            x -= 1
            y -= 1
            if x is y:
                print('%d is %d' % (x, y))
            else:
                print('Attention! %d is not %d' % (x, y))
                break
    
    
    if __name__ == '__main__':
        main()
    
  • 모순 1 해석: python 은 성능 을 고려 하여 자주 사용 하 는 정수 대상 을 small 라 는 이름 으로 캐 시 합 니 다.ints 의 링크 에 서 는 이 정수 대상 을 사용 해 야 할 때 다시 만 들 지 않 고 캐 시 를 직접 참조 합 니 다.캐 시 구간 은 [- 5, 256] 이 며, is 를 사용 하여 비교 할 때 이 범위 내 에서 같은 주 소 를 가리 키 고, 이 범 위 를 초과 하면 다시 만 들 기 위해 257 is 257 결 과 를 false 로 얻 을 수 있 습 니 다.
  • 모순 2 코드 는 다음 과 같다.
  • import dis
    a = 257
    
    
    def main():
        b = 257  #  6 
        c = 257  #  7 
        print(b is c)  # True
        print(a is b)  # False
        print(a is c)  # False
    
    
    if __name__ == "__main__":
        main()
    
  • 모순 2 해석: 코드 블록 은 프로그램의 최소 실행 단위 로 상기 코드 에서 a = 257 과 main 은 두 개의 코드 블록 에 속한다.python 은 성능 을 향상 시 키 기 위해 같은 코드 블록 에서 만 든 정수 대상 을 규정 합 니 다. [- 5, 256] 의 범 위 를 초과 하 더 라 도 값 이 같은 정수 대상 이 존재 하면 후속 생 성 은 직접 참조 합 니 다.이 규칙 은 small 에 있 지 않 습 니 다.ints 범위 내의 음수 와 음수 치 부동 점 수 는 적용 되 지 않 지만, 비음 부동 점 수 와 문자열 에는 모두 적용 된다.따라서 c 는 b 의 257 을 인 용 했 고 a 와 b 는 같은 코드 블록 에 없 기 때문에 주석 에서 의 실행 결 과 를 얻 을 수 있다.
  • dis 모듈 을 가 져 오고 main () 방법 에 'dis. dis (main)' 라 는 문장 을 추가 하면 어 셈 블 리 를 할 수 있 습 니 다. 바이트 코드 의 측면 에서 볼 때 이 코드 를 볼 수 있 습 니 다.실행 결과 코드 6, 7 줄 의 257 은 같은 위치 에서 불 러 왔 고 9 줄 의 a 는 다른 곳 에서 불 러 왔 기 때문에 서로 다른 대상 을 인용 했다.

  • 새 겨 진 목록
  • 목록 의 요소, 즉 포 함 된 목록 으로 현실 표, 행렬, 바둑판 등 을 모 의 할 수 있 으 나 신중하게 사용 해 야 합 니 다. 그렇지 않 으 면 문제 가 발생 할 수 있 습 니 다. 코드 는 다음 과 같 습 니 다.
  • def main():
        names = ['  ', '  ', '  ', '  ', '  ']
        subjs = ['  ', '  ', '  ']
        scores = [[0] * 3] * 5
        for row, name in enumerate(names):
            print('   %s   ' % name)
            for col, subj in enumerate(subjs):
                scores[row][col] = float(input(subj + ': '))
        print(scores)
    
    
    if __name__ == '__main__':
        main()
    
  • 상기 코드 는 원래 다섯 명의 학우 의 세 과목 의 성적 을 입력 하려 고 했 으 나 최종 수출 결과 에 따 르 면 각 학생 의 세 과목 의 성적 이 똑 같 고 마지막 에 입력 한 그 학생 의 성적 이다.이 문 제 를 해결 하려 면 대상 과 대상 을 구분 하 는 인용 두 가지 개념 이 필요 합 니 다. 이것 은 메모리 의 스 택 과 더미 와 관련 됩 니 다.
  • 프로그램 에서 사용 할 수 있 는 메모 리 는 논리 적 으로 다섯 부분 으로 나 눌 수 있 습 니 다. 주소 에 따라 높 은 것 에서 낮은 것 으로 스 택, 쌓 기, 데이터 세그먼트, 읽 기 전용 데이터 세그먼트 와 코드 세그먼트 입 니 다.그 중에서 스 택 은 부분, 임시 변수, 그리고 함수 호출 시 현장 에 필요 한 데 이 터 를 저장 하고 복원 하 는 데 사 용 됩 니 다. 이 부분 에 코드 블록 이 실 행 될 때 자동 으로 분배 되 고 끝 날 때 자동 으로 방출 되 며 보통 컴 파일 러 가 자동 으로 관리 합 니 다.쌓 인 크기 가 고정 되 지 않 아 동적 으로 분배 하고 회수 할 수 있 으 며 프로그램 에 처리 해 야 할 데이터 가 많 으 면 쌓 아 올 리 는 경우 가 많다.쌓 아 올 리 는 공간 이 제대로 풀 리 지 않 으 면 메모리 유출 문 제 를 일 으 킬 수 있다. 파 이 썬, 자바 등 은 쓰레기 수 거 메커니즘 (더 이상 사용 하지 않 는 쌓 아 올 리 는 공간 자동 회수) 을 사용 해 자동 화 된 메모리 관 리 를 실현 한다.
  • 따라서 다음 과 같은 코드 를 예 로 들 면 변수 a 는 진정한 대상 이 아니 라 대상 의 인용 으로 대상 이 쌓 인 공간 에 있 는 주 소 를 기록 한 것 과 같다.마찬가지 로 변수 b 는 목록 용기 의 인용 입 니 다. 공간 에 있 는 목록 용 기 를 참조 하 였 으 며, 목록 용기 에는 실제 대상 이 저장 되 어 있 지 않 습 니 다.
  • a = object()
    b = ['apple', 'pitaya', 'grape']
    
  • 최초의 프로그램 을 보고 목록 을 [0] * 3] * 5 작업 할 때 [0, 0, 0] 이라는 목록 의 주 소 를 복사 하 는 것 일 뿐 새로운 목록 대상 을 만 들 지 않 았 다.따라서 용기 에는 다섯 가지 요소 가 있 지만 같은 목록 대상 을 인용 하여 매번 입력 할 때마다 이 목록 대상 을 수정 한 것 과 같 기 때문에 최종 적 으로 마지막 학생 의 성적 을 표시 합 니 다. 정확 한 코드 는 다음 과 같 습 니 다.
  • def main():
        names = ['  ', '  ', '  ', '  ', '  ']
        subjs = ['  ', '  ', '  ']
        scores = [[]] * 5 #  scores = [[0] * 3 for _ in range(5)]
        for row, name in enumerate(names):
            print('   %s   ' % name)
            scores[row] = [0] * 3
            for col, subj in enumerate(subjs):
                scores[row][col] = float(input(subj + ': '))
        print(scores)
    
    
    if __name__ == '__main__':
        main()
    

    좋은 웹페이지 즐겨찾기