0127_TIL

이종현·2022년 2월 2일
0

TIL

목록 보기
10/20
post-thumbnail

객체는 개념 , 인스턴스는 만들어진 객체

class Person():
    # 클래스 변수
    cnt = 0
    def __init__(self,name):
        self.name = name
        # 클래스 변수를 하나씩 증가 하고 싶을 땐?
        Person.cnt +=1 # 클래스 변수 접근 방법


jonghyun = Person('종현')
# 인스턴스 변수
jonghyun.cnt=3

클래스 변수와 인스턴스 변수의 차이?

클래스 변수는 공용, 인스턴스 변수는 독립적


self

  • self -> 인스턴스를 가리키는 것 (인스턴스 자신)
  • 모든 메소드는 self 키워드를 가져야 한다.

인스턴스 메소드

  • 인스턴스 변수를 사용하거나, 인스턴스 변수에 값을 설정한느 메소드
class Person():
    # 클래스 변수
    cnt = 0
    def __init__(self,name):
        self.name = name
        # 클래스 변수를 하나씩 증가 하고 싶을 땐?
        Person.cnt +=1 # 클래스 변수 접근 방법
    
    def run(self):
        print('뛰어!')
        #self로 아무것도 하지 않을 때에는 staticmethod로 설정
        #self.run = True


jonghyun = Person('종현')
# 인스턴스 변수
jonghyun.run()

>>>
뛰어!

클래스 메소드

  • 클래스가 사용할 메소드

  • @classmethod로 정의

    • @ = > 데코레이터 : 함수
    • 꾸며질 함수를 매개변수로 받고
    • 안에 함수를 매핑을 한다.
    from datetime import datetime as dt
    
    							#꾸며질 함수를 매개변수로 받고
    def time_display_decorator(origin_func):
        #안에 함수를 정의
        def decorated():
            print(dt.now())
            origin_func()
            print('------')
        #함수를 꼭 리턴 해줘야 한다
        #return을 안할 시에, NoneTypeError 나온다
        return decorated
    
    @time_display_decorator
    def test_a():
        print('test_a')
    @time_display_decorator
    def test_b():
        print('test_b')
    
    test_a() #time_display_decorator(test_a)()

*깊은내용

데코레이터는 1급 객체와 연관 되어 있다.

from datetime import datetime as dt


def time_display_decorator(origin_func):
    def decorated():
        print(dt.now())
        origin_func()
        print('------')
    return decorated
# 심화
# 클래스로 데코레이터를 정의 할수도 있음
class TimeDisplay():
    def __init__(self,origin_func):
        self.origin_func = origin_func
    def __call__(self):
        print(dt.now())
        self.origin_func()
        print('--------')


@time_display_decorator
def test_a():
    print('test_a')

@TimeDisplay
def test_b():
    print('test_b')

test_a()
test_b()
class Person():
    # 클래스 변수
    cnt = 0
    def __init__(self,name):
        self.name = name
        # 클래스 변수를 하나씩 증가 하고 싶을 땐?
        Person.cnt +=1 # 클래스 변수 접근 방법
    
    #인스턴스 메소드
    def run(self):
        print('뛰어!')
        self.run = True
    
    #클래스 메소드
    #첫번째 인자로 클래스를 넘겨줌
    @classmethod
    def plus(cls):
        cls.cnt +=1

#클래스 변수 사용시, 인스턴스를 만들지 않아도 된다.
print(Person.cnt)
Person.plus()
print(Person.cnt)
>>>>
0
1

static

  • 속성을 다르지 않고, 단지 기능(행동)만을 하는 메소드를 정의할 때, 사용
class Person():
    # 클래스 변수
    cnt = 0
    def __init__(self,name):
        self.name = name
        # 클래스 변수를 하나씩 증가 하고 싶을 땐?
        Person.cnt +=1 # 클래스 변수 접근 방법
    

    # 클래스 메소드
    # 첫번째 인자로 클래스를 넘겨줌
    @classmethod
    def plus(cls):
        cls.cnt +=1
    
    
    # static메소드
    # 클래스 , 인스턴스와 관계가 없다
    @staticmethod
    def run():
        print('뛰어!')
    


#클래스 변수 사용시, 인스턴스를 만들지 않아도 된다.
print(Person.cnt)
Person.plus()
print(Person.cnt)

Person.run()

>>>
0
1
뛰어!

객체지향의 핵심 4가지

추상화

  • 공통된 속성과 메소드를 뽑아내는것 => 상위 클래스를 만들 수 있음

상속

  • 두 클래스 사이 부모 - 자식 관계를 정립
  • 상속을 통한 메소드 재사용 가능.
  • super ()
    • 부모클래스에 있는 것을 사용하기 위해
  • 메소드 오버라이딩을 통해 자식 클래스에서 재정의 가능함
    • 자식 이기는 부모 없다.
  • 다중 상속
    • 중복된 속성이나 메소드가 있는 경우, 상속 순서에 의해 결정 됨

다형성

  • 동일한 메소드가 클래스에 따라 다르게 행동할 수 있음
    • 하나의 클래스가 여러 형태를 받을 수 있음
    • 하나의 타입에 여러 타입의 객체가 올 수 있음

캡슐화

  • 속성과 메소드를 묶는 작업

  • '은닉성' -> 접근에 대한 권한

    • 심화 : 응집도, 결합도
      • 모듈 내 응집도가 높고 모듈 간 결합도가 낮을수록 좋다!
  • 접근 제어자 종류

    • Public : 공개

      • 언더바 없이 시작하는 메소드 나 속성
      • 일반적으로 작성되는 메소드와 속성의 대다수
    • Protected : 상속 관계 클래스 안 에서만 접근 가능

      • 언더바 1개로 시작하는 메소드나 속성
      • 코드에 은닉성을 띄우고 싶을 때, Protected로 접근
      • 밖에서 접근이 필요할 땐, 메소드를 정의해서 사용
    • Private : 내 클래스 안에서 만 가능

      • 언더바 2개 로 시작하는 메소드나 속성
      class Person:
          def __init__(self,age):
              self.__age = age
          
          def get_age(self):
              return self.__age
      
      tony = Person(27)
      print(tony.__age)
      >> 에러
      print(tony.get_age())
      >> 27
      
      ###################################
      
      class Person:
          def __init__(self,age):
              self.__age = age
          
          def get_age(self):#public method
              return self.__age #private value
          
          def set_age(self): #public method
              self.__age += 1
      
      tony = Person(27)
      
      print(tony.get_age())
      
      tony.set_age()
      
      print(tony.get_age())
      >>
      27
      28
      • private value 에 접근을 하려면, public method를 통해 접근 해야 한다.

      • #name mangling을 통해 변화된 private에 접근하는법
        print(tony._Person__age)
        #이렇게 쓰면 안됨
    • getter , setter

      class Person:
          def __init__(self):
              self.__age = None
              self.__name = None
          
          #getter 메소드 : 뭔가를 주는거
          def get_age(self):
              return self.__age
          
          #setter 메소드 : 뭔가를 설정,할당 함
          def set_age(self,new_age):
              self.__age = new_age
      
          @property #getter
          def name(self): #getter
              return self.__name
          @name.setter #setter
          def name(self, new_name): #setter
              self.__name = new_name 
      
      jonghyun = Person()
      jonghyun.set_age(24)
      
      #이런 형식으로 안 써도 된다.
      #jonghyun.get_name('jonghyun')
      jonghyun.name = 'Jonghyun'
      print(jonghyun.name)
      >>> Jonghyun
      jonghyun.name = 'JonghyunLEE'
      #name을 변수의 이름처럼 쓸 수 있음
      print(jonghyun.name)
      >>> JonghyunLEE
 ---

 ```python
 #매직 메소드
 class Person:
     def __init__(self):
         self.__age = None
         self.__name = None
     
     #매직 메소드
     def __str__(self):
         return f'나이는 {self.name}살 이구요, 이름은 {self.name} 입니다!'
     
     #getter 메소드 : 뭔가를 주는거
     def get_age(self):
         return self.__age
     
     #setter 메소드 : 뭔가를 설정,할당 함
     def set_age(self,new_age):
         self.__age = new_age
 
     @property 
     def name(self): #getter
         return self.__name
     @name.setter
     def name(self, new_name): #setter
         self.__name = new_name 
 
 jonghyun = Person()
 jonghyun.set_age(24)
 
 jonghyun.name = 'Jonghyun'
 print(jonghyun.name)
 
 jonghyun.name = 'JonghyunLEE'
 print(jonghyun.name)
 
 ##__str__ 메소드로 인해 가능
 print(jonghyun)
 ```

 
profile
개발 일기

0개의 댓글