[python] 클래스

728x90

1. 클래스 정의

파이썬 클래스(Class)는 객체 지향 프로그래밍(Object-Oriented Programming, OOP)의 기본적인 개념으로, 데이터와 해당 데이터를 처리하는 메서드들을 하나로 묶어서 표현하는 코드 구조입니다. 클래스는 객체를 생성하기 위한 틀 또는 설계도와 같은 역할을 합니다. 클래스를 정의한 후에는 이를 기반으로 여러 개의 객체를 생성하여 사용할 수 있습니다.

파이썬 클래스를 정의하는 방법은 다음과 같습니다

 

class 클래스명: # object를 상속받기 때문에 class 클래스명(object):로 해도되고 object를 생략해도 된다.
    # 클래스 속성 (멤버 변수)
    변수1 = 값1
    변수2 = 값2

    # 메서드 정의
    def 메서드1(self, 인자1, 인자2):
        # 메서드 코드

    def 메서드2(self, 인자1, 인자2):
        # 메서드 코드

 

위의 코드에서 클래스명은 정의할 클래스의 이름을 나타내고, 변수1, 변수2는 클래스의 속성(멤버 변수)을 나타내며, 메서드1, 메서드2는 클래스의 메서드를 나타냅니다.

클래스의 속성은 해당 클래스의 모든 객체가 공유하는 변수이고, 메서드는 클래스에 속하는 함수로, 클래스의 속성을 처리하거나 다른 동작을 수행할 수 있습니다. 메서드의 첫 번째 인자로 self를 사용하는데, 이는 해당 메서드가 호출되는 객체 자신을 나타냅니다.

 

2. 인스턴스 생성

클래스를 기반으로 객체를 생성하려면 다음과 같이 클래스를 호출하면 됩니다:

# 클래스로부터 객체 생성
객체명 = 클래스명()

이렇게 생성된 객체는 클래스의 속성과 메서드에 접근할 수 있습니다

# 객체의 속성에 접근
값 = 객체명.변수1

# 객체의 메서드 호출
객체명.메서드1(인자1, 인자2)

 

 

예제1)

class Dog:

    species = 'firstDog' # 클래스 변수: 직접 접근 가능, 공유

    def __init__(self,name,age):
        self.name = name
        self.age = age

# 클래스 정보
print(Dog) # 출력: <class '__main__.Dog'>

# 인스턴스화
a = Dog("puddle",2)
b = Dog("wel",3)
c = Dog("puddle",2)

print(id(a),id(b),id(c)) # 출력해보면 모두 다른값이 나온다 => 즉 보이는 값은 동일하더라도 코드입장에서는 다른것으로 확인한다 => 즉 인스턴스화 시킨 객체는 전부 다른 객체이다.

# 네임스페이스: 객체를 인스턴스화 할 때 저장된 공간
print('dog1',a.__dict__) # 출력: dog1 {'name': 'puddle', 'age': 2}

print('dog2',b.__dict__) # 출력: dog2 {'name': 'wel', 'age': 3}

# 인스턴스 속성 확인
print(f"{a.name} is {a.age} and {b.name} is {b.age}") # 출력:puddle is 2 and wel is 3

if a.species == 'firstDog':
    print(f"{a.name} is a {a.species}") # 출력 : puddle is a firstDog

# 직접 접근 가능한지 확인
print(Dog.species) # 출력: firstDog
print(a.species) # 출력: firstDog
print(b.species) # 출력: firstDog

 

참고로 클래스 변수와 동일한 이름으로 인스턴스 변수를 만드는 것도 가능합니다.

만약 똑같은 이름의 변수가 있을 경우 변수를 호출하게 되면 먼저 인스턴스변수에서 찾고 인스턴스 변수에 없다면 클래스 변수에서 찾습니다.

 

예제를 통해서 확인해보겠습니다.

 

예제1) 인스턴스 변수가 있을 경우

class Dog:

    species = 'firstDog' # 클래스 변수: 직접 접근 가능, 공유

    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.species = "instanceDog"

# 클래스 정보
print(Dog) # 출력: <class '__main__.Dog'>

# 인스턴스화
a = Dog("puddle",2)
b = Dog("wel",3)
c = Dog("puddle",2)

print(a.species) #출력 instanceDog

 

예제2) 인스턴스 변수가 없을 경우

class Dog:

    species = 'firstDog' # 클래스 변수: 직접 접근 가능, 공유

    def __init__(self,name,age):
        self.name = name
        self.age = age
        # self.species = "instanceDog"

# 클래스 정보
print(Dog) # 출력: <class '__main__.Dog'>

# 인스턴스화
a = Dog("puddle",2)
b = Dog("wel",3)
c = Dog("puddle",2)

print(a.species) #출력 firstDog

3. self의 의미

파이썬 클래스에서 self는 자기자신의 인스턴스를 의미합니다.

예제1)

class SelfTest:
    def fuc1():
        print('fuc1 called')
    def fuc2(self):
        print(id(self))
        print('fuc2 called')

f = SelfTest()
a ="1"
print(dir(f))

print(id(f)) # print(id(self))와 동일한 값이 출력됨

# f.fuc1() # 에러발생 : TypeError: fuc1() takes 0 positional arguments but 1 was given
SelfTest.fuc1() # fuc1 called -> self가 없으면 클래스로 바로 접근해야 호출가능하다.


f.fuc2() # 출력: id값 fuc2 called -> 인스턴스화 시킨 변수가 self로 넘어간다. 여기서는 f가 self로 넘어간다고 볼 수 있다.
# SelfTest.fuc2() # 에러발생 : TypeError: fuc2() missing 1 required positional argument: 'self'
SelfTest.fuc2(f) # 출력: id값 fuc2 called

class WareHouse:
    # 클래스 변수
    stock_num =0 # 재고

    def __init__(self,name):
        # 인스턴스 변수
        self.name = name
        WareHouse.stock_num += 1

    def __del__(self): #객체가 소멸할 때 자동으로 호출되는 함수
        WareHouse.stock_num -= 1

user1 = WareHouse('Lee')
user2 = WareHouse('Kim')

print(WareHouse.stock_num) # 출력 : 2

print('before',WareHouse.__dict__) # 'stock_num' : 2

del user1

print('after',WareHouse.__dict__) # 'stock_num' : 1

 

예제2)

class Person:

    def __init__(self, name, age, favorite):
        self.name = name
        self.age = age
        self.favorite = favorite

    def info(self):
        print(f"current ID : {id(self)}")
        print(f"{self.name}이 좋아하는 가수는 {self.favorite.get('singer')}이다.")

p1 = Person("mike",30,{'health':'crossfit','singer':'tws'})
p2 = Person("jane",25,{'health':'tennis','singer':'le sserafim'})

print(id(p1)) #출력: 1537590860864
p1.info()
#출력: current ID : 1537590860864
# mike이 좋아하는 가수는 tws이다.

Person.info(p1)
#출력: current ID : 1537590860864
# mike이 좋아하는 가수는 tws이다.

print(id(p2)) #출력:1537590859760
p2.info()
# 출력: jane이 좋아하는 가수는 le sserafim이다.
# current ID : 1537590859760

Person.info(p2)
# 출력: current ID : 1537590859760
# jane이 좋아하는 가수는 le sserafim이다.

 

p1, p2의 인스턴스의 id값과 self의 id값이 동일한 것을 확인할 수 있습니다. 

또한 클래스로 메서드를 호출했을 때 메서드 내부에 인스턴스를 넣으니 똑같은 값이 출력되는 것을 확인할 수 있습니다.

4. 멤버변수

파이썬에서 멤버 변수(Member Variable)는 클래스 내에서 정의된 변수로, 해당 클래스의 모든 메서드에서 접근할 수 있는 변수를 말합니다. 멤버 변수는 클래스의 상태를 나타내는 데이터를 저장하는 데 사용되며, 객체의 속성과 값들을 저장하여 객체의 특성을 표현합니다.

파이썬에서 멤버 변수를 정의하려면 클래스의 메서드들과 동일한 위치에 변수를 선언하면 됩니다. 이러한 멤버 변수는 self를 사용하여 클래스 내에서 접근할 수 있습니다. self는 해당 클래스의 객체 자신을 나타내며, 객체를 생성할 때 자동으로 전달되므로 self를 통해 멤버 변수에 접근하고 값을 설정할 수 있습니다.

아래는 파이썬에서 멤버 변수를 정의하고 사용하는 예시입니다

 

class Person:
    def __init__(self, name, age):
        # 멤버 변수 정의 및 초기화
        self.name = name
        self.age = age

    def say_hello(self):
        # 멤버 변수 사용
        print(f"안녕하세요, 저는 {self.name}이고, {self.age}살입니다.")

# Person 클래스의 객체 생성
person = Person("철수", 30)

# say_hello 메서드 호출
person.say_hello()  # 출력: 안녕하세요, 저는 철수이고, 30살입니다.


print("이름 : {0}, 나이 : {1}".format(person.name,person.age)) #출력: 이름: 철수, 나이:30

person2 = Person("영희",20)

person2.gender = "여성" #변수를 추가로 할당 person2에만 변수가 추가됨

if person2.gender=="여성":
    print("{0}는 여성입니다.".format(person2.name)) #영희는 여성입니다.

위 예시에서 Person 클래스에는 name과 age라는 멤버 변수가 정의되어 있습니다. 이 변수들은 __init__ 메서드를 통해 객체 생성 시 인자로 전달된 값을 저장하고, say_hello 메서드에서 self.name과 self.age를 사용하여 값을 출력하고 있습니다.

멤버 변수는 객체마다 다른 값을 가지며, 해당 클래스의 모든 메서드에서 사용할 수 있어 객체의 상태를 표현하고 다루는 데 유용합니다. 객체를 생성할 때마다 멤버 변수의 값이 다르게 설정되므로 각각의 객체는 독립적인 상태를 가질 수 있습니다.

5. 클래스 기반 메서드

일반적으로 클래스 내부의 요소를 직접 변경하는 것은 좋은 방법이 아닙니다.

그래서 인스턴스화 된 요소들은 인스턴스 메서드를 만들어 호출합니다.

반면에 클래스 변수는 인스턴스 메서드로 변경할 수 없기 때문에 클래스 메서드를 만들어 변경합니다.

 

사용방법은 아래와 같습니다.

class 클래스명
	    
    def 인스턴스 메서드(self):
    	...
        
   	@classmethod
    def 클래스 메서드(cls):
    	...
        
  	@staticmethod
    def static메서드():
    	...

 

static 메서드는 다른 메서드와 다르게 유연하다는 특징이 있습니다. 따라서 매개변수에 필수로 넣어야되는 값이 없습니다.

 

 

예제를 통해 보여드리겠습니다.

 

class Person:

    hobby = "crossfit"

    def __init__(self,name,age):
        self._name = name
        self._age = age

    def __str__(self):

        return f"{self._name}의 나이는 {self._age}살 이고 취미는 {self.hobby} 이다."

    @classmethod
    def change_hobby(cls,new_hobby): # cls는 클래스를 의미
        print(id(cls))
        cls.hobby = new_hobby

    @staticmethod
    def is_name(inst): # static 메서드에는 필수로 넣어야하는 매개변수가 없다.
        if inst._name == 'mike':
            return f"본인입니다."
        else:
            return f"타인입니다."

p = Person('mike',30)
print(p) # 출력: mike의 나이는 30살 이고 취미는 crossfit 이다.

Person.change_hobby("dance") # 클래스 메서드 호출 -> 1981412366976, 클래스 변수 hobby를 변경

print(id(Person)) # 출력: 1981412366976

print(p) # 출력: mike의 나이는 30살 이고 취미는 dance 이다.

# static 메서드는 인스턴스와 클래스로 모두 호출이 가능하다.
print(p.is_name(p)) #출력:본인입니다
print(Person.is_name(p)) #출력:본인입니다

 

 

'PYTHON Programming > Python' 카테고리의 다른 글

[python] 메서드  (0) 2024.05.20
[python] 매직 메서드  (0) 2024.05.11
[python] 입출력  (0) 2024.04.23
[python] 함수  (0) 2024.04.23
[python] 컴프리헨션  (0) 2024.04.23