본문 바로가기
IT 개인학습/Python

매직메소드

by kiimy 2021. 7. 18.
728x90
728x90

매직 메소드

클래스 안에 정의된 함수

( 리스트, 튜플, 딕셔너리, 정수, 실수, 문자열 등과 같은 타입 역시 클래스를 통해 만들어진 기본 데이터 타입 )

ex 직접 만든 타입도 인덱싱 기능을 제공하려 할때 매직메소드 사용

class Notebook:
    def __init__(self, name, price): # 객체의 초기화를 위해 클래스 생성시 호출될때 동작
        self._name = name
        self._price = price
    
    def __str__(self): # 클래스의 인스턴스에서 str()이 호출될 때의 동작
        return f'{self.__class__.name} Class Info : {self._name}, {self._price}'
        
    def __add__(self, x): # 사용하기 쉽게 +에 __add__에 매핑되었다고 생각하면 됨
        print("Called __add__")
        return (self._price + x._price) * 0.8
        
    def __sub__(self, x):
        print("Called __sub__")
        return self._price - x._price
        
    def __le__(self, x): # little or equal(<=) 표현
        print("Called __le__")
        if self._price <= x._price:
            return True
        else:
            return False

    def __ge__(self, x): # greater or equal(>=) 표현
        print("Called __ge__")
        if self._price >= x._price:
            return True
        else:
            return False
'''
# 인스턴스 생성  
xps13 = Notebook('XPS13', 100)
macbook_pro = Notebook('Macbook Pro', 200)

# add method를 구현하지 않았다면 아래처럼(그러지 추천하지 않음)
print(xps13._price + macbook_pro._price)

# add method를 구현했기 때문에 이렇게!
print(xps13 + macbook_pro)
'''

https://zzsza.github.io/development/2020/07/05/python-magic-method/

  •  __doc__
    • Docstring을 출력하는 메소드

 

  • __bool__
    • Boolean 유무를 나타내는 메소드
    • bool(n)과 동일한 표현

 

  • __del__
    • 객체를 없어질 때 호출되는 메소드
    • 내부에 있는 레퍼런스 카운터가 0이 되면 삭제됨

 

  • __bytes__
    • 객체를 나타내는 byte 문자열

 

  • __format__
    • 객체를 나타내는 format을 지정하고 싶을 때 사용

 

  • __len__
    • 객체의 길이를 반환

 

  • __iter__
    • 컨테이너의 iterator를 반환

 

  • __reversed__
    • 순서가 반대로 바뀌는 reversed() 함수 호출

 

  • __contains__
    • item 인자를 받고, 존재하면 True, 아니면 False
    • __contains__가 정의도지 않으면 __iter__를 통해 이터레이션을 돌며 확인함

인스턴스.속성 (. 점 == __getattribute__ )

class Stock:
    def __getattribute__(self, item):
        print(item, "객체에 접근하셨습니다.")


s = Stock()
s.data(아무이름) # ==> data 객체에 접근하셨습니다.

참조 : https://wikidocs.net/83755

가시성 (프라이빗 변수) 

= 객체 외부에서 보이지 않도록 캡슐화와 정보 은닉이 가능

( 외부에서 __items속성에 접근하면 속성 오류 발생 )

class Box:
	def __init__(self, name):
    	self.name = name
        self.__items = []
        
    def add_item(self, item):
        self.__items.append(item)
        print('아이템 추가')
        
	def get_number_of_items(self):
    	return len(self.__items)
        
 box = Box('asd')
 
 print(box.__items) 
 # ==> AttributeError

 

getter, setter

==> 프라이빗 변수에 간접적으로 접근 가능 

( 프라이빗 변수 값을 추출, 변경할 목적 )

property == getter, setter보다 쉽게 만들고 사용할 수 있음

ex @property + @변수이름.setter 

ex 인스턴스.items() 처럼 가져올려고 만듬 ==> 딕셔너리를 사용하지 않을려고( 인스턴스[''] X )

클래스를 만들고 해당 클래스 특성들을 설정( 메소드를 특성처럼 취급해 가져온다 )

클래스 내에 다른 특성들과 연관이 되어 있는 특성들을 관리할 때 사용

@property

def items(self):
	return self.__items
    
@items.setter
def items(self, item):
	self.__items = item
class Person:
	def __init__(self, first_name, last_name):
		self.first_name = first_name
		self.last_name = last_name
		self.full_name = self.first_name + ' ' + self.last_name

fred = Person('Fred', 'Williams')

print(fred.first_name) #=> 'Fred'
print(fred.last_name) #=> 'Williams'
print(fred.full_name) #=> 'Fred Williams'

print('-'*100)

fred.first_name = 'Ted'

print(fred.first_name) #=> 'Ted'
print(fred.full_name) #=> 'Fred Williams'

# 원했던 것은 first_name 과 last_name 을 합치는 것

# case 1
class Person:
	def __init__(self, first_name, last_name):
		self.first_name = first_name
		self.last_name = last_name

	def full_name(self):
		return self.first_name + ' ' + self.last_name

# case 2 클래스의 특성이 아닌 하나의 메소드로
#  해당 메소드를 클래스의 특성 (attribute) 처럼 접근
class Person:
	def __init__(self, first_name, last_name):
		self.first_name = first_name
		self.last_name = last_name

	@property
	def full_name(self):
		return self.first_name + ' ' + self.last_name

# getter, setter 
# @full_name.setter 는 그저 full_name 을 변경할 때 어떻게 바꾸는지 알려주는 함수
class Person:
	def __init__(self, first_name, last_name):
		self.first_name = first_name
		self.last_name = last_name

	@property
	def full_name(self):
		return self.first_name + ' ' + self.last_name
		
	@full_name.setter
	def full_name(self, new_full_name):
		first_name, last_name = new_full_name.split()
		self.first_name = first_name
		self.last_name = last_name

fred = Person('Fred', 'Williams')

print(fred.first_name) #=> 'Fred'
print(fred.full_name) #=> 'Fred Williams'

fred.full_name = 'Ted Bottleneck'

print(fred.first_name) #=> 'Ted'
print(fred.last_name) #=> 'Bottleneck'
print(fred.full_name) #=> 'Ted Bottleneck'
728x90

'IT 개인학습 > Python' 카테고리의 다른 글

Python에서 시간 측정하기(Decorator, Command line)  (0) 2021.09.26
Error, try ... except  (0) 2021.07.18
Class 상속(inheritance)  (0) 2021.07.18
Class , Object , Method ( OOP )  (0) 2021.07.18
Python 함수  (0) 2021.07.18

댓글