Class (2) - self

Grace Goh·2022년 9월 24일
0

Python

목록 보기
23/24

self : instance의 속성attribute

__init__ method가 없을 경우 : py가 내부적으로 알아서 실행을 한다.
필요한 (인자) name, age 등이 없고 기본형으로 사용할 때는 만들지 않아도 된다.

class SelfTest:

    def func1():
        print('Func1 called')
        
    def func2(self):
        print('Func2 called')

# 인스턴스화
myf = SelfTest()

print(id(myf))
print(dir(myf)) # myf 내 사용할 수 있는 method 확인

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'func1', 'func2'] < 우리가 지정한 함수도 볼 수 있다.


self ← 인스턴스 변수

class SelfTest:
  
    def func1():
        print('Func1 called')
  
    def func2(self):
        print(id(self)) # 인자 self의 id값과
        print('Func2 called')

myf = SelfTest()
  
print(id(myf)) # 클래스를 인스턴스화한 myf의 id값이 같다. 즉 self = 인스턴스(해피)
  
myf.func2() 

1751872346000
1751872346000
Func2 called


method 호출하기

class SelfTest: 

    def func1(): # self가 없다면 클래스 method
        print('Func1 called')
  
    def func2(self): # myf가 self로 들어간다.
        print(id(self))
        print('Func2 called')

# 인스턴스화
myf = SelfTest()

(인자 self가 없는) class method 호출하기

myf.func1()
# TypeError: func1() takes 0 positional arguments but 1 was given
  
SelfTest.func1() # 클래스 method는 클래스로 바로 접근해서 호출한다.
# Func1 called

(인자 self가 있는) myf로 인스턴스화된 method 호출하기

myf.func2() # 인스턴스로 호출하거나
# Func2 called

SelfTest.func2(myf) # () 안에 인스턴스를 넘겨 줘야
# Func2 called

SelfTest.func2()
# TypeError: func2() missing 1 required positional argument: 'self'

self가 있으면 각 방instance이 있다는 뜻이다.
이 때 class라는 공통 이름만으로 각 방의 속성에 접근하는 것은 불가하다.


클래스 변수, 인스턴스 변수

현실에 존재하는 것 객체화 > 코드를 통해 인스턴스화

# 예제3
class Warehouse:
	# 클래스 변수
    stock_num = 0 # 변수 선언(재고)
	
    # 생성자
    def __init__(self, name): # self: 인스턴스 변수. 내 것. 나만의 방.
        self.name = name
        Warehouse.stock_num += 1 # 객체(인스턴스)가 1개 만들어지면 1 증가한다.

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


# 인스턴스 만들기
user1 = Warehouse('Happy')
user2 = Warehouse('Rafael')

print(Warehouse.stock_num)
# 2

Warehouse.stock_num = 50 # 직접 접근 수정

print(user1.name)
print(user2.name)
# Happy

print(user1.__dict__)
print(user2.__dict__)
# {'name': 'Happy'}

print('>>>', user1.stock_num)
# >>> 50

Warehouse.stock_num = 50과 같이 직접 접근 수정도 가능하지만 바람직하지 않으며 막아야 한다.

ex 게임, 아이템 drop율을 누군가 0.0094 -> 1로 바꿔 놓는다면 100% drop하게 된다. 1000원에 3번 하게 되어 있는 것을 누가 1000번으로 바꿔 놓으면 게임 코드, 밸런스가 무너진다.

del

# 인스턴스 네임스페이스에서는 인스턴스 변수 name만 나오고 class 변수 stock_num은 나오지 않는다.
print(user1.__dict__)
print(user2.__dict__)
# {'name': 'Happy'}

print('before', Warehouse.__dict__)

# __del__(self) 호출
del user1 

print('after', Warehouse.__dict__)

before {'__module__': '__main__', 'stock_num': 2, '__init__': <function Warehouse.__init__ at 0x000002254EF0BD30>, '__del__': <function Warehouse.__del__ at 0x000002254EF0BDC0>, '__dict__': <attribute '__dict__' of 'Warehouse' objects>, '__weakref__': <attribute '__weakref__' of 'Warehouse' objects>, '__doc__': None}

after {'__module__': '__main__', 'stock_num': 1, '__init__': <function Warehouse.__init__ at 0x000002254EF0BD30>, '__del__': <function Warehouse.__del__ at 0x000002254EF0BDC0>, '__dict__': <attribute '__dict__' of 'Warehouse' objects>, '__weakref__': <attribute '__weakref__' of 'Warehouse' objects>, '__doc__': None}


profile
Español, Inglés, Coreano y Python

0개의 댓글