Post

오토에버 클라우드 2기 3일차

오토에버 클라우드 2기 3일차

객체 지향 프로그래밍의 특징은 캡슐화, 상속, 다형성, 동적 바인딩 이 있다

  • 캡슐화 → 관련 있는 또는 동일한 목적을 달성하기 위한 함수와 데이터를 묶는 것

  • 상속 → 하위 클래스가 상위 클래스의 모든 속성을 물려 받는 것 (하지만 원래는 하위 클래스들이 모여서 공통점이 존재하면 상위 클래스가 생성된다)

  • 다형성 → 동일한 메세지에 대하여 다르게 반응하는 것

  • 동적 바인딩 → 실행 중간에 변경할 수 있음

 

객체 지향 프로그래밍 용어

  • 객체 → 프로그래밍에서 사용되는 모든 것
  • 클래스 → 동일한 목적을 달성하기 위한 데이터와 기능의 묶음
  • 인스턴스 → 클래스 기반으로 만들어진 객체, 사례
  • 메소드 → 클래스 안에 존재하는 기능(메소드와 함수의 차이 메소드는 클래스 내부에 존재)
  • 속성 → 클래스 내부에 존재하는 데이터

 

파이썬 클래스 외부에서 메서드 호출

1
2
3
4
5
6
name = 'minn' #str클래스를 이용해서 호출
# 아래 두개는 같은 결과 
print(name.upper())# 인스턴스를 이용해서 호출, self에 데이터를 대입하지 않아도 됨
#bound 호출
print(str.upper(name))# 클래스를 이용해서 호출, self자리에 인스턴스를 대입
#unbound 호출

 

클래스의 속성

클래스 내부에 메서드 바깥에 변수를 만들면 클래스 속성이 된다

  • 클래스 안에 만들어지고 클래스로 접근해서 읽기와 쓰기 가능
  • 인스턴스를 이용해서는 읽기만 가능하고 쓰기를 하게되면 인스턴스 안에 인스턴스 속성으로 다시 만들어짐
  • 인스턴스와 클래스에 동일한 속성인 존재하는 경우 인스턴스는 자신의 속성을 호출

 

인스턴스의 속성

  • 인스턴스 메서드 안에서 self변수를 만들면 인스턴스만 접근 가능
  • 메서드 안에서 self 없이 만들면 지역 변수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class st:
    nameSchool = '용호초'
    def insa(self):
        print('hello')
    def printName(self, name):
        self.num = 1 #인스턴스 속성 생성
        print(f"my name is {name}")

stud = st()
stud.printName('dd')
# 클래스 속성 접근
print(f"{st.nameSchool} 클래스 접근 {stud.nameSchool} 인스턴스 접근")
st.nameSchool = 'glgl' #클래스 수정
print(f"{st.nameSchool} 클래스 접근 {stud.nameSchool} 인스턴스 접근")
stud.nameSchool = 'instan' #인스턴스 수정
print(f"{st.nameSchool} 클래스 접근 {stud.nameSchool} 인스턴스 접근")
# 인스턴스 속성
print(f"{stud.num} 인스턴스 접근") # {st.num} 클래스 접근하면 에러 발생
1
2
3
4
5
dd
용호초 클래스 접근 용호초 인스턴스 접근
glgl 클래스 접근 glgl 인스턴스 접근
glgl 클래스 접근 instan 인스턴스 접근
1

인스턴스를 수정하면 인스턴스 속성이 따로 생성되고 그걸 이용한다

위 코드에서 인스턴스 속성을 메서드 안에서 num을 생성 했는데 꼭 stud.printName('dd')를 먼저 호출해야 사용할 수 있다 이전에 호출하지 않으면 num 속성 사용불가능 그리고 클래스로 호출해도 역시 안된다 st클래스 내부에 num속성이 없다고 나옴

AttributeError: type object 'st' has no attribute 'num'

 

Getter, Setter

getter 속성의 값을 읽기 위한 메서드

  • 매개변수는 없고 속성을 리턴
  • 타입이 bool인경우 get대신 is를 사용한다

 

setter 속성의 값을 변경하기 위한 메서드

  • 매개변수는 속성과 동일한 데이터 타입으로 하나 추가하고 속성의 값을 수정하는 코드를 작성한다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class st:
    name = '김민정'
    #인스턴스를 생성할때 호출 생성자
    def __init__(self,name='이름없음'):
        self.name = name
    def getName(self):
        return self.name
    def setName(self, name):
        self.name = name
    # 소멸자 소멸할때 실행할 내용 매개변수 self만 가능능
    def __del__(self):
        print('인스턴스가 소멸할 때 호출')
        #프로그램이 종료될 때 자동으로 호출

print(st.name)
stud = st()# 여기서 인스턴스 소멸
stud = st(name='new name1')#인스턴스 새로 생성
print(stud.getName())
stud.setName('new name2')
print(stud.getName())
1
2
3
4
5
김민정
인스턴스가 소멸할 때 호출
new name1
new name2
인스턴스가 소멸할 때 호출

 

클래스만 호출이 가능한 메서드

staticmethod는 데코레이터를 이용해서 생성하고 self 매개변수가 필요없다

self 가 없으므로 인스턴스 속성을 사용할 수 없다 클래스 속성 초기화에 주로 사용한다

1
2
3
4
5
6
class Student:
    @staticmethod
    def smethod():
        print("staticmethod")

Student.smethod() #staticmethod 출력

 

classmethod는 데코레이터를 이용해서 생성한다 매개변수가 필요하면 매개변수로 cls사용

1
2
3
4
5
6
class Student:
    @classmethod
    def cmethod(cls):
        print(cls)

Student.cmethod() #<class '__main__.Student'>를 출력

그래서 위 staticmethod, classmethod를 왜 사용하는가??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person:
    population = 0

    def __init__(self, name):
        self.name = name
        Person.population += 1

    @staticmethod
    def is_adult(age):
        return age >= 18

    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")
    
# 정적 메서드 사용: 객체 생성 없이 가능
print(Person.is_adult(20))   # True

# 클래스 메서드 사용: 클래스 자체로 인스턴스 생성
anon = Person.create_anonymous()
print(anon.name)             # Anonymous

정적 메서드는 클래스 내부에 속해있지만 인스턴스나 클래스에 무관하게 작동한다 관련 기능이지만 클래스 내부에 넣고 싶다면 정적 메서드를 사용한다고 한다

클래스 메서드는 인스턴스를 만들지 않고도 클래스 자체를 조작하거나 새로운 인스턴스를 만들 때 사용한다고 GPT가 말해주는데 이해가 되지 않아서 좀 더 조사해봐야겠다

 

클래스 속성 제한__slots__

파이선에서 클래스를 이용하여 인스턴스 생성하고 인스턴스에 a.num = 0을 통해서 속성을 생성할 수 있다 이렇게 된다면 같은 클래스지만 가지고 있는 속성이 다르게 된다 그래서 __slots__을 사용해서 클래스를 생성하면 속성 생성 제한을 만들 수 있다

1
2
3
4
5
6
7
classs Student:
    __slots__ = ["num","name"]
    def __init__(self):
        	pass

st = Student()
st.num = 0 # 이건 가능하지만 위에 없는거면 불가능

 

property

변수를 사용하는 것 처럼 메서드를 호출하는 문법

변수명 = property(fget=None,fset=None,fdel=None,doc=None)

fget 에 getter를 지정하고 fset에 setter를 지정하며 fdek은 삭제, doc는 help할 때 호출된다

 

파이썬에서 private

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# private 속성을 만듦
class Student:
    def __init__(self,name='noname',age = 0, aa = 1):
        self.name = name
        self.age = age
        self.__aa = aa # 프라이빗속성을 가짐
        
    def getAa(self):
        print(self.__aa)

student1 = Student()
print(student1.name)
print(student1.age)
print(student1.__aa) #여기서 오류 발생 AttributeError: 'Student' object has no attribute '__aa'
student1.getAa() #이렇게 해야 정상적으로 출력

__aa는 프라이빗이라서 클래스 내부에서만 사용 가능하다

private를 이용해서 property사용 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Student:
    def __init__(self,name='noname',age = 0, aa = 1):
        self.name = name
        self.age = age
        self.__aa = aa

    def getAa(self):
        print('getter')
        print(self.__aa)

    def setAa(self,a):
        print('setter')
        self.__aa = a

    aa = property(fget=getAa,fset=setAa)

student1 = Student()
#print(student1.name)
#print(student1.age)
#print(student1.__aa)
#student1.getAa()
student1.aa = 100
student1.aa # 여기서 100 출력

 

클래스의 다중상속

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Base1():
    def method(self):
        print("Base1")
        
class Base2():
    def method(self):
        print("Base2")
        
class Base3(Base1,Base2):
    def method(self):
        super().method()
        super(Base1,self).method()
        
instance = Base3()
instance.method()

오버라이딩을 한경우 상속된 클래스의 원래 메서드를 이용할려면 super를 사용해서 호출한다 다중상속에서는 super(내가 호출할 이전 클래스,self)이렇게 사용하면 Base2의 메소드를 호출할 수 있다

 

추상 클래스

인스턴스를 만들 수 없는 클래스로 상속을 통해서 사용하는 클래스이다 추상 메서드인 경우에는 상속을 받은 뒤 하위 클래스에서 반드시 구현한 뒤에 사용해야 한다

탬플릿 메서드 패턴을 구현하기 하기 위해 사용 (비슷한 형태로 만듦)

 

패키지 파일

모듈을 모아놓은 디렉토리로 모듈을 하나의 디렉토리에 모으고 __init__.py를 만들어서 사용한다

 

sort

정렬할때 사용하는 메서드

1
2
3
4
5
datas = ['hello', 'My','asdfasd']
print(datas) # ['hello', 'My', 'asdfasd']
#key에 설정된 함수를 사지고 데이터를 변환해서 정렬
datas.sort(key=str.upper,reverse=False)
print(datas) # ['asdfasd', 'hello', 'My']

 

list 대안

deque → 삽입과 삭제를 양방향에서 모두 가능하다 fifo, lifo를 구현할 때 사용하면 효과적이다

queue → queue 모듈에서는 동기화된 queue, LifoQueue(stack), PriorityQueue를 제공한다

 

This post is licensed under CC BY 4.0 by the author.