TIL11. Python : Special method

ID์งฑ์žฌยท2021๋…„ 9์›” 13์ผ
0

Python

๋ชฉ๋ก ๋ณด๊ธฐ
23/39
post-thumbnail

๐Ÿ“Œ ์ด ํฌ์ŠคํŒ…์—์„œ๋Š” Python์˜ special method์— ๋Œ€ํ•ด ์ต์ˆ™ํ•ด์ง€๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์ ธ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.



๐ŸŒˆ Special method

๐Ÿ”ฅ Special method๋ž€?

๐Ÿ”ฅ Special method๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๊ธฐ

๐Ÿ”ฅ Special method๋กœ Vector ๋งŒ๋“ค๊ธฐ



1. Special method๋ž€?

๐Ÿค” special method๊ฐ€ ๋ฌด์—‡์ผ๊นŒ?

โœ”๏ธ ํŒŒ์ด์ฌ์˜ ๋ชจ๋“  ์ž๋ฃŒํ˜•์€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์—์„œ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— class ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๋ฐ์ดํ„ฐ ํƒ€์ž…๋ณ„๋กœ ์œ ์šฉํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
โœ”๏ธ ์ž๋ฃŒ๊ตฌ์กฐ์˜ ์‚ดํŽด๋ณด๋ฉด ๋”๋ธ” ์–ธ๋”์Šค์ฝ”์–ด(__)๋กœ ์‹œ์ž‘ํ•˜๊ณ  ๋๋‚˜๋Š” ํ˜•ํƒœ์˜ ๋งค์„œ๋“œ๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ์ด๋ฅผ "Magic method" ๋˜๋Š” "Special method"๋ผ ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

print(int) # <class 'int'>
print(dir(int))
"""
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__',
'__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__',
'__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__',
'__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__',
'__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__',
'__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__',
'__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__',
'__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
'__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio',
'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator',
'real', 'to_bytes']
"""

โœ”๏ธ ์˜ˆ๋ฅผ๋“ค์–ด, intํ˜• ๋ฐ์ดํ„ฐ๊ฐ€ +(๋”ํ•˜๊ธฐ), -(๋นผ๊ธฐ) ๋“ฑ ์‚ฌ์น™์—ฐ์‚ฐ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ intํ˜• ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€์—๋Š” ์ด๋ฅผ ์œ„ํ•œ "Special method"๊ฐ€ ์ค€๋น„๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

# ๋”ํ•˜๊ธฐ(+)
n = 100
print(n+200) # 300
print(n.__add__(200)) # 300
print(n.__doc__)
"""
int([x]) -> integer
int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is a number, return x.__int__().  For floating point
numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in the
given base.  The literal can be preceded by '+' or '-' and be surrounded
by whitespace.  The base defaults to 10.  Valid bases are 0 and 2-36.
Base 0 means to interpret the base from the string as an integer literal.
>> int('0b100', base=0)
4
"""
# ๊ณฑํ•˜๊ธฐ(*)
n = 2
print(n*100) # 200
print(n.__mul__(100)) # 200
# Boolean
n = 0
print(bool(n)) # False
print(n.__bool__()) # False

2. Special method๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๊ธฐ

๐Ÿค” specail method๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๋ฉด ๋ถˆ๊ฐ€๋Šฅ ํ–ˆ๋˜ ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ”๏ธ Calss ๊ฐ์ฒด๋Š” intํ˜•์ฒ˜๋Ÿผ ์‚ฌ์น™์—ฐ์‚ฐ์ด๋‚˜ ๋Œ€์†Œ๋น„๊ต ๋“ฑ์„ ์‹œ๋„ํ•˜๋ฉด TypeError๊ฐ€ ๋ฐœ์ƒ๋ฉ๋‹ˆ๋‹ค.

class Student:
    def __init__(self, name, height):
        self._name = name
        self._height = height
# ๊ฐ์ฒด ์ƒ์„ฑ
s1 = Student('Jaewon', 171)
s2 = Student('Haezin', 163)
print(s1 + s2) # TypeError
print(s1 >= s2) # TypeError
print(s1 <= s2) # TypeError
print(s1 - s2) # TypeError

โœ”๏ธ ์ด๋Ÿดใ„ท ๋•Œ, "Special method"๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ํ•„์š”์— ๋”ฐ๋ผ ๊ทธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ณ , ์ž‘๋™ ๋ฐฉ๋ฒ•์„ ๋‹ค๋ฅด๊ฒŒ customํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

class Student:
    def __init__(self, name, height):
        self._name = name
        self._height = height
    # __str__ ์˜ค๋ฒ„๋ผ์ด๋”ฉ
    def __str__(self): 
        return 'Student Class Info : {}, {}'.format(self._name, self._height)
    # __ge__ ์˜ค๋ฒ„๋ผ์ด๋”ฉ
    def __ge__(self, x): # ๐Ÿ‘ˆ ge : ํฌ๊ฑฐ๋‚˜ ๊ฐ™๋‹ค
        if self._height >= x._height:
            return True
        else:
            return False
    # __le__ ์˜ค๋ฒ„๋ผ์ด๋”ฉ
    def __le__(self, x): # ๐Ÿ‘ˆ le : ์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค
        if self._height <= x._height:
            return True
        else:
            return False
    # __sub__ ์˜ค๋ฒ„๋ผ์ด๋”ฉ
    def __sub__(self, x):
        return self._height - x._height
# ๊ฐ์ฒด ์ƒ์„ฑ
s1 = Student('Jaewon', 171)
s2 = Student('Haezin', 163)
# __str__ ๋งค์„œ๋“œ ์ถœ๋ ฅ
print(s1) # Student Class Info : Jaewon, 171
print(s2) # Student Class Info : Haezin, 163
# __ge__  ๋งค์„œ๋“œ ์ถœ๋ ฅ
print(s1 >= s2) # True
print(s1.__ge__(s2)) # True
# __le__ ๋งค์„œ๋“œ ์ถœ๋ ฅ
print(s1 <= s2) # False
print(s1.__le__(s2)) # False
# __sub__ ๋งค์„œ๋“œ ์ถœ๋ ฅ
print(s1 - s2) # 8
print(s2 - s1) # -8

3. Special method๋กœ Vector ๋งŒ๋“ค๊ธฐ

# Magic Method
class Vector(object):
    def __init__(self, *args):
        """Create a vetor, example : v = Vector(1,2)"""
        if len(args) == 0:
            self._x, self._y = 0, 0
        else:
            self._x, self._y = args
    def __repr__(self):
        """Returns the vector informations"""
        return 'Vector(%r, %r)' % (self._x, self._y)
    def __add__(self, other):
        """Returns the vector addition of self and other"""
        return Vector(self._x + other._x, self._y + other._y)
    def __mul__(self, y):
        return Vector(self._x * y, self._y * y)
    def __bool__(self):
        return bool(max(self._x, self._y))
# Vector ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
v1 = Vector(3,5)
v2 = Vector(15,20)
v3 = Vector()
# ๋งค์ง๋ฉ”์†Œ๋“œ ์ถœ๋ ฅ
print(Vector.__init__.__doc__) # Create a vetor, example : v = Vector(1,2)
print(Vector.__repr__.__doc__) # Returns the vector informations
print(Vector.__add__.__doc__) # Returns the vector addition of self and other
print(v1, v2, v3) # Vector(3, 5) Vector(15, 20) Vector(0, 0)
print(v1 + v2) # Vector(18, 25)
print(v1 * 4) # Vector(12, 20)
print(v2 * 10) # Vector(150, 200)
print(bool(v1), bool(v2), bool(v3)) # True True False
profile
Keep Going, Keep Coding!

0๊ฐœ์˜ ๋Œ“๊ธ€