파이썬/파이썬 이론

8. Python_Class

잘잔디 2023. 4. 13. 17:49

객체지향 프로그래밍

  • 객체지향 프로그래밍은 복잡한 문제를 잘게 나누어 객체로 만들고, 객체를 조합해서 문제를 해결한다.
  • 현실 세계의 복잡한 문제를 처리하는데 유용하며 기능을 개선하고 발전시킬 때도 해당 클래스만 수정하면 되므로
  • 큰 프로젝트의 유지복수에도 매우 효율적입니다.
  • 객체가 가진 데이터를 클래스의 속성(Attribute)이라 부르고 객체가 갖는 기능을 메서드(Method)라고 부릅니다.

클래스

  • 클래스 명은 주로 PascalCase를 사용한다.
  • 클래스는 사용자 정의 객체를 만들기 위한 주형이라고 생각하면 된다.
  • 클래스 정의는 보통 클래스의 인스턴스를 대상으로 연산하는 메서드 정의를 포함하고 있습니다.
  • 클래스도 doc_string을 적어줄 수 있다.
  • int,list,dict 등도 클래스입니다.

객체와 인스턴스

  • 객체와 인스턴스는 같은 말이라고 할 수 있는데, 객체는 단지 객체 라고 표현하지만
  • 인스턴스는 특정 클래스의인스턴스다라고 표기한다는 차이점이 있다.

메서드 Method

  • 클래스 바디 안에서 정의되는 함수이다.
  • 해당 클래스의 객체들이 각각 가질 수 있는 함수이다.
  • 메서드는 첫 번째 인자로 인스턴스 객체(self)를 받는다.
  • 첫 번째 인자를 설정 안 하면 에러가 발생한다.
  • 클래스 속성을 만들때 __init__메서드 안에 self.속성에 값을 할당하면 된다.
    • init함수에 self를 인자로 넣지 않으면 오류가 발생한다.
    • __=double under score = dunder (파이썬의 여러 기능들을 사용할 때 던더 메서드를 구현하여 사용한다. )

class ClassName():
    def method_name(self):
        pass # method_body
    pass # class_body
instance_variable = ClassName()
print(type(instance_variable))

class Student():
    def __init__(self):
        self.hello = "안녕하세요"
    def greeting(self):
        print(self.hello)
stu = Student()
stu.greeting()
  • self는 인스턴스 자기 자신을 의미한다.
  • self.hello 처럼 객체마다 자기 자신에 속성을 추가하여 사용할 수 있다.
  • __init__의 매개변수 self에 들어가는 값은 Student() 의 인스턴스라고 할 수 있다.
  • self 가 완성된 후에는 변수인 james에 할당되었다.
  • 이후 메서드를 호출하면 현재 인스턴스가 자동으로 매개변수 self에 들어옵니다. 그래서

chang = Student() # 독립적인 값을 보장하는 instance로 생성됩니다.
print(chang.hello)
chang.greeting()

bebe = Student()
print(bebe.hello)

self란

  • 인스턴스 자기자신을 가리킨다.

클래스 속성

  • 인스턴스를 생성할때 만들어지는 값
  • 속성 값 할당을 위해서 init(self) 메서드안에 slef 다음에 값을 받을 매개변수를 지정해주어야 한다.
  • 그 후 매개변수를 self.속성에 할당한다.

비공개 속성

  • 인스턴스 속성값을 변경하지 못하도록 만들기 위해서는 비공개 속성 사용가능
  • self.__attr2 = param2 # 비공개 속성은 클래스 영역 밖에서는 호출(출력)이 불가능하다.
  • method 또한 앞에 __ 를 붙여주면 클래스 영역 밖에서 호출이 불가능한 비공개 메서드로 사용가능하다.
  • 비공개 속성은 class 내부에서는 접근이 되기 때문에 method를 통해 간접적으로 사용가능하다.(자바의 private와 같다.)
  • 비공개 속성을 수정할 때도 method를 통해 클래스 내부에서 간접 접근한다면 수정도 가능하다.
class Person:
    org = 'korea'  # 얘는 class속성이다. 얘를 접근하여 바꾸면 해당 class로 만든 모든 instance의 org값이 바뀐다
    def __init__(self,name,age,address,wallet):
        self.hello = "안녕하세요"
        self.name = name
        self.age = age
        self.address = address
        self.__wallet = wallet
    def greeting(self):
        print(f"{self.hello} 제 이름은 {self.name}입니다.")
    def get_wallet(self):
        print(self.__wallet)
    def set_wallet(self,n):
        self.__wallet = n
    def pay(self,amount):
        if self.__wallet <amount:
            print("돈이 모자랍니다.")
            return
        self.__wallet -=amount
        print(f"이제 {self.__wallet}원 남았네요")
    @classmethod # self를 사용하지 않고, class 자체로 method만드는 방법
    def from_string(cls,string):
        name,age,address,__wallet = string.split(",")
        return cls(name,age,address,__wallet)
  #  @staticmethod #self도 cls(class)도 안쓰는 경우(인스턴스나 class 영향없이 자체로 method가 될때)

p1 = Person("james",20,"서울시 마포구",2000)
p2 = Person("tomas",10,"수원시 권선동",30000)
p1.greeting()
p1.get_wallet() 
p1.pay(20000)
p1.get_wallet() 
p1.set_wallet(20000)
p1.pay(20000)

 

#__dict__를 통해 해당 인스턴스의 속성들을 볼 수 있다.
print(p1.__dict__)
print(p2.__dict__)

class Person():
    def __init__(self):
        self.name = input("이름은 무엇인가요? :")
        self.age = int(input("나이는 무엇인가요? :"))
        self.address = input("주소는 무엇인가요? :")

    def Person_info(self,n):
        print(f"{n}번째 이름:{self.name}\\n{n}번째 나이:{self.age}\\n{n}번째 주소:{self.address}")

p1 = Person()
p2 = Person()
p1.Person_info("첫")
p2.Person_info("두")

class Character():
    def __init__(self):
        HP,MP,AP = input("체력,마나,AP를 입력하세요").split()
        self.HP = float(HP)
        self.MP = float(MP)
        self.AP = int(AP)
    def tibbers(self):
        print(f'티버: 피해량 {self.AP*0.65+400}')

C1 = Character()
C1.tibbers()

class Team:
    '''팀 객체를 만듭니다.'''
    count = 0
    order = []
    def __init__(self,number):
        self.number = number
        self.name = None
        self.__member = set()
        Team.count +=1

    def __len__(self): # 내장 함수(Built-in function) len(Team())-->파이썬 __len__(self)를 찾아서 실행
        return len(self.__member)

    def add_member(self,name):
        if name in self.__member:
            print(f"{name}님은 이미 팀에 있습니다.")
        else:
            self.__member.add(name)
            print(f"{name}님을 {self.number}팀에 추가했습니다.")

    def rm_member(self,name):
        if name in self.__member:
            self.__member.remove(name)
            print(f"{name}님을 {self.number}팀에서 삭제했습니다.")
        else:
            print(f"{name}님은 해당 팀에 없습니다.")

    def get_count(self):
        print(f"count: {Team.count}")

    def get_order(self):
        print(f"order: {Team.order}")

    def set_order(self,num):
        if num in Team.order:
            Team.order.remove(num)
        Team.order.append(num)

    def print_teams(self):
        for i in self.__member:
            print(i,end=' ')
        print()

t1 = Team(1)
t1.add_member('윤규헌')
t1.add_member('윤규헌')
print(len(t1))
t1.add_member('이호진')
print(len(t1))
t1.add_member("이기수")
t1.rm_member('이기수')
t1.rm_member('이기수')

t2 = Team(2)
t2.set_order(t2.number)
t1.set_order(t1.number)
t1.get_order()
t1.get_count()
t3 = Team(3)
t3.get_count()
t3.set_order(t3.number)
t3.get_order()

import numpy as np
class TeamBuilder:
    has_team = False
    teams = []

    def __init__(self,members,team_count):
        self.members = members
        self.team_count = team_count
        self.create_team()

    def create_team(self):
        nums = np.arange(len(self.members))
        np.random.shuffle(nums)
        count =0
        if TeamBuilder.has_team:
            TeamBuilder.teams = []

        for i in range(self.team_count):
            TeamBuilder.teams.append(Team(i))

        for i in nums:
            if count == self.team_count:
                count = 0

            TeamBuilder.teams[count].add_member(self.members[i])
            count+=1
        has_team = True

    def show_team_info(self):
        for i in range(self.team_count):
            print('Team :',i+1,' ',end='')
            TeamBuilder.teams[i].print_teams()

members =list("강지인 김강직 김경목 김기훈 김민수 김예린 김유림 김호영 도강현 맹지호 민병창 서영호 신제우 우상욱 윤규헌 이민호 이병호 이선주 이호진 허경모 황도희".split())
builder1 = TeamBuilder(members,5)
builder1.show_team_info()