๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ Python/OOP

[OOP] (4) ์ถ”์ƒํ™”(Abstraction) : docstring, type hinting, ์ •์  ๋™์  ํƒ€์ž… ์–ธ์–ด

Hello๐Ÿ‘‹ I'm Dona!:)

๊ฐ์ฒด ์ง€ํ–ฅํ”„๋กœ๊ทธ๋ž˜๋ฐ ์˜์–ด๋กœ๋Š” OOP(Object-Oriented-Programming) ์ •๋ฆฌํ•˜๊ธฐ 4ํƒ„! ๐Ÿก


๐Ÿ” ๋“ค์–ด๊ฐ€๋ฉฐ : ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์ถ”์ƒํ™”๋ž€?

  • ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ๊ผญ ์•Œ์•„์•ผ๋งŒ ํ•˜๋Š” ๋ถ€๋ถ„๋งŒ์„ ๊ฒ‰์œผ๋กœ ๋“œ๋Ÿฌ๋‚ด๋Š” ๊ฒƒ
  • ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์ด ํŠน์ • ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ํ•„์ˆ˜์ ์ธ ์ •๋ณด๋ฅผ ์ œ์™ธํ•œ ์„ธ๋ถ€์‚ฌํ•ญ์„ ๊ฐ€๋ฆฌ๋Š” ๊ฒƒ
  • ๋ณ€์ˆ˜ ์ถ”์ƒํ™”, ํ•จ์ˆ˜ ์ถ”์ƒํ™”, ํด๋ž˜์Šค ์ถ”์ƒํ™” ๋“ฑ์ด ์žˆ๋‹ค.
์ถ”์ƒํ™”๋ž€, " ๋ณต์žกํ•œ ๋‚ด์šฉ์€ ์ˆจ๊ธฐ๊ณ , ์ฃผ์š” ๊ธฐ๋Šฅ์—๋งŒ ์‹ ๊ฒฝ์“ฐ๋Š” ๊ฒƒ "

1.  ์ถ”์ƒํ™” ์ž˜ํ•˜๊ธฐ : ์ด๋ฆ„ ์ž˜ ์ง“๊ธฐ

  • ํด๋ž˜์Šค, ๋ณ€์ˆ˜, ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์„ ์–ด๋””์— ์“ธ ์ˆ˜ ์žˆ๊ณ , ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์ง๊ด€์ ์œผ๋กœ ์œ ์ถ”๋˜๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์ž
  • ๋ณ€์ˆ˜ ์ด๋ฆ„์— ๋Œ€ํ•œ ๊ทœ์น™์ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด PEP8์„ ์ฐธ๊ณ ํ•˜์ž - python PEP8(์ฝ”๋”ฉ ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ) 
  • ํ•„์ž๊ฐ€ ์ฝ”์„ธ๋ผ์—์„œ ํŒŒ์ด์ฌ ๊ฐ•์˜์—์„œ ๋ฐฐ์šด ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ๋‹ˆ๋ชจ๋‹‰(mnemonic)ํ•˜๊ฒŒ ์ง“๋Š” ๊ฒƒ๋„ ์—ฌ๊ธฐ์— ํ•ด๋‹น๋œ๋‹ค.
  • ๐Ÿฅ•๋‹ˆ๋ชจ๋‹‰ ๋ณ€์ˆ˜ ์ด๋ฆ„(mnemonic varaiable name) : ๋ณด๋Š” ์‚ฌ๋žŒ์„ ์œ„ํ•ด ์ ์ ˆํžˆ ์„ ํƒ๋œ ๋ณ€์ˆ˜ ์ด๋ฆ„, ๊ธฐ์–ตํ•˜๊ธฐ ์‰ฌ์šด 
  • ์›น์—์„œ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋ณ€์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ํ™•์ธํ•˜๋ฉฐ ์ฝ”๋”ฉ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์‚ฌ์ดํŠธ๋ฅผ ์†Œ๊ฐœํ•œ๋‹ค

๊ฐ„๋‹จํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ ํ’€์ด์— ํ™œ์šฉํ•˜๊ธฐ์— ์ข‹๋‹ค

ํด๋ž˜์Šค, ๋ณ€์ˆ˜, ๋ฉ”์†Œ๋“œ ์ถ”์ƒํ™”๋ฅผ ์ฝ”๋“œ ์˜ˆ์‹œ๋กœ ๋Š๊ปด๋ณด์ž

# ์ถ”์ƒํ™”์˜ ์•ˆ ์ข‹์€ ์˜ˆ์‹œ : ์–ด๋””์— ์“ฐ๋Š” ํด๋ž˜์Šค, ํ•จ์ˆ˜, ๋ณ€์ˆ˜์ธ์ง€ ์ดํ•ดํ•˜๊ธฐ ํž˜๋“ค๋‹ค
class SomeClass:
    class_variable = 0.02
    
    def __init__(self, variable_1, variable_2):
        self.variable_1 = variable_1
        self.variable_2 = variable_2
        
    def method_1(self, some_value):
        self.variable_2 += some_value

 

# ์ถ”์ƒํ™”์˜ ์ข‹์€ ์˜ˆ์‹œ : ์–ด๋””์— ์“ฐ๋Š” ํด๋ž˜์Šค, ํ•จ์ˆ˜, ๋ณ€์ˆ˜์ด๊ณ  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ์ง€ ์ง๊ด€์ ์œผ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค
class BankAccount:
	'''์€ํ–‰ ๊ณ„์ขŒ ํด๋ž˜์Šค'''
    interest = 0.02 # ์ด์ž
    
    def __init__(self, owner_name, balance):
        self.owner_name = owner_name # ์ด๋ฆ„
        self.balance = balance # ์ž”์•ก
        
    def deposit(self, amount):
        # ์˜ˆ๊ธˆ
        self.balance += amount

2.  ๋ฌธ์„œํ™”(docstring = documentation string)

  • ์ถ”์ƒํ™”๋ฅผ ๋” ์ž˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” 'docstring'์ด ์žˆ๋‹ค
  • ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ, """์ด๋ ‡๊ฒŒ""", ๋˜๋Š” '''์ด๋ ‡๊ฒŒ''' ๋”ฐ์˜ดํ‘œ ์„ธ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค
  • ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ docstring ๋‚ด์šฉ์€ __doc__ ์†์„ฑ์— ์ €์žฅ๋˜๋ฉฐ, help(class์ด๋ฆ„)๋กœ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค
  • ๋ฌธ์„œํ™”์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ํ”„๋กœ๊ทธ๋žจ์„ ํ•จ๊ป˜ ๋งŒ๋“œ๋Š” ํŒ€์›๋“ค๊ณผ ๋ฌธ์„œํ™” ํฌ๋งท(style)์— ๊ด€ํ•ด ๋ฏธ๋ฆฌ ์•ฝ์†์„ ํ•˜๊ณ  ์ด๋ฅผ ์ž˜ ์ง€ํ‚ค๋Š” ๊ฒƒ! ๐Ÿค™
  • ํ˜ผ์ž์„œ ๋งŒ๋“œ๋Š” ํ”„๋กœ๊ทธ๋žจ์ด๋ผ๋„ ์ž์‹ ๋งŒ์˜ ํฌ๋งท(style)์„ ์ผ๊ด€์„ฑ์žˆ๊ฒŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋‚˜์ค‘์— ํ”„๋กœ๊ทธ๋žจ์„ ์ˆ˜์ •ํ•  ๋•Œ ์ข‹๋‹ค๐Ÿ‘
# docstring ์‚ฌ์šฉ ์˜ˆ์‹œ
class BankAccount:
    '''์€ํ–‰ ๊ณ„์ขŒ ํด๋ž˜์Šค'''
    interest = 0.02
    
    def __init__(self, owner_name, balance):
        '''์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ : name(๋ฌธ์ž์—ด), balance(์‹ค์ˆ˜ํ˜•)'''
        self.owner_name = owner_name
        self.balance = balance
        
    def deposit(self, amount):
        '''์ž”์•ก ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ balance๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ amount๋งŒํผ ๋Š˜๋ ค์ฃผ๋Š” ๋ฉ”์†Œ๋“œ'''
        self.balance += amount
        
    def withdraw(self, amount):
        '''์ž”์•ก ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ balance๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ amount๋งŒํผ ์ค„์—ฌ์ฃผ๋Š” ๋ฉ”์†Œ๋“œ'''
        if self.balance < amount:
            print("Insufficient balance!")
        else:
            self.balance -= amount

# docstring ํ™•์ธํ•˜๊ธฐ
help(BankAccount)

  

help(class์ด๋ฆ„)์„ ํ†ตํ•ด docstirng ํ™•์ธํ•œ ๊ฒฐ๊ณผ


๐Ÿ“Ž docstring style

docstring์˜ ํ˜•์‹์— ๊ผญ ์ง€์ผœ์•ผํ•  ๊ทœ์น™์€ ์—†์ง€๋งŒ, ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” ํฌ๋งท์€ ์žˆ๋‹ค.

๋Œ€ํ‘œ์ ์ธ ๋ฌธ์„œํ™”(docstring)์˜ 3๊ฐ€์ง€ ํฌ๋งท(style)์„ ์ฝ”๋“œ ์˜ˆ์‹œ์™€ ํ•จ๊ป˜ ์•Œ์•„๋ณด์ž.

   

  1. Google docstring
    # example : ์œ ์ €๋ฅผ ์œ„ํ•œ ์ถ”์ฒœ ์˜์ƒ์„ ์ฐพ๋Š” ๋ฉ”์†Œ๋“œ์˜ docstring์„ ์ž‘์„ฑํ•ด๋ณด์ž
    
    def find_suggestion_videos(self, number_of_suggestions=5):
        """์œ ์ €์—๊ฒŒ ์ถ”์ฒœํ•  ์˜์ƒ์„ ์ฐพ์•„์ค€๋‹ค
        Parameters:
          number_of_suggestions (int): ์ถ”์ฒœํ•˜๊ณ  ์‹ถ์€ ์˜์ƒ ์ˆ˜
            (๊ธฐ๋ณธ๊ฐ’์€ 5)
            
        Returns:
          list: ์ถ”์ฒœํ•  ์˜์ƒ ์ฃผ์†Œ๊ฐ€ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ
        """
     
  2. reStructuredText (ํŒŒ์ด์ฌ ๊ณต์‹ ๋ฌธ์„œํ™” ๊ธฐ์ค€)
    # example : ์œ ์ €๋ฅผ ์œ„ํ•œ ์ถ”์ฒœ ์˜์ƒ์„ ์ฐพ๋Š” ๋ฉ”์†Œ๋“œ์˜ docstring์„ ์ž‘์„ฑํ•ด๋ณด์ž
    
    def find_suggestion_videos(self, number_of_suggestions=5):
        """์œ ์ €์—๊ฒŒ ์ถ”์ฒœํ•  ์˜์ƒ์„ ์ฐพ์•„์ค€๋‹ค
        
        :param number_of_suggestions: ์ถ”์ฒœํ•˜๊ณ  ์‹ถ์€ ์˜์ƒ ์ˆ˜
          (๊ธฐ๋ณธ๊ฐ’์€ 5)
        :type number_of_suggestions: int
        :returns: ์ถ”์ฒœํ•  ์˜์ƒ ์ฃผ์†Œ๊ฐ€ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ
        :rtype: list
        """
     
  3. NumPy/SciPy (ํ†ต๊ณ„, ๊ณผํ•™ ๋ถ„์•ผ์—์„œ ์“ฐ์ด๋Š” Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)
    # example : ์œ ์ €๋ฅผ ์œ„ํ•œ ์ถ”์ฒœ ์˜์ƒ์„ ์ฐพ๋Š” ๋ฉ”์†Œ๋“œ์˜ docstring์„ ์ž‘์„ฑํ•ด๋ณด์ž
    
    def find_suggestion_videos(self, number_of_suggestions=5):
        """์œ ์ €์—๊ฒŒ ์ถ”์ฒœํ•  ์˜์ƒ์„ ์ฐพ์•„์ค€๋‹ค
        
        Parameters
        ----------
        number_of_suggestions: int
          ์ถ”์ฒœํ•˜๊ณ  ์‹ถ์€ ์˜์ƒ ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’์€ 5)
        
        Returns
        -------
        list 
          ์ถ”์ฒœํ•  ์˜์ƒ ์ฃผ์†Œ๊ฐ€ ๋‹ด๊ธด ๋ฆฌ์ŠคํŠธ
        """

๐Ÿ“Ž type hinting with python

  • ํŒŒ์ด์ฌ์„ ์ •์  ํƒ€์ž… ์–ธ์–ด์ฒ˜๋Ÿผ ํƒ€์ž…์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ
  • ํŒŒ์ด์ฌ์€ ๋™์  ํƒ€์ž… ์–ธ์–ด(๊ทธ๋•Œ ๊ทธ๋•Œ ํ•จ์ˆ˜์˜ ํƒ€์ž…์ด ๋ณ€ํ•œ๋‹ค)
  • type hingting์„ ์ง€ํ‚ค์ง€์•Š์•„๋„ error๋Š” ์•ˆ๋‚˜์ง€๋งŒ, ์—‰๋šฑํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์Œ
# example
# ๋ณ€์ˆ˜์— ๋„ฃ์–ด์•ผํ•  ํƒ€์ž…์„ hinting
x : float = 0.02
y : int = 3

# ํ•จ์ˆ˜ : ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์˜ ํƒ€์ž…์„ hinting
def func -> float :

# ํด๋ž˜์Šค
class BankAccount:
    '''์€ํ–‰ ๊ณ„์ขŒ ํด๋ž˜์Šค'''
    interest: float = 0.02
    
    def __init__(self, owner_name: str, balance: float) -> None:
        '''์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ : name(๋ฌธ์ž์—ด), balance(์‹ค์ˆ˜ํ˜•)'''
        self.owner_name = owner_name
        self.balance = balance
        
    def deposit(self, amount: float) -> None:
        '''์ž”์•ก ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ balance๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ amount๋งŒํผ ๋Š˜๋ ค์ฃผ๋Š” ๋ฉ”์†Œ๋“œ'''
        self.balance += amount
        
    def withdraw(self, amount: float) -> None:
        '''์ž”์•ก ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ balance๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ amount๋งŒํผ ์ค„์—ฌ์ฃผ๋Š” ๋ฉ”์†Œ๋“œ'''
        if self.balance < amount:
            print("Insufficient balance!")
        else:
            self.balance -= amount

๐Ÿ“Ž ๋™์  ํƒ€์ž… ์–ธ์–ด vs ์ •์  ํƒ€์ž… ์–ธ์–ด

[๋™์  ํƒ€์ž… ์–ธ์–ด]

  • ํƒ€์ž…(์ž๋ฃŒํ˜•)์„ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ(์ปดํŒŒ์ผ) ์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‹คํ–‰ํ•˜๋ฉด์„œ ๊ฒฐ์ •ํ•จ
  • ๋Œ€ํ‘œ์ ์œผ๋กœ Python, Javascript, Ruby ๋“ฑ์˜ ์–ธ์–ด๊ฐ€ ์žˆ์Œ
  • ์žฅ์  : ์‹คํ–‰ํ•  ๋•Œ๊นŒ์ง€ ํƒ€์ž…์— ๋Œ€ํ•œ ๊ฒฐ์ •์„ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ ํƒ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ์Œ, ์ฝ”๋“œ๊ฐ€ ๊ฐ„๋‹จํ•จ
  • ๋‹จ์  : ๋ณ€์ˆ˜์— ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ํƒ€์ž…์ด ๋“ค์–ด์™€ TypeError๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
# ๋™์  ํƒ€์ž… ์–ธ์–ด : python
i = 0
j = 1.5
k = "DONA"

  

[์ •์  ํƒ€์ž… ์–ธ์–ด]

  • ๋ณ€์ˆ˜ ์„ ์–ธ ์‹œ ์•ž์— ํƒ€์ž…(์ž๋ฃŒํ˜•)์„ ์ง€์ •ํ•ด์ฃผ์–ด์•ผํ•จ, ๋งž์ง€ ์•Š์€ ๊ฐ’์ด ๋“ค์–ด์žˆ์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ ๋ฐœ์ƒ
  • ๋Œ€ํ‘œ์ ์œผ๋กœ C, C#, C++, Java ๋“ฑ์˜ ์–ธ์–ด๊ฐ€ ์žˆ์Œ
  • ์žฅ์  : ์ปดํŒŒ์ผ ์‹œ ํƒ€์ž…์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๋น ๋ฅด๊ณ , ํƒ€์ž… ์—๋Ÿฌ ๋ฌธ์ œ์ ์„ ์ดˆ๊ธฐ์— ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ •์„ฑ์ด ๋†’์Œ
# ์ •์  ํƒ€์ž… ์–ธ์–ด : java
int i = 0;
float j = 1.5;
String k = "DONA";
String k = new String("DONA");

๐Ÿ“Ž Reference

๐Ÿก ํ•ด๋‹น ๋ธ”๋กœ๊ทธ OOP series