Imitation, Imagination, Integration

Index

1
2
3
4
5
6
7
8
9
함수의 구분 - magic method란? 
Basic method
Operator method
Inverse operator method
Incremental assignment operator method
Unary operator method
Comparison operator method
Attribute operations
Container type operations

Magic method

함수의 구분 - magic method란?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
파이썬에서 함수는 두 가지로 나뉜다 
1. Function
- 클래스 밖에서 정의되고 클래스와 연관이 없는 함수를 말한다
2. Method
- 클래스 안에서 정의되고 객체의 메소드는 attribute로 볼 수도 있다

여기서 Method는 또 두 가지로 나뉜다

1. Automatically generated by python
- 자동적으로 생성되는 메소드
- Magic method or Special method or Dundu
- __func__() 형태를 띈다
- 특정 조건에 해당할 때 자동적으로 함수가 호출된다
2. Manually defined method
- 클래스 안에서 선언된다는 것을 제외하면 Function과 같다고 할 수 있다

Basic method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1. __new__(cls[,*argv]) 
- object(객체)가 '처음 인스턴스화 될 때 호출'되는 메소드
- 첫번째 매개변수는 클래스, 그 이외의 매개변수는 __init__ 메소드로 전달된다
- 이 메소드는 다른 클래스의 생성자를 호출하거나 다른 인스턴스로 직접 반환할 수 있기 때문에 __init__ 메소드 사용 여부를 결정할 수 있다
- 이 메소드는 주로 튜플이나 문자열과 같은 immutable 타입을 상속하는데 사용된다
- __init__ 메소드가 실행되기 전에 호출되는 메소드
- __new__ 메소드가 호출 될때 객체가 메모리에 할당된다
- object를 반환한다
- Java에서는 인스턴스를 메모리에 할당하는 경우 Static factory method라고 한다
- C++에서는 Allocator라고 한다
- Instantiator라고 부르는 경우도 있다
2. __init__(self[,*argv])
- 인스턴스 객체가 '생성'될 때 호출된다
- 생성자 메소드의 역할을 하지만 객체에 메모리를 할당하지 않는 특수한 메소드이다
- Initializer라고 하기도 한다
3. __del__(self)
- 인스턴스 객체가 '삭제'될 때 호출된다
4. __call__(self[,*argv])
- 클래스의 '인스턴스가 함수'처럼 호출되도록 해주는 메소드
- class('name', 28)()이렇게 호출하는 것은 사실 instance.__call__('name',28)와 같다
5. __len__(self)
- 인스턴스 객체의 길이를 반환한다
6. __repr__(self)
- 객체를 사람이 이해할 수 있도록 '설명'하는 문자열을 반환한다
- ls = [1,2,3] 객체가 있을 때 repr(ls)는 '[1,2,3]'을 반환한다
7. __str__(self)
- 어떠한 타입의 인자가 들어와도 모두 '문자열화' 하여 반환한다
- 서로 다른 데이터를 문자열 데이터로 변환하여 서로 호환되도록 한다
- 클래스 내에 __str__ 메소드를 정의하지 않으면 __repr__ 메소드가 대신한다
8. __int__(self)
- int 클래스가 호출 되었을 때 행동할 것들을 정의한다
9. __float__(self)
- float 클래스가 호출 되었을 때 행동할 것들을 정의한다
10. __round__(self[,n])
- round 클래스가 호출 되었을 때 행동할 것들을 정의한다
11. __hash__(self)
- hash 클래스가 호출 되었을 때 행동할 것들을 정의한다
12. __bytes__(self)
- bytes 클래스가 호출 되었을 때 행동할 것들을 정의한다
13. __bool__(self)
- bool 클래스가 호출 되었을 때 행동할 것들을 정의한다
14. __format__(self,form)
- format 클래스가 호출 되었을 때 행동할 것들을 정의한다

Singleton using new method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs): # cls는 class를 의미한다
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs) # super() == object, super()는 상속된 클래스의 출력을 전부 실행하지 않는다 (중복 실행을 방지할 수 있다)
return cls._instance


class SingletonClass(Singleton):
pass

x = SingletonClass()
y = SingletonClass()

print(x==y)
: True

Restrict the number of instance using new method

1
2
3
4
5
6
7
8
9
10
11
12
13
class TwoInstance(object):
MAX_Inst = 2
Inst_created = 0
def __new__(cls, *args, **kwargs):
if (cls.Inst_created >= cls.MAX_Inst):
raise ValueError("Cannot create more objects")
cls.Inst_created += 1
return super().__new__(cls)

ti1 = TwoInstance()
ti2 = TwoInstance()
ti3 = TwoInstance()
: ValueError: Cannot create more objects

str vs repr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class A:
def __str__(self): # self는 instance를 뜻한다
return 'str method is called'

def __repr__(self):
return 'repr method is called'

a = A()

str(a)
: 'str method is called'

print(a)
: str method is called

repr(a)
: 'repr method is called'

a
: repr method is called


class B:
def __repr__(self):
return 'repr method is called'

b = B()

str(b)
: 'repr method is called'

print(b)
: repr method is called

repr(b)
: 'repr method is called'

a
: repr method is called

Operator method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1. __add__(self, other)
2. __sub__(self, other)
3. __mul__(self, other)
4. __truediv__(self, other)
- '/'(나누기)연산을 구현하기 위해 호출되는 메소드
5. __floordiv__(self, other)
- '//'(나누기 후 내림)연산을 구현하기 위해 호출되는 메소드
6. __mod__(self, other)
- '%'(나눈 나머지)연산을 구현하기 위해 호출되는 메소드
7. __pow__(self, other[,mod])
- '**'(제곱)연산을 구현하기 위해 호출되는 메소드
8. __divmod__(self, other)
- '//'(나누기 후 내림)연산과 '%'(나눈 나머지)연산을 동시에 구현하기 위해 호출되는 메소드 ㄴ
9. __lshift__(self, other)
- '<<'(왼쪽 시프트)연산을 구현하기 위해 호출되는 메소드
- n = 10일 때 n << 1 이면, 10을 2진수로 표현하고 => 1010, 1010을 왼쪽으로 한 칸씩 옮기면 10100, 10100을 10진수로 바꾸면 20
10. __rshift__(self, other)
- '>>'(오른쪽 시프트)연산을 구현하기 위해 호출되는 메소드
- n = 10일 때 n >> 1 이면, 10을 2진수로 표현하고 => 1010, 1010을 오른쪽으로 한 칸씩 옮기면 101, 101을 10진수로 바꾸면 5
11. __and__(self, other)
12. __or__(self, other)
13. __xor__(self, other)

Inverse operator method

역 연산자

1
2
3
4
5
6
1. __radd__(self, other)
- '+' 연산을 구현하기 위해 호출되는 메소드
- __add__ 메소드와 동일하지만 차이점은 __radd__ 메소드는 연산하는 숫자 객체가 오른쪽에 있을 경우에 호출 되는 반면 __add__ 메소드는 왼쪽에 있을 경우 호출된다
2. __rsub__(self, other)
- '-' 연산을 구현하기 위해 호출되는 메소드
- __radd__ 메소드의 마이너스 연산 버전이라고 보면 된다

radd and rsub

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Number1(object):
def __add__(self, value):
return 3 + value

def __sub__(self, value):
return 2.1 - value

n1 = Number1()

n1 + 3
: 6
3 + n1
: TypeError: unsupported operand type(s) for +: 'int' and 'Number1'

n1 - 2
: 0.100000000000
2 - n1
: TypeError: unsupported operand type(s) for -: 'int' and 'Number1'

class Number2(object):
def __add__(self, value):
return 3 + value

def __sub__(self, value):
return 2.1 - value

def __radd__(self, value):
return 4 + value

def __rsub__(self, value):
return 3.1 - value

n2 = Number2()

n2 + 3
: 6
3 + n2
: 7

n2 - 2
: 0.100000000000
2 - n2
: 1.1

Incremental assignment operator method

증감 연산자

1
2
3
4
1. __iadd__(self, other)
- '+=' 연산을 구현하기 위해 호출되는 메소드
2. __isub__(self, other)
- '-=' 연산을 구현하기 위해 호출되는 메소드

Unary operator method

단항 연산자

1
2
3
4
5
6
7
8
1. __pos__(self)
- 객체에 '+' 부호를 부여할 때 호출된다
2. __neg__(self)
- 객체에 '-' 부여할 때 호출된다
3. __abs__(self)
- 객체에 절대값 속성을 부여할 때 호출된다
4. __invert__(self)
- '~' 부정 연산을 할 때 호출된다

Comparison operator method

1
2
3
4
5
6
7
8
9
10
11
12
1. __gt__(self, other)
- 왼쪽 항이 더 크다 즉, '>' 연산할 때 호출되는 메소드
2. __ge__(self, other)
- 왼쪽 항이 더 크거나 같다 즉, '>=' 연산할 때 호출되는 메소드
3. __lt__(self, other)
- 왼쪽 항이 더 작다 즉, '<' 연산할 때 호출되는 메소드
4. __le__(self, other)
- 왼쪽 항이 더 작거나 같다 즉, '<=' 연산할 때 호출되는 메소드
5. __eq__(self, other)
- 왼쪽 항과 오른쪽 항이 같다 즉, '==' 연산할 때 호출되는 메소드
6. __ne__(self, other)
- 왼쪽 항과 오른쪽 항이 같지 않다 즉, '!=' 연산할 때 호출되는 메소드

Attribute operations

1
2
3
4
5
6
7
1. __getattr__(self, name)
2. __getattribute__(self, name)
3. __setattr__(self, name, value)
4. __delattr__(self, name)
5. __get__(self, instance, owner)
6. __set__(self, instance, value)
7. __delelte__(self, instance, value)

Container type operations

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1. __len__(self)
- 컨테이너의 크기를 찾을 때 호출되는 메소드
2. __getitem__(self, key)
- 컨테이너안에 있는 특정한 요소를 가져올 때 호출되는 메소드
3. __setitem__(self, key, value)
- 컨테이너 안의 특정한 요소를 지정할 때 호출되는 메소드
4. __delitem__(self, key)
- 컨테이너 안의 특정한 요소를 삭제할 때 호출되는 메소드
5. __iter__(self)
- 이터레이터 안의 요소에 대한 행동을 정의할 때 호출되는 메소드
6. __reversed__(self)
- reversed()함수가 호출될 때 호출되는 메소드
7. __contains__(self, item)
- 컨테이너 객체를 in 이나 not in 키워드를 사용해서 특정 데이터를 찾을 때 호출되는 메소드

Reference

1
2
3
4
1. Parkito blog (https://shoark7.github.io/programming/python/difference-between-__repr__-vs-__str__)
2. Programmer ALL (https://www.programmerall.com/article/6895286124/)
3. Python-course.eu (https://python-course.eu/oop/magic-methods.php)
4. weeklyit.code.blog (https://weeklyit.code.blog/2019/12/24/2019-12-3주-python의-__init__과-__new__/)