연구 노트 : Python3 객체 지향

또한 잘못된 경우 개인 사용에 대한 접근은, 저를 수정하시기 바랍니다.

객체 지향 프로그래밍은 프로그래밍입니다 디자인 . 객체 기본 프로그램과 같은 수단은 , 객체가 포함 된 데이터 및 데이터의 조작 기능 .

이 디자인 아이디어는 자연에서 온 것입니다. 때문에 자연에서, 클래스 (클래스)예 (인스턴스) 개념은 매우 당연하다. 클래스 플레이어 선수의 개념을 의미하고, 인스턴스 (인스턴스) 예를 들어, 하나의 콘크리트 플레이어입니다 : 클래스 예를 들어, 우리는 클래스 선수를 정의, 추상적 인 개념이다 요르단, 듀란트가 다릅니다.

: 프로그래밍 경험은 객체 지향 세 가지 특징을 알고 캡슐화 , 상속 , 다형성 .

  • 클래스의 예

    클래스는 추상 템플릿입니다. 예를 들어, 플레이어 클래스입니다. 객체의 구체적인 예는, 각각 같은 방법이 있습니다.

    • 클래스의 정의

      키워드 class, 클래스 이름 (대문자), 그리고 마지막으로 (객체) . 그는 적절하지 않은 경우의 선택에, 상속되는 클래스를 표시 할 수 있습니다 object그렇게 종류이기 때문에, 클래스 의 조상 .

      class Player(object):
          pass
    • 의 인스턴스를 만듭니다

      유사한 함수 호출로, 여기있다 클래스 이름 () 작업.

      # 创建实例1
      player1 = Player()
      # 创建实例2
      player2 = Player()
    • 속성 바인딩

      만들어 __init__.py방법을 self대표 인스턴스 자체.

      class Player(object):
      
          def __init__(self, name, age):
              self.name = name
              self.age = age

      의 방법으로 재산을 취득 하는 객체입니다. 등록

      # 创建实例1
      player1 = Player("Jordan", 45)
      # 获取属性
      name = player1.name
      age = player1.age
    • 꾸러미

      이제, 우리는 인스턴스가 이러한 속성을 가질 수 있다는 것을 알고. 직접 클래스 내에서 의 정의 데이터에 대한 액세스 기능 들은 "데이터"할 수 있도록 패키지 까지. 그리고 그 방법은 클래스의 함수이다.

      인쇄 이름의 구현, 연령

      class Player(object):
      
          def __init__(self, name, age):
              self.name = name
              self.age = age
      
          def print_name_age(self):
              print("%s, %d"%(self.name, self.age))
      
      player1 = Player("Jack", "30")
      print(player1.print_name_age())

      보기의 호출자의 관점에서, 한 I는 입력의 인스턴스를 만들 때와 같은 name, age. 그리고 그 방법은 내가 원하는 것을 얻을,라고합니다. 내부의 특정 클래스를 달성하는 방법, 내가 관리 할 필요가 없습니다.

  • 액세스 제한

    상기 클래스와 경우에, 우리는 클래스 내부 속성과 메소드를 가질 수 있다는 것을 배웠습니다. 그리고 외부 코드도 할 수있다 자유롭게 변경할 수 인스턴스의 속성을. 사실,이는 안전하지 , 우리는해야 되지 않도록 이러한 작업을. 즉, 민간 공공 변경이 변수를 가지고있다.

    • 부동산 민영화

      파이썬에서, 두 개의 밑줄을 사용하여 __사유 재산을 나타낼 수 있습니다. 우리의 플레이어 클래스의 지속적인 개선.

      class Player(object):
      
          def __init__(self, name, age):
              self.__name = name
              self.__age = age
      
          def print_name_age(self):
              return "%s, %d" % (self.__name, self.__age)
      
      
      player1 = Player("Jack", 30)
      print(player1.__name)   # ERROR 

      속성이 민영화 된 후에는 획득 할 수 없습니다.

    • , 취득 재산의 민영화를 수정

      사실 매우 간단합니다, 그것은 것입니다 get, set방법. 이제 클래스에 추가 get_name, get_age방법, 및 set_name, set_age방법. 우리의 플레이어 클래스를 변경하기 위해 계속합니다.

      class Player(object):
      
          def __init__(self, name, age):
              self.__name = name
              self.__age = age
      
          def get_name(self):
              return self.__name
      
          def get_age(self):
              return self.__age
      
          def set_age(self, age):
              self.__age = age
      
          def print_name_age(self):
              return "%s, %d" % (self.__name, self.__age)
      
      
      player1 = Player("Jack", 30)
      player1.set_age(100)
      print(player1.get_name())       # Jack
      print(player1.get_age())        # 100

      물론, 변경 기능을 달성했다. 방법을 추가 할 수 없습니다, 당신은 바로 지금, 획득, 수정하는 방법이 다소 불필요한 추가 할 수 있습니다. 사실, 방법은 추가하지 목표로하는 것은 , 매개 변수의 검사를 만들기 위해 유효하지 않은 매개 변수를 전달하지 않도록하는 것입니다.

       def set_age(self, age):
              if 0 <= age <= 100:
                  self.__age = age
              else:
                  raise ValueError('bad score')

      물론, 실제 개발 프로젝트, 당신은, 밑줄 인스턴스 속성의 시작을 볼 수 있습니다 _name. 액세스는 액세스 할 수 있지만 당신은 비공개로를 참조하십시오.

      당신이 작성하지 않은 경우 마지막 get방법을 호출 할 수 없습니다, 물론 당신은 파이썬 인터프리터, 수 있기 때문에 __name속성이된다 _Player__name. 하지만 난 당신이 잊지 좋습니다. 권장하지 않음

  • 상속 및 다형성

    • 상속

      클래스 정의가 말한 것, 모든 클래스는 상속 할 수 있습니다 object우리 자신의 정의를 상속 할 수 있습니다 같은 클래스를.

      예를 들어, I는 정의 Animal동물이 있으며, 동물 run()방법.

      나는 개와 고양이를 작성하는 경우,이 동물을 상속 할 수 있습니다.

      class Animal(object):
      
          def run(self):
              return "animal is running"
      
      class Dog(Animal):
          pass
      
      class Cat(Animal):
          pass

      상속의 장점은 : 서브 클래스는 개와 고양이가 이미 가지고 있다는 것을 의미, 부모 클래스의 모든 기능을 얻을 수 있습니다 run()갈 길을.

      위의 예제를 바탕으로, 우리는 전화로 이동합니다.

      dog = Dog()
      print(dog.run())
      
      cat = Cat()
      print(cat.run())
      
      # output
      animal is running
      animal is running

      로직을 준수하기 위해, 우리는 코드를 변경 계속

      class Animal(object):
      
          def run(self):
              return "animal is running"
      
      class Dog(Animal):
      
          def run(self):
              return "dog is running"
      
      class Cat(Animal):
      
          def run(self):
              return "cat is running"
      
      dog = Dog()
      print(dog.run())
      
      cat = Cat()
      print(cat.run())
      
      # output:
      dog is running
      cat is running

      이것은 실행에 누가 매우 분명하다.

      서브 클래스와 동일한 수퍼에 존재할 때 run()의 시간 인 방법. 부모 클래스 커버하는 서브 클래스입니다.

    • 다형성

      우선, 다형성 또는 이해하기 어려운 비트를 들어, 우리는 단지 프로그램을 통해 강화 해 나갈 수 있습니다.

      class Animal(object):
      
          def run(self):
              return "animal is running"
      
      class Dog(Animal):
      
          pass
      
      class Cat(Animal):
      
          def run(self):
              return "cat is running"
      
      
      dog = Dog()
      print(isinstance(dog, Dog))
      print(isinstance(dog, Animal))
      
      # output:
      True
      True

      위의 코드에서 알 수있는 바와 같이 dog속하는 Dog유형과에 속하는 Animal유형. 유사하게, cat그것은 동일하다.

      객체가있는 경우 우리는 객체를 전달할 때 run()구현에 대한 방법을. 그렇지 않은 경우, 상위 클래스의 전화 이동 run()방법. 이 다형성이다.

      이것은 동적 언어, 동적 언어 당신이 호출 할 수 있습니다, 제대로 한 방법이있는 한, 종류를 확인하지 않습니다, 매개 변수를 인스턴스 메소드를 호출합니다.

      공부를 계속

      import json
      
      f = open('/path/to/file.json', 'r')
      print(json.load(f))
      
      class Students(object):
          def __init__(self, strlist):
              self.strlist = strlist
      
          def read(self):
              return(self.strlist)
      
      s = Students('["Tim", "Bob", "Alice"]')
      
      print(json.load(s))

      이후 f개체가 갖는 read()방법 및 s개체가 read()방법.

      따라서, 어떤 물체가만큼 같은 것으로 간주 될 수 read()메서드를 호출 파일과 같은 오브젝트를 통과 할 수있다 json.load().

  • 개체 정보 가져 오기

    개체 유형 분석 : isinstance()함수를 객체의 취득 type()유형 : .

    오브젝트 속성 및 메소드를 가져 : dir()기능.

  • 속성과 클래스 속성의 예

    우리는 당신이 사용할 수있는 앞서 언급 한 __init__.py예는 바인딩 속성 방법.

    마찬가지로, 클래스는 속성을 가질 수있다. 그리고이 모든 속성을 분류합니다.

    class Player(object):
    
        country = "chinese"

    우리는 클래스 속성을 정의 할 때, 비록 모든 분류하지만,에 액세스 할 수있는 클래스의 인스턴스입니다.

    위의 테스트 인수

    p = Player()          # 创建实例p
    
    print(p.country)       # 打印country属性,因为实例并没有country属性,所以会继续查找类属性
    
    print(Player.country) # 打印类属性
    
    p.country = "small Japan" # 给实例绑定country属性
    print(p.country)          # 由于实例属性的优先级高于类属性,因此屏蔽了类的属性
    
    print(Player.country)     # 但是类属性并未消失。还是可以访问
    
    del p.country             # 删除实例绑定的属性之后
    
    print(p.country)          # 再去调用,就只能委屈得到类属性了。

    참고 : 실제 프로그래밍을 수행 할 때 하지 에 대한 예를 속성클래스 속성 은 Using 같은 에서 이름 .

  • 클래스 메소드

    언급 한 이전 인스턴스 속성과 메소드를 가지고, 속성의 종류가있다, 또한 방법이있다.

    class Person(object):
    
        count = 0
    
        @classmethod
        def how_many(cls):
            return cls.count
    
        def __init__(self, name):
            self.name = name
            Person.count = Person.count + 1
    
    print(Person.how_many())
    p1 = Person('Bob')
    print(Person.how_many()) 

    그것은 표시하여, 볼 수 있습니다 @classmethod 결합, Person오히려 클래스보다는 클래스 인스턴스를. 입력 클래스 메소드 클래스 자체의 최초의 파라미터는 일반적으로 변수 이름으로 명명 cls위, cls.count실제로 동등한 Person.count.

    오히려 인스턴스에 호출하는 것보다 클래스 호출에 있기 때문에, 그러므로 클래스 메소드 없습니다 얻을 인스턴스 변수 만 얻을 수 있습니다 참조 클래스를 .

  • __slots__

    당신이 동적으로 결합 할 수 있기 때문에, 그래서 우리는 방법이이 건물의 인스턴스를 제한하는 데 사용됩니다, 제한 할 필요가있다. 예를 들어 다음과 같은 절차는 :

    class Student(object):    
      __slots__ = ('name', 'age')
    
    s = Student()
    s.name = "Jack"
    s.age = 20
    s.score = 90      # AttributeError

    위의 과정을 볼 수있다하십시오 튜플 정의 할 수 있습니다 바인딩속성 이름, 이후 점수 넣어되지 않은 __slots__에서, 그것은 바인딩 할 수 없습니다 점수 속성을. 이 경우 학생은 서브 클래스가, slots아무런 효과가 없습니다 정의 서브 클래스 속성.

  • @재산

    우리는 전면에 대한 액세스를 제한하는 언급했다. 변수 간의 관계. 우리가 사용하는 get, set방법. 그것은 조금 너무 편리 속성을 직접적으로, 복잡 보인다.

    파이썬은 두 매개 변수에는 검사가 없음을, 그리고 변수는 간단한 방법을 속성 비슷한 클래스에 액세스 할 수 있습니까? 그것은이있다.

    장식 같이 동적 클래스 메소드의 함수에 동일한 기능을 장식하는 기능을 추가 할 수있다.

    파이썬의 내장 @property데코레이터에 대한 책임이 할 수있는 방법라는 특성 에 있습니다. 예를 들어, 다음 절차

    class Student(object):
    
        @property
        def score(self):
            return self._score
    
        @score.setter
        def score(self, value):
            if not isinstance(value, int):
                raise ValueError('score must be an integer!')
            if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
            self._score = value
    
    s = Student()
    s.score = 60
    print(s.score)

    @property역할은 속성 getter 메소드가 단지 추가하는 것입니다 @property이 시간에 그것을 @property다시 다른 장식 만든 @score.setterA에 대한 책임 세터 방법을 속성 할당되고, 그래서 우리는 제어 특성을 가지고 작동. 코드 봐 s.score = 60실제 변환은 s.set_score(60), s.score실제 변환을 s.get_score(). 그래서 사실, 본질 또는 getter 및 setter 메소드를 통해 달성합니다.

  • 열거 클래스

    어떤 경우에는, 클래스 오브젝트가 제한되어 고정 유성 타입만큼 현재 8 개 주제; 오브젝트 12 개월 클래스 및 고정 한정된 실시 예는 네 개의 객체를 가진다 같은 계절 클래스로서, 클래스가 호출됩니다 열거 클래스 .

    • 정의 열거 클래스

      열거 () 함수를 사용하여 작성 됨. 첫 번째 파라미터는 클래스 이름 열거 클래스이며, 두 번째 파라미터는 열거 값 터플 포맷이다.

      import enum
      
      Season = enum.Enum('Season', ('SPRING', 'SUMMER', 'FALL', 'WINTER'))
    • 액세스 열거 형 값

      각 부재는 이름, 값을 두 가지 특성을 갖는다.

      # 直接访问指定枚举
      print(Season.SPRING)
      # 访问枚举成员的变量名
      print(Season.SPRING.name)
      # 访问枚举成员的值
      print(Season.SPRING.value)
      
      # output:
      Season.SPRING
      SPRING
      1

      또한, 개선하기 위해 __members__사전인가 사전을 반환하는 속성을.

      for name, member in Season.__members__.items():    
          print(name, '=>', member, ',', member.value)
      
      # output:
      SPRING => Season.SPRING , 1
      SUMMER => Season.SUMMER , 2
      FALL => Season.FALL , 3
      WINTER => Season.WINTER , 4
  • 유형()

    언급 이전, 유형 () 함수는 변수의 유형을 볼 수는 있지만이 유형을 사용하려면 ()는 직접의 클래스의 유형을 볼? 다음 코드를 살펴 보자 :

    class Role:
        pass
    
    r = Role()
    # 查看变量r的类型
    print(type(r))        # <class '__main__.Role'>
    # 查看Role类本身的类型
    print(type(Role))     # <class 'type'>

    카드는 클래스 자체는 역할 유형을 입력하고, 위의 출력에서 ​​볼 수 있습니다. 하드 조금 발음이 문장은 어떻게 역할 클래스의 타입 입력 이해하기?

    클래스 역할의 클래스 정의를 사용하는 프로그램은 또한 특정 오브젝트 (객체 클래스 타입)를 정의하는 것으로 이해 및 객체 변수 역할에 할당된다 파이썬의 관점에서. 따라서, 모든 클래스의 클래스 정의를 사용하여 프로그램 클래스 유형의 인스턴스입니다.

    파이썬 실제로 전체 형태 () 함수 개체 유형을 만드는 (등가 클래스의 생성자 함수를 입력)이 허용되고, 클래스 타입의 인스턴스이기 때문에 클래스 타입 동적 클래스를 생성 파이썬 때문에 () 함수를 사용할 수있다. 예를 들어 다음과 같은 절차는 :

    def fn(self):    
      print('fn函数')
    
    # 使用type()定义Dog类
    Dog = type('Dog', (object,), dict(walk=fn, age=6))
    # 创建Dog对象
    d = Dog()
    # 分别查看d、Dog的类型
    print(type(d))
    print(type(Dog))
    d.walk()
    print(Dog.age)
    
    #output:
    <class '__main__.Dog'>
    <class 'type'>
    fn函数
    6

    매개 변수가 세 개의 클래스를 정의 지정 유형 ()를 사용합니다 :

    1, 매개 변수 : 클래스 이름이 생성되었습니다.

    2, 두 개의 매개 변수 : 클래스의 세트는 부모 클래스를 상속합니다. 파이썬은 다중 상속을 지원하기 때문에, 그래서 여기의 여러 부모 클래스를 지정 튜플. 심지어 실제로 단지 부모 불구하고,뿐만 아니라 쉼표 (이상이어야 함) 튜플 구문을 사용해야합니다.

    3 세 파라미터 : 바인딩 클래스 딕셔너리 객체 클래스 변수 및 방법에 관한 것이다. 사전의 값이 통상의 값이면 어떤는 클래스 변수를 나타내며, 사전 키 변수 또는 방법 이름처럼, 값이 사전의 함수 인 경우, 방법.

    따라서, 라인 5 개 코드는 객체 클래스를 상속받는 클래스, 클래스는 산책 () 메소드와 변수 연령 클래스를 정의 정의합니다.

  • 元类

    메타 클래스는 당신이 이해하지 않는 경우, 당신은 배울 수없는, 전체 프로세스를 읽고, 이해하기 어렵지 않다.

    실제로는 복잡한 클래스가 할 MetaClass (분류) 방법에 의해 필요 만들려면 동적으로, 비교적 간단한 클래스를 만드는 데 적용 할 때, 유형 () 함수 앞에 말하기.

    위안 클래스는 단순히 클래스가 클래스를 만드는 것입니다으로 이해 될 수있다.

    • 정의 메타 클래스

      상속 및 유형 클래스를 만들 필요하고 기본 명명 규칙은 끝을 메타 클래스 수있는 클래스 이름을 확인하는 것입니다. 또한, 엘리먼트 정의되고 구현 될 필요는 __new__()방법 (반환 값이 있어야한다). 클래스가 생성 위안화 클래스 때문에, __new__()방법은 새로운 클래스를 생성하는 데 사용, 호출됩니다.

      # 定义Item元类,继承type
      class ItemMetaClass(type):
          # cls代表动态修改的类
          # name代表动态修改的类名
          # bases代表被动态修改的类的所有父类
          # attr代表被动态修改的类的所有属性、方法组成的字典
          def __new__(cls, name, bases, attrs):
              # 动态为该类添加一个cal_price方法
              attrs['cal_price'] = lambda self: self.price * self.discount
              return type.__new__(cls, name, bases, attrs)

      상기 과정에서, 목표 클래스 동적 cal_price 수단을 추가하기 위해이 방법을 대체 할 때.

    • 클래스 메타 클래스 만들기

      # 定义Book类
      class Book(metaclass=ItemMetaClass):
          __slots__ = ('name', 'price', '_discount')
          def __init__(self, name, price):
              self.name = name
              self.price = price
          @property
          def discount(self):
              return self._discount
          @discount.setter
          def discount(self, discount):
              self._discount = discount
      
      # 定义cellPhone类
      class CellPhone(metaclass=ItemMetaClass):
          __slots__ = ('price', '_discount' )
          def __init__(self, price):
              self.price = price
          @property
          def discount(self):
              return self._discount
          @discount.setter
          def discount(self, discount):
              self._discount = discount

      위의 프로그램은 두 개의 클래스 핸드폰을 예약을 정의하고, 두 클래스의 정의에 정보 요소의 유형을 지정, 따라서이 두 클래스를 만드는 파이썬 인터프리터는 ItemMetaClass가의 경우 __new__이 방법을 수정하기위한 호출됩니다 두 클래스.

      그래서이 두 클래스는 여전히 cal_price () 메소드의 정의입니다. 다음 코드는 검출한다.

      b = Book("Python基础教程", 89)
      b.discount = 0.75
      # 创建Book对象的cal_price()方法
      print(b.cal_price())
      cp = CellPhone(2399)
      cp.discount = 0.85
      # 创建CellPhone对象的cal_price()方法
      print(cp.cal_price())
      
      # output:
      66.75
      2039.1499999999999

      이상의 결과의 운영의 관점에서, 동적으로 프로그램을 수정할 수있는 배치 형 메타 클래스를 사용하여, 그들은 일부 수정에 중점을두고 있습니다. 이 기능은 몇 가지 기본적인 프레임 워크를 개발할 때, 프로그램이 클래스의 클래스 메소드를 추가 사용하여 달러의 특정 번호에 대한 공통 기능을해야 할 수도 있습니다 매우 유용합니다.

추천

출처www.cnblogs.com/lowkeyao/p/11311822.html