객체지향 프로그래밍 (Object Oriented Programming)

maro·2024년 3월 14일

데이터를 객체(object)로 취급하며, 이러한 객체가 바로 프로그래밍의 구현의 중심인 프로그래밍 개발 방식.

Class(클래스) 정의

객체지향 언어에서 데이터인 객체(instance) 를 어떻게 구성할지 정의한 설계도/템플릿을 클래스 라고 한다.

Class에는 다음 두가지를 정의한다.
1. Attribute/State

  • 객체의 속성, 상태 값을 저장할 변수
  • 보통 class로 정의하는 data는 여러개의 값들로 구성된다. 이 값들을 저장하는 변수를 attribute/state 라고 한다.
    - 고객: 고객ID, 패스워드, 이름, email, 주소, 전화번호, point ...
    - 제품: 제품번호, 이름, 제조사, 가격, 재고량
  • Instance 변수라고 한다.
  • 개별 객체는 각각의 instance변수를 가진다.
  1. behavior
  • 객체의 state 값을 처리하는 함수.
  • instance method 라고 한다.
  • 개별 객체(instance)들은 동일한 instance 메소드를 이용해 자신의 instance 변수의 값들을 처리한다.

객체지향 프로그래밍이란 Data와 Data를 처리하는 함수를 분리하지 않고 하나로 묶어 모듈로 개발하는 방식이다. 그래서 어떤 값들과 어떤 함수를 묶을 것인지를 class로 정의한다. 그리고 그 class로 부터 객체(instance) 를 생성(instantiate)해서 사용한다.

class는 Data type이고 instance는 value 이다.

  • 파이썬에서는 class에 정의된 instance변수와 method를 합쳐 Attribute 라고 표현한다.

class 정의

class 클래스이름: #선언부
#클래스 구현
#메소드들을 정의

클래스 이름의 관례

  • 파스칼 표기법 사용-각 단어의 첫글자는 대문자 나머진 소문자로 정의한다.
  • ex) Person, Student, HighSchoolStudent

Instance(객체)

class로 부터 생성된 값(value)로 클래스에서 정의한 attribute를 behavior를 이용해 처리한다.

클래스로부터 객체(Instance) 생성

변수 = 클래스이름()

Attribute(속성) - instance 변수

attribute는 객체의 데이터, 객체를 구성하는 값들, 객체의 상태값들을 말한다.
값을 저장하므로 변수로 정의한다. 그래서 instance 변수 라고 한다.

객체에 속성을 추가, 조회

객체의 속성 추가(값 변경)

    1. Initializer(생성자)를 통한 추가
      - 객체에 처음 attribute를 정의한다. 이것을 초기화 라고 한다.
    1. 객체.속성명(변수명) = 값 (추가/변경)
    1. 메소드를 통한 추가/변경
      - 2, 3번 방식은 initializer에서 초기화한 attribute를 변경한다.
  • 속성 값 조회
    - 객체.속성명

  • 객체._dict
    - 객체가 가지고 있는 Attribute들을 dictionary로 반환한다.

#Person 클래스 생성
class Person :
    pass
#Person 클래스의 객체(instance)를 생성
p = Person()
#Person 객체 p에 속성(Person-사람과 관련된 변수들)을 추가 - 이름, 나이, 주소
p.name = "이순신"
p.age = 20
p.address = "서울"
#p의 속성들을 조회
print("이름", p.name)
print("나이", p.age)
print("주소", p.address)

이름 이순신
나이 20
주소 서울

생성자(Initializer)¶

객체를 생성할 때 호출되는 특수메소드로 attribute들 초기화에 하는 코드를 구현한다.

  • Initializer를 이용해 초기화하는 Attribute들이 그 클래스에서 생성된 객체들이 가지는 Attribute가 된다.
  • 객체 생성후 새로운 attributee들을 추가 할 수 있지만 하지 않는 것이 좋다.

구문

def init(self [,매개변수들 선언]): #[ ] 옵션.

# 구현 -> attribute(instance변수) 초기화
self.속성명 = 값

변수 초기화: 처음 변수 만들어서 처음 값 대입하는 것.

#Person -> name, age, address 속성을 가지는 클래스.
class Person :
    def __init__(self, name, age, address) :
        #instance 변수에 따라 파라미터로 받은 값들을 할당해서 초기화.
        #instance 변수 : self.변수명
        self.name = name
        self.age = age
        self.address = address
        print("객체생성완료")
p1 = Person("이순신", 20, "서울")
#객체 생성
#1. 메모리에 instance 변수들을 저장할 영역이 생성.
#2. class에 정의된 __init__()메소드를 호출. 
#1에서 생성된 instance를 __init()의 첫번째 파라미터(self)에 전달.
#객체 생성시 전달한 argument들을 __init__()의 두번째 파라미터부터 전달.

객체생성완료

print(p1.name, p1.age, p1.address)

이순신 20 서울

p2 = Person("유관순", 30, "부산")
print(p2.name, p2.age, p2.address)

객체생성완료
유관순 30 부산

p2.age = 32
p2.address = "광주"
print(p2.name, p2.age, p2.address)

유관순 32 광주

Instance 메소드(method)

객체가 제공하는 기능
객체의 attribute 값을 처리하는 기능을 구현한다.

구문

def 이름(self [, 매개변수들 선언]):

# 구현
# attribute 사용(조회/대입)
self.attribute

self 매개변수 - 메소드를 소유한 객체를 받는 변수 - 호출할 때 전달하는 argument를 받는 매개변수는 두번째 부터 선언한다.

메소드 호출

  • 객체.메소드이름([argument, ...])

instance 메소드의 self parameter

메소드는 반드시 한개 이상의 parameter를 선언해야 하고 그 첫번째 parameter는 관례적으로 변수명을 self로 한다.
메소드 호출시 그 메소드를 소유한 instance가 self parameter에 할당된다.

  • 메소드 안에서 self는 instance를 가리키며 그 instance에 정의된 attribute나 method를 호출 할 때 사용한다.

Initializer의 self

  • 현재 만들어 지고 있는 객체를 받는다.

메소드의 self

  • 메소드를 소유한 객체를 받는다.

Caller에서 생성자/메소드에 전달된 argument들을 받을 parameter는 두번째 변수부터 선언한다.

class Person :
    def __init__(self, name, age, address) :
        #instance 변수에 따라 파라미터로 받은 값들을 할당해서 초기화.
        #instance 변수 : self.변수명
        self.name = name
        self.age = age
        self.address = address
    #메소드
    def get_info(self) :
        #메소드에서 instance 변수/메소드 호출 -> self.변수명, self.메소드명()
        info = f"이름:{self.name}, 나이:{self.age}, 주소:{self.address}"
        return info
    def add_age(self, age) :
        #instance 변수 age를 파라미터로 받은 age를 더한 값으로 변경.
        self.age = self.age + age
    def print_info(self) :
        #person의 정보들을 출력
        txt = self.get_info() #메소드에서 메소드 호출 : self.호출할메소드
        print(txt)
p = Person("이순신", 20, "서울")
s = p.get_info()
print(s)
p.add_age(15)
p.print_info() #p가 print_info의 self에 연결하고 이게 get_info의 self에 연결

이름:이순신, 나이:20, 주소:서울
이름:이순신, 나이:35, 주소:서울

p2 = Person("유관순", 30, "대전")
s2 = p2.get_info()
print(s2)

이름:유관순, 나이:30, 주소:대전

접근제어를 통한 정보 은닉 (Information Hiding)

Attribute의 값을 caller(객체 외부)가 마음대로 바꾸지 못하게 하기 위해 직접 호출을 막고 setter/getter 메소드를 통해 값을 변경/조회 하도록 한다.

  • Attribute의 값을 업무 규칙/조건에 맞는 값만 대입할 수 있도록 하는 것이 목적.
    - Attribute의 값을 변경하는 메소드에 변경 가능 조건을 넣어 업무 규칙에 맞는 값들만 대입될 수 있도록 한다.
  • setter
    - Attribute의 값을 변경하는 메소드. 관례상 set 으로 시작
  • getter
    - Attribute의 값을 조회하는 메소드. 관례상 get 으로 시작

Attribute 직접 호출 막기

  • Attribute의 이름을 (double underscore)로 시작한다. (로 끝나면 안된다.)
  • 같은 클래스안에서는 선언한 이름으로 사용이 가능 하지만 외부에서는 그 이름으로 호출할 수 없게 된다.
p.name = "박순신"
p.print_info()

이름:이순신, 나이:22, 주소:서울

p.age = -40
p.print_info()

이름:이순신, 나이:22, 주소:서울

class Person :
    def __init__(self, name, age, address) :
        #name : 두글자 이상
        #age : 양수
        #address : 특별한 규칙이 없다.
        self.__name = name
        self.__age = age
        self.address = address
        #__name, __age : 클래스 밖에서는 호출 못하게 처리.
        #address는 클래스 밖에서도 호출 가능.
     #메소드
    def get_info(self) :
        #메소드에서 instance 변수/메소드 호출 -> self.변수명, self.메소드명()
        #__변수명 으로 접근을 제한한 변수는 같은 클래스에서는 호출 가능.
        info = f"이름:{self.__name}, 나이:{self.__age}, 주소:{self.address}"
        return info
    def add_age(self, age) :
        #instance 변수 age를 파라미터로 받은 age를 더한 값으로 변경.
        self.__age = self.__age + age
    def print_info(self) :
        #person의 정보들을 출력
        txt = self.get_info() #메소드에서 메소드 호출 : self.호출할메소드
        print(txt)
    #__변수 를 반환하는 메소드 - get_이름() : getter
    def get_name(self) :
        return self.__name
    #__변수 의 값을 변경하는 메소드 - set_이름() : setter
    def set_name(self, name) :
        if len(name) >= 2 : #두글자 이상일 때만
            self.__name = name
    def get_age(self) :
        return self.__age
    def set_age(self, age) :
        if age >= 0 : #양수
            self.__age = age
p = Person("이순신", 22, "서울")
p.print_info()

코드를 입력하세요

이름:이순신, 나이:22, 주소:서울

p.set_age(40)
p.print_info()

이름:이순신, 나이:40, 주소:서울

p.set_age(-10) #안바뀜
p.print_info()

이름:박순신, 나이:40, 주소:서울

p.set_name("박순신")
p.print_info()

이름:박순신, 나이:40, 주소:서울

p.set_name("강") #안바뀜
p.print_info()

이름:박순신, 나이:40, 주소:서울

print(p.get_name(), p.get_age())

박순신 40

p.address = "경기도"
print(p.address)
p.print_info()

경기도
이름:박순신, 나이:40, 주소:경기도

데코레이터(decorator)를 이용해 property 지정.

은닉된 instance 변수의 값을 사용할 때 getter/setter대신 변수를 사용하는 방식으로 호출할 수 있도록 한다.
setter/getter 메소드이름을 변수처럼 선언 (보통은 같은 이름으로 지정)
getter메소드 : @property 데코레이터를 선언
setter메소드 : @getter메소드이름.setter 데코레이터를 선언.

  • 반드시 getter 메소드를 먼저 정의한다.
  • setter메소드 이름은 getter와 동일해야 한다.

getter/setter의 이름을 Attribute 변수처럼 사용한다.
주의: getter/setter 메소드를 직접 호출 할 수 없다. 변수형식으로만 호출가능하다.

#name, age -> 메소드
#__name, __age, address -> attribute
#객체.name = 값 (대입) ==> name(값) 호출 (setter - @name.setter)
#print(객체.name) (조회) ==> name() 호출 (getter - @property)
#객체 : 외부 - p.name class 내부 : self
class Person :
    def __init__(self, name, age, address) :
        #name : 두글자 이상
        #age : 양수
        #address : 특별한 규칙이 없다.
        self.name = name #setter name 메소드 호출 @name.setter  self.name(name)
        self.age = age #setter age 메소드 호출 @address.setter
        self.address = address
        #__name, __age : 클래스 밖에서는 호출 못하게 처리.
        #address는 클래스 밖에서도 호출 가능
      #setter/getter 데코레이터를 이용해 구현
    #get_name() 
    @property #getter/setter는 일반 메소드 전에 작성해야됨.
    def name(self) :
        print("get_name")
        return self.__name
    @name.setter
    def name(self, name) :
        print("set_name")
        if len(name) >= 2 :
            self.__name = name
    @property
    def age(self) :
        return self.__age
    @age.setter
    def age(self, age) :
        if age >= 0 :
            self.__age = age
     #메소드
    def get_info(self) :
        #메소드에서 instance 변수/메소드 호출 -> self.변수명, self.메소드명()
        #__변수명 으로 접근을 제한한 변수는 같은 클래스에서는 호출 가능.
        info = f"이름:{self.name}, 나이:{self.age}, 주소:{self.address}"
        return info
    def add_age(self, age) :
        #instance 변수 age를 파라미터로 받은 age를 더한 값으로 변경.
        self.age = self.age + age
    def print_info(self) :
        #person의 정보들을 출력
        txt = self.get_info() #메소드에서 메소드 호출 : self.호출할메소드
        print(txt)
p = Person("이순신", 22, "서울")
p.print_info()

set_name
get_name
이름:이순신, 나이:22, 주소:서울

p.name = "장순신"

set_name

print(p.name)

get_name
장순신

p = Person("이순신", 22, "서울")
p.print_info()

set_name
get_name
이름:이순신, 나이:22, 주소:서울

p.name = "박순신"
p.print_info()
p.name = "강"
p.print_info()

set_name
get_name
이름:박순신, 나이:22, 주소:서울
set_name
get_name
이름:박순신, 나이:22, 주소:서울

상속 (Inheritance)

기존 클래스를 확장하여 새로운 클래스를 구현한다.

  • 생성된 객체(instance)가 기존 클래스에 정의된 Attribute나 method를 사용할 수있고 그 외의 추가적인 attribute와 method들을 가질 수 있는 클래스를 구현하는 방법.
  • 같은 category의 클래스들을 하나로 묶어주는 역할을 한다.

기반(Base) 클래스, 상위(Super) 클래스, 부모(Parent) 클래스
물려 주는 클래스.

  • 상속하는 클래스에 비해 더 추상적인 클래스가 된다.
  • 상속하는 클래스의 데이터 타입이 된다.

파생(Derived) 클래스, 하위(Sub) 클래스, 자식(Child) 클래스

  • 상속하는 클래스.
  • 상속을 해준 클래스 보다 좀더 구체적인 클래스가 된다.

상위 클래스와 하위 클래스는 계층관계를 이룬다.

  • 상위 클래스는 하위 클래스 객체의 타입이 된다.

다중상속

  • 하나의 클래스가 여러 클래스를 상속받아 정의 하는 것을 다중상속이라고 하며 파이썬은 다중상속이 가능하다.

MRO (Method Resolution Order)

  • 다중상속시 메소드 호출할 때 그 메소드를 찾는 순서.
  1. 자기 자신
  2. 상위클래스(하위에서 상위로 올라간다)
    - 다중상속의 경우 먼저 선언한 클래스 부터 찾는다. (왼쪽->오른쪽)
    MRO 순서 조회
  • Class이름.mro()

object class

  • 모든 클래스의 최상위 클래스
  • 상속 하지 않은 클래스는 object 를 상속받는다.
  • special method, special attribute 를 정의 하고 있다.

class Parent1:
...

class Parent2:
...

class Sub(Parent1, Parent1):
...

class Person :
   # def __init__(self, name, age) :
        #self.name = name
        #self.age = age
    #def print_info(self) :
        #print(f"이름:{self.name}, 나이:{self.age}")
    def go(self) :
        print("갑니다.")
    def eat(self) :
        print("점심을 먹는다")
#Student, Teacher => Person class를 상속
class Student(Person) :
    def study(self) :
        print("공부를 합니다.")
class Teacher(Person) :
    def teach(self) :
        print("가르칩니다.")
s = Student()
s.study()
s.go()
s.eat()

공부를 합니다.
갑니다.
점심을 먹는다

t = Teacher()
t.teach()
t.go()
t.eat()

가르칩니다.
갑니다.
점심을 먹는다

Method Overriding (메소드 재정의)

상위 클래스에 정의한 메소드의 구현부를 하위 클래스에서 다시 구현하는 것. 상위 클래스는 모든 하위 클래스들에 적용할 수 있는 추상적인 구현 밖에는 못한다.
하위 클래스에서 그 기능을 자신에 맞게 좀 더 구체적으로 재구현할 수 있게 해주는 것을 Method Overriding이라고 한다.

  • 방법: 메소드 선언은 동일하게 하고 구현부는 새롭게 구현한다.

super() 내장함수

하위 클래스에서 상위 클래스의 instance를 사용할 수있도록 해주는 함수. 상위클래스에 정의된 instance 변수, 메소드를 호출할 때 사용한다.

구문

  • super().메소드명()

상위 클래스의 Instance 메소드를 호출할 때 – super().메소드()

  • 특히 method overriding을 한 하위 클래스에서 상위 클래스의 원본 메소드를 호출 할 경우 반드시 super().메소드() 형식으로 호출해야 한다.
    메소드에서
  • self.xxxx : 같은 클래스에 정의된 메소드나 attribute(instance 변수) 호출
  • super().xxxx : 부모클래스에 정의된 메소드나 attribute(부모객체의 attribute) 호출
class Person :
    def go(self) :
        print("갑니다.")
    def eat(self) :
        print("먹습니다")
class Student(Person) :
    def study(self) :
        print("공부를 합니다.")
    def eat(self) :
        print("학교 식당에서 급식을 먹습니다.")
class Teacher(Person) :
    def teach(self) :
        print("가르칩니다.")
    def eat(self) :
        print("외부 식당에 갑니다.")
        #print("먹는다.")
        super().eat() # => 부모클래스(객체)의 eat()
s = Student()
s.eat()

학교 식당에서 급식을 먹습니다.

t = Teacher()
t.eat()

외부 식당에 갑니다.
먹습니다

class Person :
    #Person -> Teacher/Student 의 공통 attribute, method를 정의하는 클래스
    def __init__(self, name, age) :
        self.name = name
        self.age = age
    def get_info(self) :
        return f"이름:{self.name}, 나이:{self.age}"
    def print_info(self) :
        print(self.get_info())
#하위 클래스의 메소드 : self => 하위클래스의 속성, 메소드 호출
#                     super() => 부모클래스의 속성, 메소드 호출
class Student(Person) :
    #Student attribute : name, age (Person) + grade
    def __init__(self, name, age, grade) :
        super().__init__(name, age) #부모의 init()을 호출
        self.grade = grade
    def get_info(self) :
        return f"{super().get_info()}, 성적:{self.grade}"
s = Student("김학생", 10, 20)
s.name, s.age, s.grade

('김학생', 10, 20)

s.get_info()

'이름:김학생, 나이:10, 성적:20'

객체 관련 유용한 내장 함수, 특수 변수

isinstance(객체, 클래스이름-datatype) : bool

  • 객체가 두번째 매개변수로 지정한 클래스의 타입이면 True, 아니면 False 반환
  • 여러개의 타입여부를 확인할 경우 class이름(type)들을 튜플(tuple)로 묶어 준다.
  • 상위 클래스는 하위 클래스객체의 타입이 되므로 객체와 그 객체의 상위 클래스 비교시 True가 나온다.

객체.dict

  • 객체가 가지고 있는 Attribute 변수들과 대입된 값을 dictionary에 넣어 반환
p = Person("홍길동", 10)
s = Student("이순신", 15, 20)
isinstance(p,Person)

True

isinstance(p, Student)

False

isinstance(s, Student)

True

#부모클래스는 모든 자식클래스 객체들의 타입이 된다.
isinstance(s, Person)

True

a = 10
if isinstance(a, (int, float)) : # a가 int 또는 float 타입인지?
    print(a + 20)

30

특수 메소드(Special method)

특수 메소드란

파이썬 실행환경(Python runtime)이 객체와 관련해서 특정 상황 발생하면 호출 하도록 정의한 메소드들. 그 특정상황에서 처리해야 할 일이 있으면 구현을 재정의 한다.

  • 객체에 특정 기능들을 추가할 때 사용한다.
  • 정의한 메소드와 그것을 호출하는 함수가 다르다.
    - ex) init() => 객체 생성할 때 호출 된다.
    메소드 명이 더블 언더스코어로 시작하고 끝난다.
  • ex) __init__(), __str__()
    매직 메소드(Magic Method), 던더(DUNDER) 메소드라고도 한다.
    특수메소드 종류
  • https://docs.python.org/ko/3/reference/datamodel.html#special-method-names

주요 특수메소드

__init__(self [, …])

  • Initializer
  • 객체 생성시 호출 된다.
  • 객체 생성시 Attribute의 값들을 초기화하는 것을 구현한다.
  • self 변수로 받은 instance에 Attribute를 설정한다.

__call__(self [, …])
객체를 함수처럼 호출 하면 실행되는 메소드

  • Argument를 받을 Parameter 변수는 self 변수 다음에 필요한대로 선언한다.
  • 처리결과를 반환하도록 구현할 경우 return value 구문을 넣는다. (필수는 아니다.)
class Test :
    def __call__(self, a) :
        print("call", a)
        return "리턴값"
t = Test()
t(1000) # t() ==> t.__call__()

call 1000
'리턴값'

__str__(self)

  • Instance(객체)의 Attribute들을 묶어서 문자열로 반환한다.
  • 내장 함수 str(객체) 호출할 때 이 메소드가 호출 된다.
    - str() 호출할 때 객체에 __str__()의 정의 안되 있으면 __repr__() 을 호출한다. __repr__()도 없으면 상위클래스에 정의된 __str__()을 호출한다.
    - print() 함수는 값을 문자열로 변환해서 출력한다. 이때 그 값을 str() 에 넣어 문자열로 변환한다.
#str(값) ==> string
class Person :
    #Person -> Teacher/Student 의 공통 attribute, method를 정의하는 클래스
    def __init__(self, name, age) :
        self.name = name
        self.age = age
    def __str__(self) :
        return f"이름: {self.name}, 나이: {self.age}"
p = Person("홍길동", 30)
str(p) # str() => p.__str__()

'이름: 홍길동, 나이: 30'

print(p)

이름: 홍길동, 나이: 30

연산자 재정의(Operator overriding) 관련 특수 메소드

연산자의 피연산자로 객체를 사용하면 호출되는 메소드들
다항연산자일 경우 가장 왼쪽의 객체에 정의된 메소드가 호출된다.

  • a + b 일경우 a의 add() 가 호출된다.

비교 연산자

  • __eq__(self, other) : self == other
    == 로 객체의 내용을 비교할 때 정의 한다.
  • __lt__(self, other) : self < other,
  • __gt__(self, other): self > other
    min()이나 max()에서 인수로 사용할 경우 정의해야 한다.
  • __le__(self, other): self <= other
  • __ge__(self, other): self >= other
  • __ne__(self, other): self != other

산술 연산자

  • __add__(self, other): self + other
  • __sub__(self, other): self - other
  • __mul__(self, other): self * other
  • __truediv__(self, other): self / other
  • __floordiv__(self, other): self // other
  • __mod__(self, other): self % other
#str(값) ==> string
class Person :
    #Person -> Teacher/Student 의 공통 attribute, method를 정의하는 클래스
    def __init__(self, name, age) :
        self.name = name
        self.age = age
    def __str__(self) :
        return f"이름: {self.name}, 나이: {self.age}"
    def __add__(self, other) :
        # a + b => a.__add__(b) ==> self : a, other : b
        # other : int - self.age + other, other : Person : self.age + other.age
        if isinstance(other, int) :
            return self. age + other
        elif isinstance(other, Person) :
            return self.age + other.age
        else :
            raise Exception(f"{type(other)}는 계산할 수 없는 타입입니다.") # 에러발생.
    def __eq__(self, other) :
        # self와 other의 attribute 값이 같은지 여부를 확인
        # p1 == p2, p1:self, p2:other
        if not isinstance(other, Person) :
            return False
        if self.name == other.name and self.age == other.age :
            return True
        return False
p = Person("이순신", 20)
p + 10

30

p2 = Person("유관순", 50)
p + p2

70

p + "aaa"

Exception Traceback (most recent call last)
Cell In[164], line 1
----> 1 p + "aaa"
Cell In[161], line 17, in Person.add(self, other)
15 return self.age + other.age
16 else :
---> 17 raise Exception(f"{type(other)}는 계산할 수 없는 타입입니다.")
Exception: <class 'str'>는 계산할 수 없는 타입입니다.

p1 = Person("이순신", 20)
p2 = Person("이순신", 20)
p3 = Person("유관순", 10)
print(p1 == p2)
print(p1 == p3)
p1 == "aaa"

True
False
False

class변수, class 메소드

class변수

  • (Intance가 아닌) 클래스 자체의 데이터
  • Attribute가 객체별로 생성된다면, class변수는 클래스당 하나가 생성된다.
    구현
    - class 블럭에 변수 선언.

class 메소드

  • 클래스 변수를 처리하는 메소드
  • 구현
    - @classmethod 데코레이터를 붙인다.
    - 첫번째 매개변수로 클래스를 받는 변수를 선언한다. 이 변수를 이용해 클래스 변수나 다른 클래스 메소드를 호출 한다.

static 메소드

클래스의 메소드로 클래스 변수와 상관없는 단순기능을 정의한다.

  • Caller 에서 받은 argument만 가지고 일하는 메소드를 구현한다.

구현

  • @staticmethod 데코레이터를 붙인다.
  • Parameter에 대한 규칙은 없이 필요한 변수들만 선언한다.

class 메소드/변수, static 메소드 호출

  • 클래스이름.변수
  • 클래스이름.메소드()
class Person:
    # 변수 정의 -> class 변수 (class 소유)
    GENDER_MALE = '남성'
    GENDER_FEMALE = '여성'
    # class 변수를 다루는 메소드 -> class method
    @classmethod
    def print_gender_constants(clzz) : # clzz : 클래스 자체를 받는 변수
        print(clzz.GENDER_MALE, clzz.GENDER_FEMALE)
    @staticmethod
    def static_method() :
        print("static method")
    def __init__(self, name, age, gender) :
        self.name = name
        self.age = age
        self.gender = gender
    def __str__(self) :
        return f"{self.name}, {self.age}, {self.gender}"
p = Person("이순신", 20, Person.GENDER_MALE)
p2 = Person("강감찬", 30, Person.GENDER_MALE)
p3 = Person("유관순", 22, Person.GENDER_FEMALE)
print(p)
print(p2)
print(p3)

이순신, 20, 남성
강감찬, 30, 남성
유관순, 22, 여성

Person.print_gender_constants()

남성 여성

Person.static_method()

static method

profile
공부 & 프로젝트 & 개발 블로그

0개의 댓글