Python3 객체지향


Python은 처음부터 객체지향 언어였기 때문에 Python에서는 클래스와 객체를 쉽게 만들 수 있습니다. 이번 장에서는 Python의 객체지향 프로그래밍을 자세히 소개하겠습니다.

이전에 객체지향 프로그래밍 언어를 접해본 적이 없다면 먼저 객체지향 언어의 몇 가지 기본 기능을 이해하고 기본적인 객체지향 개념을 머릿속에 형성해야 할 수도 있습니다. Python으로 객체지향 프로그래밍을 더 쉽게 배워보세요.

다음으로 객체지향의 몇 가지 기본 특성을 간략하게 살펴보겠습니다.


객체 지향 기술 소개

  • Class(클래스): 동일한 속성과 메서드를 가진 객체의 집합을 설명하는 데 사용됩니다. 컬렉션의 모든 개체에 공통적인 속성과 메서드를 정의합니다. 객체는 클래스의 인스턴스입니다.

  • 클래스 변수: 클래스 변수는 인스턴스화된 개체 전체에서 공통됩니다. 클래스 변수는 클래스 내부와 함수 본문 외부에 정의됩니다. 클래스 변수는 일반적으로 인스턴스 변수로 사용되지 않습니다.

  • 데이터 멤버: 클래스 변수 또는 인스턴스 변수는 클래스 및 해당 인스턴스 객체와 관련된 데이터를 처리하는 데 사용됩니다.

  • 메서드 재작성: 상위 클래스에서 상속된 메소드가 하위 클래스의 요구 사항을 충족할 수 없는 경우 이를 재작성할 수 있습니다. 이 프로세스를 메소드 재작성이라고도 합니다.

  • 인스턴스 변수: 메서드에 정의된 변수는 현재 인스턴스의 클래스에만 적용됩니다.

  • 상속: 즉, 파생 클래스는 기본 클래스의 필드와 메서드를 상속합니다. 상속을 사용하면 파생 클래스의 개체를 기본 클래스 개체로 처리할 수도 있습니다. 예를 들어, 다음과 같은 디자인이 있습니다. Dog 유형의 개체는 "is-a" 관계를 시뮬레이션하는 Animal 클래스에서 파생됩니다(예: Dog is an Animal).

  • 인스턴스화: 클래스의 특정 개체인 클래스의 인스턴스를 만듭니다.

  • 메서드: 클래스에 정의된 함수입니다.

  • Object: 클래스를 통해 정의된 데이터 구조의 인스턴스입니다. 개체에는 두 개의 데이터 멤버(클래스 변수 및 인스턴스 변수)와 메서드가 포함됩니다.

다른 프로그래밍 언어와 비교하여 Python은 가능한 한 새로운 구문과 의미를 추가하지 않고 클래스 메커니즘을 추가합니다.

Python의 클래스는 객체 지향 프로그래밍의 모든 기본 기능을 제공합니다. 클래스의 상속 메커니즘은 여러 기본 클래스를 허용하고 파생 클래스는 기본 클래스의 모든 메서드를 재정의할 수 있으며 기본 클래스에서 동일한 이름을 가진 메서드를 호출할 수 있습니다. .

개체에는 데이터의 양과 유형에 관계없이 포함될 수 있습니다.

클래스 정의

구문 형식은 다음과 같습니다.

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

클래스가 인스턴스화되면 해당 속성을 사용할 수 있습니다. 실제로 클래스가 생성된 후 클래스 이름을 통해 해당 속성에 액세스할 수 있습니다.

클래스 객체

클래스 객체는 속성 참조와 인스턴스화라는 두 가지 작업을 지원합니다.

속성 참조는 Python의 모든 속성 참조와 동일한 표준 구문(obj.name)을 사용합니다.

클래스 객체가 생성된 후에는 클래스 네임스페이스의 모든 이름이 유효한 속성 이름이 됩니다. 따라서 클래스 정의가 다음과 같다면:

#!/usr/bin/python3

class MyClass:
    """一个简单的类实例"""
    i = 12345
    def f(self):
        return 'hello world'

# 实例化类
x = MyClass()

# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())

클래스 인스턴스화:

# 实例化类
x = MyClass()
# 访问类的属性和方法

위는 새 클래스 인스턴스를 생성하고 개체를 로컬 변수 x에 할당합니다. x는 빈 개체입니다.

위 프로그램 실행의 출력 결과는 다음과 같습니다.

MyClass 类的属性 i 为: 12345
MyClass 类的方法 f 输出为: hello world

많은 클래스가 초기 상태의 객체를 생성하는 경향이 있습니다. 따라서 클래스는 다음과 같이 __init__()라는 특수 메서드(생성자)를 정의할 수 있습니다.

def __init__(self):
    self.data = []

클래스가 __init__() 메서드를 정의하는 경우 클래스의 인스턴스화 작업은 자동으로 __init__() 메서드를 호출합니다. 따라서 다음 예에서는 다음과 같이 새 인스턴스를 생성할 수 있습니다.

x = MyClass()

물론 __init__() 메서드는 매개변수를 가질 수 있으며 매개변수는 __init__()를 통해 클래스의 인스턴스화 작업에 전달됩니다. 예:

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

클래스 메소드

클래스 내부에서 def 키워드를 사용하여 클래스에 대한 메소드를 정의할 수 있습니다. 일반 함수 정의와 달리 클래스 메소드에는 self 매개변수가 포함되어야 하며 이것이 첫 번째입니다. 매개변수:

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

# 实例化类
p = people('php',10,30)
p.speak()

Execute 위 프로그램의 출력 결과는 다음과 같습니다.

php 说: 我 10 岁。

Inheritance

Python은 클래스 상속도 지원합니다. 언어가 상속을 지원하지 않으면 클래스는 의미가 없습니다. 파생 클래스의 정의는 다음과 같습니다.

class DerivedClassName(BaseClassName1):
    <statement-1>
    .
    .
    .
    <statement-N>

기본 클래스에 동일한 메소드 이름이 있지만 하위 클래스 사용 시 지정되지 않은 경우 괄호 안의 기본 클래스 순서에 주의해야 합니다. , Python은 왼쪽에서 오른쪽으로 검색합니다. 즉, 하위 클래스에 해당 메소드가 없으면 왼쪽에서 오른쪽으로 검색하여 해당 메소드가 기본 클래스에 포함되어 있는지 확인합니다.


BaseClassName(예제의 기본 클래스 이름)은 파생 클래스와 동일한 범위에 정의되어야 합니다. 클래스 외에도 표현식도 사용할 수 있는데, 이는 기본 클래스가 다른 모듈에 정의된 경우 매우 유용합니다:

class DerivedClassName(modname.BaseClassName):

Instance

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))



s = student('ken',10,60,3)
s.speak()

위 프로그램 실행 결과는 다음과 같습니다:

ken 说: 我 10 岁了,我在读 3 年级

다중 상속

Python 또한 다중 상속 형식에 대한 지원이 제한되어 있습니다. 다중 상속의 클래스 정의는 다음 예와 같습니다.

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

부모 클래스에 동일한 메소드 이름이 있지만 사용 시 지정되지 않은 경우 괄호 안의 부모 클래스 순서에 주의해야 합니다. 하위 클래스에서 Python은 왼쪽에서 오른쪽으로 검색합니다. 즉, 하위 클래스에 해당 메서드가 없으면 왼쪽에서 오른쪽으로 검색하여 상위 클래스에 해당 메서드가 포함되어 있는지 확인합니다.

#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))

#另一个类,多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))

#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)

test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同,默认调用的是在括号中排前地父类的方法

위 프로그램 실행의 출력 결과는 다음과 같습니다.

我叫 Tim,我是一个演说家,我演讲的主题是 Python

메소드 재작성

상위 클래스 메소드의 기능이 요구 사항을 충족할 수 없는 경우 하위 클래스에서 상위 클래스의 메소드를 재작성할 수 있습니다.

#!/usr/bin/python3

class Parent:        # 定义父类
   def myMethod(self):
      print ('调用父类方法')

class Child(Parent): # 定义子类
   def myMethod(self):
      print ('调用子类方法')

c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法

위 프로그램을 실행한 출력 결과는 다음과 같습니다.

调用子类方法

클래스 속성 및 메서드

클래스의 개인 속성

__private_attrs: 두 개의 밑줄로 시작하여 속성이 비공개임을 선언합니다. 클래스 외부에서 사용하거나 직접 액세스할 수 없습니다. 클래스 self.__private_attrs 내부의 메서드에서 사용되는 경우.

클래스 메소드

클래스 내에서 def 키워드를 사용하여 클래스에 대한 메소드를 정의할 수 있습니다. 일반 함수 정의와 달리 클래스 메소드에는 self 매개변수가 포함되어야 하며 이것이 첫 번째 매개변수

Private입니다. method of the class

__private_method: 두 개의 밑줄로 시작하는 메소드는 private 메소드로 선언되며 클래스 외부에서 호출할 수 없습니다. 클래스 내에서 slef.__private_methods를 호출하세요.

예제는 다음과 같습니다.

#!/usr/bin/python3

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0    # 公开变量

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print (self.__secretCount)

counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount)  # 报错,实例不能访问私有变量

위 프로그램을 실행한 결과는 다음과 같습니다.

1
2
2
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    print (counter.__secretCount)  # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'

클래스의 고유 메서드:

  • __init__ :객체 생성 시 호출되는 생성자

  • __del__ : 객체를 해제할 때 사용되는 파괴 함수

  • __repr__ : 인쇄, 변환

  • __setitem__ : 인덱스에 따라 값 지정

  • __getitem__: 인덱스에 따라 값 가져오기

  • __len__: 길이 가져오기

  • __cmp__: 비교 연산

  • __call__: 함수 호출

  • __add__: 덧셈 연산

  • __sub__: 뺄셈 연산

  • __mul__: 곱셈 연산

  • __div__: 나눗셈 연산

  • __mod__: 나머지 작업

  • __pow__: 연산자 오버로딩

Python은 클래스의 전용 메서드도 오버로드할 수 있습니다.

#!/usr/bin/python3

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

위 코드의 실행 결과는 다음과 같습니다.

Vector(7,8)