KR_Exception - somaz94/python-study GitHub Wiki
์์ธ ์ฒ๋ฆฌ๋ ํ๋ก๊ทธ๋จ ์คํ ์ค ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
try:
# ์คํํ ์ฝ๋
result = 10 / 0
except ZeroDivisionError as e:
# ์์ธ ๋ฐ์์ ์คํํ ์ฝ๋
print(f"์๋ฌ ๋ฐ์: {e}")
else:
# ์์ธ๊ฐ ๋ฐ์ํ์ง ์์์ ๋ ์คํํ ์ฝ๋
print("์ฑ๊ณต!")
finally:
# ์์ธ ๋ฐ์ ์ฌ๋ถ์ ๊ด๊ณ์์ด ์คํํ ์ฝ๋
print("์ข
๋ฃ")
# ๊ธฐ๋ณธ ์์ธ ์ฒ๋ฆฌ
try:
num = int(input("์ซ์๋ฅผ ์
๋ ฅํ์ธ์: "))
result = 100 / num
print(f"๊ฒฐ๊ณผ: {result}")
except ValueError:
print("์ฌ๋ฐ๋ฅธ ์ซ์๋ฅผ ์
๋ ฅํ์ธ์.")
except ZeroDivisionError:
print("0์ผ๋ก ๋๋ ์ ์์ต๋๋ค.")
์์ธ ์ฒ๋ฆฌ ํ๋ฆ:
-
try
๋ธ๋ก์ ์ฝ๋๊ฐ ์คํ๋๋ค. - ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ํด๋น ์์ธ์ ์ผ์นํ๋
except
๋ธ๋ก์ด ์คํ๋๋ค. - ์ผ์นํ๋
except
๊ฐ ์์ผ๋ฉด ์์ธ๋ ์์ ํธ์ถ์๋ก ์ ํ๋๋ค. - ์์ธ๊ฐ ๋ฐ์ํ์ง ์์ผ๋ฉด
else
๋ธ๋ก์ด ์คํ๋๋ค. - ๋ง์ง๋ง์ผ๋ก
finally
๋ธ๋ก์ด ํญ์ ์คํ๋๋ค.
def safe_division(a, b):
try:
result = a / b
except ZeroDivisionError:
print("0์ผ๋ก ๋๋ ์ ์์ต๋๋ค.")
return None
except TypeError:
print("์ซ์๋ง ๋๋ ์ ์์ต๋๋ค.")
return None
else:
print("๋๋์
์ฑ๊ณต!")
return result
finally:
print("๋๋์
์ฐ์ฐ ์ข
๋ฃ")
# ํ
์คํธ
print(safe_division(10, 2)) # ์ ์ ์ผ์ด์ค
print(safe_division(10, 0)) # 0์ผ๋ก ๋๋๊ธฐ
print(safe_division(10, "2")) # ํ์
์๋ฌ
Python์ ๋ค์ํ ๋ด์ฅ ์์ธ ํด๋์ค๋ฅผ ์ ๊ณตํ๋ค. ๋ชจ๋ ์์ธ๋ BaseException
ํด๋์ค์์ ํ์๋๋ค.
# ๊ธฐ๋ณธ์ ์ธ ๋ด์ฅ ์์ธ๋ค
try:
# IndexError
list1 = [1, 2, 3]
print(list1[4])
except IndexError:
print("๋ฆฌ์คํธ ์ธ๋ฑ์ค ๋ฒ์ ์ด๊ณผ")
try:
# KeyError
dict1 = {"a": 1}
print(dict1["b"])
except KeyError:
print("์กด์ฌํ์ง ์๋ ํค")
try:
# ValueError
int("abc")
except ValueError:
print("์๋ชป๋ ๊ฐ ๋ณํ")
- Exception: ๋๋ถ๋ถ์ ๋ด์ฅ ์์ธ์ ๊ธฐ๋ณธ ํด๋์ค
-
ArithmeticError: ๋ชจ๋ ์ฐ์ ์ฐ์ฐ ๊ด๋ จ ์ค๋ฅ์ ๊ธฐ๋ณธ ํด๋์ค
- ZeroDivisionError: 0์ผ๋ก ๋๋๊ธฐ ์๋
- OverflowError: ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ๋๋ฌด ํผ
-
LookupError: ๋งคํ ๋๋ ์ํ์ค ๊ด๋ จ ์ค๋ฅ์ ๊ธฐ๋ณธ ํด๋์ค
- IndexError: ์ํ์ค์์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์ธ๋ฑ์ค
- KeyError: ๋งคํ(๋์ ๋๋ฆฌ)์์ ์กด์ฌํ์ง ์๋ ํค
- ValueError: ๊ฐ์ด ์ ์ ํ์ง ์์ (์ฌ๋ฐ๋ฅธ ํ์ ์ด์ง๋ง ๋ถ์ ์ ํ ๊ฐ)
- TypeError: ๋ถ์ ์ ํ ํ์ ์ ๊ฐ์ฒด์ ์ฐ์ฐ ์ ์ฉ
- NameError: ์กด์ฌํ์ง ์๋ ๋ณ์ ์ฐธ์กฐ
- AttributeError: ๊ฐ์ฒด์ ์กด์ฌํ์ง ์๋ ์์ฑ ์ฐธ์กฐ
- SyntaxError: ํ์ด์ฌ ๋ฌธ๋ฒ ์ค๋ฅ (์ปดํ์ผ ์๊ฐ ์์ธ)
- RuntimeError: ํ๋ก๊ทธ๋จ ์คํ ์ค ๋ฐ์ํ ์ผ๋ฐ์ ์ธ ์ค๋ฅ
- FileNotFoundError: ํ์ผ์ด ์กด์ฌํ์ง ์์
- PermissionError: ํ์ผ ์ ๊ทผ ๊ถํ ๋ถ์กฑ
- ImportError/ModuleNotFoundError: ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ ์คํจ
- MemoryError: ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ
- RecursionError: ์ต๋ ์ฌ๊ท ๊น์ด ์ด๊ณผ
# ์์ธ ํ์
๊ณ์ธต ๊ตฌ์กฐ ํ์ธ
def print_exception_hierarchy(exception_class, indent=0):
print(' ' * indent + exception_class.__name__)
for subclass in exception_class.__subclasses__():
print_exception_hierarchy(subclass, indent + 4)
# ์ผ๋ถ ์์ธ ๊ณ์ธต ๊ตฌ์กฐ ์ถ๋ ฅ
print_exception_hierarchy(BaseException)
# ์์ ๊ด๊ณ๋ฅผ ์ด์ฉํ ์์ธ ์ฒ๋ฆฌ
try:
# ๋ค์ํ ์ฐ์ ์์ธ ๊ฐ๋ฅ์ฑ์ด ์๋ ์ฝ๋
result = 1 / 0
except ArithmeticError as e:
print(f"์ํ ์ฐ์ฐ ์ค๋ฅ: {type(e).__name__} - {e}")
ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ด์ฅ ์์ธ๋ง์ผ๋ก ๋ชจ๋ ์ค๋ฅ ์ํฉ์ ํํํ๊ธฐ ์ด๋ ค์ธ ๋ ์ฌ์ฉ์ ์ ์ ์์ธ๋ฅผ ๋ง๋ค ์ ์๋ค.
class CustomError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return self.message
def validate_age(age):
if age < 0:
raise CustomError("๋์ด๋ ์์์ผ ์ ์์ต๋๋ค")
return age
# ๊ธฐ๋ณธ ์์ธ ํด๋์ค
class AppError(Exception):
"""์ ํ๋ฆฌ์ผ์ด์
๊ธฐ๋ณธ ์์ธ"""
def __init__(self, message="์ ํ๋ฆฌ์ผ์ด์
์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค", code=None):
self.message = message
self.code = code
super().__init__(self.message)
# ํน์ ๊ธฐ๋ฅ๋ณ ์์ธ
class ValidationError(AppError):
"""์
๋ ฅ๊ฐ ๊ฒ์ฆ ์์ธ"""
def __init__(self, message="์
๋ ฅ๊ฐ์ด ์ ํจํ์ง ์์ต๋๋ค", field=None):
self.field = field
message_with_field = f"{message} (ํ๋: {field})" if field else message
super().__init__(message_with_field, code="VALIDATION_ERROR")
class DatabaseError(AppError):
"""๋ฐ์ดํฐ๋ฒ ์ด์ค ์์
์์ธ"""
def __init__(self, message="๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๋ฅ", operation=None):
self.operation = operation
message_with_op = f"{message} (์์
: {operation})" if operation else message
super().__init__(message_with_op, code="DB_ERROR")
# ์์ธ ์ฌ์ฉ
def register_user(username, age):
if not username:
raise ValidationError("์ฌ์ฉ์ ์ด๋ฆ์ ํ์์
๋๋ค", "username")
if not isinstance(age, int) or age < 0 or age > 150:
raise ValidationError("๋์ด๋ 0-150 ์ฌ์ด์ ์ ์์ฌ์ผ ํฉ๋๋ค", "age")
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์ฅ ์๋ฎฌ๋ ์ด์
if username == "admin":
raise DatabaseError("์ฌ์ฉ์ ์ ์ฅ ์คํจ", "INSERT")
return {"username": username, "age": age}
# ์์ธ ์ฒ๋ฆฌ
try:
user = register_user("", 25)
except ValidationError as e:
print(f"๊ฒ์ฆ ์ค๋ฅ: {e.message}, ์ฝ๋: {e.code}, ํ๋: {e.field}")
except DatabaseError as e:
print(f"DB ์ค๋ฅ: {e.message}, ์ฝ๋: {e.code}, ์์
: {e.operation}")
except AppError as e:
print(f"์ผ๋ฐ ์ค๋ฅ: {e.message}, ์ฝ๋: {e.code}")
# ์ฌ๋ฌ ์์ธ ์ฒ๋ฆฌ
try:
value = input("๊ฐ์ ์
๋ ฅํ์ธ์: ")
num = int(value)
result = 100 / num
print(f"๊ฒฐ๊ณผ: {result}")
except (TypeError, ValueError) as e:
# ์ฌ๋ฌ ์์ธ๋ฅผ ํ๋ฒ์ ์ฒ๋ฆฌ
print(f"ํ์
๋๋ ๊ฐ ์๋ฌ: {e}")
except ZeroDivisionError as e:
print(f"0์ผ๋ก ๋๋ ์ ์์ต๋๋ค: {e}")
except Exception as e:
# ๋ชจ๋ ์์ธ ์ฒ๋ฆฌ (๋ง์ง๋ง ์์ธ ์ฒ๋ฆฌ์๋ก๋ง ์ฌ์ฉ)
print(f"๊ธฐํ ์๋ฌ: {e}")
# ์์ธ ํํผ (์ผ๋ถ๋ฌ ๋ฌด์)
def ignore_exception():
try:
# ์คํจํด๋ ๊ด์ฐฎ์ ์์
risky_operation()
except Exception:
pass # ์์ธ ๋ฌด์
# ์์ธ ๋ค์ ๋ฐ์ (์์ธ ์ฒด์ธ)
def process_data(data):
try:
return process_value(data)
except ValueError as e:
# ์ถ๊ฐ ์ ๋ณด์ ํจ๊ป ์์ธ ๋ค์ ๋ฐ์
raise ValueError(f"๋ฐ์ดํฐ ์ฒ๋ฆฌ ์คํจ: {data}") from e
# ํ์ฌ ์์ธ ์ ๋ณด ์ ๊ทผ
import sys
def log_exception():
try:
1 / 0
except:
# ํ์ฌ ์์ธ ์ ๋ณด ํ์ธ
exc_type, exc_value, exc_traceback = sys.exc_info()
print(f"์์ธ ์ ํ: {exc_type}")
print(f"์์ธ ๊ฐ: {exc_value}")
# ์์ธ ์ถ์ ์ ๋ณด ์ถ๋ ฅ
import traceback
traceback.print_exc() # ๊ฐ๋จํ ์คํ ์ถ์ ์ ๋ณด ์ถ๋ ฅ
def calculate_average(numbers):
# ์กฐ๊ฑด ํ์ธ ๋ฐ ์คํจ ์ AssertionError ๋ฐ์
assert len(numbers) > 0, "๋ฆฌ์คํธ๊ฐ ๋น์ด์์ต๋๋ค"
return sum(numbers) / len(numbers)
# assert ์ฌ์ฉ ์
try:
avg = calculate_average([])
except AssertionError as e:
print(f"์ด์ค์
์ค๋ฅ: {e}")
Python์์๋ ๋ณดํต ๋ ๊ฐ์ง ์ฝ๋ฉ ์คํ์ผ์ ์ฌ์ฉํ๋ค:
- EAFP (Easier to Ask for Forgiveness than Permission): ํ๋ฝ๋ณด๋ค ์ฉ์๊ฐ ์ฝ๋ค
- LBYL (Look Before You Leap): ๋์ฝํ๊ธฐ ์ ์ ์ดํด๋ณธ๋ค
# LBYL ๋ฐฉ์ (์ฌ์ ๊ฒ์ฌ)
def lbyl_style(data, key):
if key in data: # ๋จผ์ ํ์ธ
return data[key]
else:
return None
# EAFP ๋ฐฉ์ (์์ธ ์ฒ๋ฆฌ)
def eafp_style(data, key):
try:
return data[key] # ์ผ๋จ ์๋
except KeyError:
return None
# Python์ ์ผ๋ฐ์ ์ผ๋ก EAFP ์คํ์ผ์ ์ ํธํ๋ค
์ปจํ
์คํธ ๋งค๋์ ๋ with
๋ฌธ๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ, ์์ ๊ด๋ฆฌ๋ฅผ ์๋ํํ๋ค.
# with ๋ฌธ์ ์ฌ์ฉํ ์์ ๊ด๋ฆฌ
with open('file.txt', 'r') as f:
content = f.read()
# ํ์ผ์ด ์๋์ผ๋ก ๋ซํ (์์ธ ๋ฐ์ํด๋ ๋ซํ)
# ํด๋์ค ๊ธฐ๋ฐ ์ปจํ
์คํธ ๋งค๋์
class MyContextManager:
def __init__(self, name):
self.name = name
def __enter__(self):
print(f"{self.name} ์ปจํ
์คํธ ์์")
return self # with ๋ฌธ์ as ๋ณ์์ ํ ๋น๋จ
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"{self.name} ์ปจํ
์คํธ ์ข
๋ฃ")
# ์์ธ ์ ๋ณด ์ถ๋ ฅ
if exc_type is not None:
print(f"์์ธ ๋ฐ์: {exc_type.__name__} - {exc_val}")
# True ๋ฐํ ์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ ๊ฒ์ผ๋ก ๊ฐ์ฃผ
# False ๋๋ None ๋ฐํ ์ ์์ธ๋ฅผ ํธ์ถ์์๊ฒ ์ ํ
return False # ์์ธ ์ ํ
# ์ฌ์ฉ ์์
try:
with MyContextManager("ํ
์คํธ") as cm:
print("์์
์ํ ์ค...")
raise ValueError("ํ
์คํธ ์์ธ")
print("์ด ์ค์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด ์คํ๋์ง ์์")
except ValueError:
print("์์ธ๊ฐ ์ ํ๋์์ต๋๋ค.")
from contextlib import contextmanager
@contextmanager
def my_context(name):
print(f"{name} ์ปจํ
์คํธ ์์")
try:
# yield ์ด์ : __enter__์ ํด๋น
yield name # ์ปจํ
์คํธ ๋ด๋ถ๋ก ๊ฐ ์ ๋ฌ
# yield ์ดํ: ์ ์ ์ข
๋ฃ ์ __exit__์ ํด๋น
print(f"{name} ์ปจํ
์คํธ ์ ์ ์ข
๋ฃ")
except Exception as e:
# ์์ธ ๋ฐ์ ์ __exit__์ ํด๋น
print(f"{name} ์ปจํ
์คํธ ์์ธ ์ข
๋ฃ: {e}")
# ๋ค์ ๋ฐ์์ํค๋ฉด ํธ์ถ์์๊ฒ ์์ธ ์ ํ
raise
# ์ฌ์ฉ ์์
with my_context("๋ฐ์ฝ๋ ์ดํฐ") as value:
print(f"์ปจํ
์คํธ ๋ด๋ถ, ๊ฐ: {value}")
# ์์ธ ๋ฐ์ ์ ์ปจํ
์คํธ ๊ด๋ฆฌ์๊ฐ ์ฒ๋ฆฌ
# raise ValueError("ํ
์คํธ ์์ธ")
# ์์ ๋๋ ํ ๋ฆฌ ์ปจํ
์คํธ ๋งค๋์
import tempfile
import shutil
import os
@contextmanager
def temporary_directory():
temp_dir = tempfile.mkdtemp()
print(f"์์ ๋๋ ํ ๋ฆฌ ์์ฑ: {temp_dir}")
try:
yield temp_dir
finally:
print(f"์์ ๋๋ ํ ๋ฆฌ ์ญ์ : {temp_dir}")
shutil.rmtree(temp_dir)
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์
์ปจํ
์คํธ ๋งค๋์ (๊ฐ์)
@contextmanager
def transaction():
print("ํธ๋์ญ์
์์")
try:
yield
print("ํธ๋์ญ์
์ปค๋ฐ")
except:
print("ํธ๋์ญ์
๋กค๋ฐฑ")
raise
# ์ฌ์ฉ ์์
with temporary_directory() as temp_dir:
# ์์ ํ์ผ ์์ฑ
file_path = os.path.join(temp_dir, "test.txt")
with open(file_path, "w") as f:
f.write("ํ
์คํธ ๋ฐ์ดํฐ")
print(f"ํ์ผ ์์ฑ๋จ: {file_path}")
# ์ปจํ
์คํธ ์ข
๋ฃ ์ ์์ ๋๋ ํ ๋ฆฌ์ ํ์ผ ์ญ์
# ์ธ๋ถํ๋ ์์ธ ์ฒ๋ฆฌ
def process_user_input():
try:
# ์์ try ๋ธ๋ก์ผ๋ก ํน์ ์์
๋ง ๋ณดํธ
age = int(input("๋์ด๋ฅผ ์
๋ ฅํ์ธ์: "))
except ValueError:
print("๋์ด๋ ์ซ์๋ก ์
๋ ฅํด์ผ ํฉ๋๋ค.")
return None
try:
# ๋ค๋ฅธ ์์
์ ๋ณ๋์ try ๋ธ๋ก์ผ๋ก ๋ณดํธ
name = input("์ด๋ฆ์ ์
๋ ฅํ์ธ์: ")
if not name:
raise ValueError("์ด๋ฆ์ ํ์์
๋๋ค.")
except ValueError as e:
print(f"์
๋ ฅ ์ค๋ฅ: {e}")
return None
# ์ฑ๊ณต ์ ๊ฒฐ๊ณผ ๋ฐํ
return {"name": name, "age": age}
# ๋๋น - ๋๋ฌด ํฐ try ๋ธ๋ก (์ํฐ ํจํด)
def process_user_input_bad():
try:
# ๋๋ฌด ๋ง์ ๋ก์ง์ ํ๋์ try์ ํฌํจ
age = int(input("๋์ด๋ฅผ ์
๋ ฅํ์ธ์: "))
name = input("์ด๋ฆ์ ์
๋ ฅํ์ธ์: ")
if not name:
raise ValueError("์ด๋ฆ์ ํ์์
๋๋ค.")
return {"name": name, "age": age}
except Exception as e:
# ๋๋ฌด ์ผ๋ฐ์ ์ธ ์์ธ ์ฒ๋ฆฌ
print(f"์ค๋ฅ ๋ฐ์: {e}")
return None
import logging
# ๋ก๊น
์ค์
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def divide_numbers(a, b):
try:
result = a / b
logger.info(f"๋๋์
์ฑ๊ณต: {a} / {b} = {result}")
return result
except ZeroDivisionError:
# ์์ธ ๋ก๊น
(์ ์ ํ ๋ ๋ฒจ ์ ํ)
logger.error(f"0์ผ๋ก ๋๋๊ธฐ ์๋: {a} / {b}", exc_info=True)
# ์ฌ์ฉ์์๊ฒ ์น์ํ ๋ฉ์์ง ๋ฐํ
return "0์ผ๋ก ๋๋ ์ ์์ต๋๋ค"
except TypeError as e:
logger.exception(f"ํ์
์ค๋ฅ: {a} / {b}") # ์ ์ฒด ์คํ ์ถ์ ๋ก๊น
return f"์ซ์๋ง ๋๋ ์ ์์ต๋๋ค: {e}"
# ์ง์คํ๋ ์ค๋ฅ ์ฒ๋ฆฌ
def get_user_by_id(user_id):
try:
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ก์ธ์ค ์ฝ๋
user = database.find_user(user_id)
return user
except DatabaseConnectionError:
log_error("๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์คํจ")
raise ServiceUnavailableError("์๋น์ค๊ฐ ์ผ์์ ์ผ๋ก ๋ถ๊ฐ๋ฅํฉ๋๋ค")
except UserNotFoundError:
return None # ์ฌ์ฉ์๊ฐ ์์ผ๋ฉด None ๋ฐํ
except Exception as e:
log_error(f"์ฌ์ฉ์ ์กฐํ ์ค ์ ์ ์๋ ์ค๋ฅ: {e}")
raise InternalServerError("๋ด๋ถ ์๋ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค")
# ์กฐ๊ธฐ ๋ฐํ๊ณผ ๊ฐ๋ ์กฐํญ (Guard Clause)
def process_payment(payment):
# ์ ์ ์กฐ๊ฑด ๊ฒ์ฌ - ๋น ๋ฅธ ์คํจ(Fail Fast) ์ ๋ต
if not payment:
raise ValueError("๊ฒฐ์ ์ ๋ณด๊ฐ ์์ต๋๋ค")
if not payment.get('amount'):
raise ValueError("๊ฒฐ์ ๊ธ์ก์ด ์์ต๋๋ค")
if payment.get('amount') <= 0:
raise ValueError("๊ฒฐ์ ๊ธ์ก์ ์์์ฌ์ผ ํฉ๋๋ค")
# ์ ์ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด ์ฃผ์ ๋ก์ง ์ํ
return process_valid_payment(payment)
โ ์์ธ ์ฒ๋ฆฌ ๋ชจ๋ฒ ์ฌ๋ก:
- ๊ตฌ์ฒด์ ์ธ ์์ธ๋ฅผ ๋จผ์ ์ฒ๋ฆฌํ๊ณ , ์ผ๋ฐ์ ์ธ ์์ธ๋ฅผ ๋์ค์ ์ฒ๋ฆฌํ๋ค
- ์์ธ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํ์ฉํ์ฌ ๊ด๋ จ ์์ธ๋ฅผ ๊ทธ๋ฃนํํ๋ค
- ์ต์ํ์ ์ฝ๋๋ง try ๋ธ๋ก์ ํฌํจ์์ผ ์ค๋ฅ ์์ธ์ ๋ช ํํ ํ๋ค
- ๋งค์ฐ ํฐ try-except ๋ธ๋ก์ ํผํ๊ณ ์ ์ ํ ํฌ๊ธฐ๋ก ๋๋๋ค
- ๋น์ด ์๋ except ๋ธ๋ก์ ํน๋ณํ ์ด์ ๊ฐ ์๋ค๋ฉด ์ฌ์ฉํ์ง ์๋๋ค
- ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ธ๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๋ค๋ฉด ์ฌ์ฉ์ ์ ์ ์์ธ ๋์ ์ฌ์ฉํ๋ค
- ์๋ฏธ ์๋ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๊ณ ๊ฐ๋ฅํ๋ฉด ํด๊ฒฐ ๋ฐฉ๋ฒ๋ ์ ์ํ๋ค
- ๋๋ฒ๊น ์ ๋์๋๋ ์ ๋ณด๋ฅผ ๋ก๊ทธ์ ๊ธฐ๋กํ๋ค
- ์ฌ์ฉ์ ์ ์ ์์ธ๋ ์๋ฏธ ์๋ ๊ณ์ธต ๊ตฌ์กฐ๋ก ์ค๊ณํ๋ค
- ์์ ๊ด๋ฆฌ๋ฅผ ์ํด ํญ์ ์ปจํ ์คํธ ๋งค๋์ (with ๋ฌธ)์ ์ฌ์ฉํ๋ค