๐Ÿ [Python] แ„แ…ณแ†ฏแ„…แ…ขแ„‰แ…ณ & แ„†แ…ฆแ„‰แ…ฉแ„ƒแ…ณ แ„‰แ…ตแ†ทแ„’แ…ช - 2แ„‡แ…ฎ

ํด๋ž˜์Šค ์ฝ”๋“œ

๋‹ค์Œ๊ณผ ๊ฐ™์ด ํด๋ž˜์Šค ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

class Car():
    def __init__(self, company, details) -> None:
        self._company = company
        self._details = details

    def __str__(self) -> str:
        return f'str : {self._company} - {self._details}'

    def __repr__(self) -> str:
        return f'repr : {self._company} - {self._details}'


self ์˜ ์˜๋ฏธ

์ดํ›„, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

car1 = Car("Ferrari", {'color': 'white', 'horsepower': 400, 'price': 8000})
car2 = Car("BMW", {'color': 'Black', 'horsepower':200, 'price': 3000})
car3 = Car("Audi", {'color': 'Silver', 'horsepower': 300, 'price': 8000})

ํด๋ž˜์Šค ์ฝ”๋“œ์—์„œ ๊ฐ ๋ฉ”์†Œ๋“œ๋งˆ๋‹ค ์ธ์ž๋กœ self๋ฅผ ์ž…๋ ฅ ๋ฐ›์•„์•ผ, ํ˜„์žฌ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ ์ฃผ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ธ์Šคํ„ด์Šค ์ •๋ณด ์ฆ‰, self ๋ฅผ ๋ฐ›์•„์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ํ™•์ธ ์‹ค์ œ๋กœ ํ™•์ธ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํด๋ž˜์Šค ์•ˆ์— ๋ฉ”์†Œ๋“œ๋ฅผ ์ถ”๊ฐ€ ํ•ด์ค๋‹ˆ๋‹ค.

    def detail_info(self):
        print(f"Current ID : {id(self)}")
        print(f"Car Detail Info : {self._company} {self._details.get('price')}")

์ดํ›„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด id ๊ฐ’์„ ์ถœ๋ ฅํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

print(id(car1))
car1.detail_info()

# 4455768016
# Current ID : 4455768016
# Car Detail Info : Ferrari 8000


์ฆ‰, ์ธ์Šคํ„ด์Šค์˜ id๊ฐ’๊ณ  ์ธ์Šคํ„ด์Šค์˜ self ๋Š” ๊ฐ™์Œ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ์˜ˆ๋ฅผ ๋“ค์–ด __class__ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜„์žฌ ์ธ์Šคํ„ด์Šค์˜ ํด๋ž˜์Šค๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

print(car1.__class__, car2.__class__)
print(id(car1.__class__) , id(car2.__class__))

# <class '__main__.Car'> <class '__main__.Car'>
# 140311856751936 140311856751936

์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ์›ํ˜•์ธ ํด๋ž˜์Šค ๋˜ํ•œ ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด์ด๊ณ  ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ณ  ์žˆ๋Š” ๊ฒƒ ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ธ์Šคํ„ด์Šค์˜ ์›ํ˜•์ธ ํด๋ž˜์Šค๊ฐ€ ์ธ์Šคํ„ด์Šค๋ผ๊ณ  ํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธ์Šคํ„ด์Šค๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š๊ณ  ํด๋ž˜์Šค ๋ฐ”๋กœ ๋’ค์— ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?

Car.detail_info()
# TypeError: detail_info() missing 1 required positional argument: 'self'

์œ„์™€ ๊ฐ™์ด ์—๋Ÿฌ๊ฐ€ ๋œจ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์‚ดํŽด ๋ณด๋ฉด self ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋‹น์—ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์„ ์–ธ ํ•  ๋•Œ, ์ธ์ž๋กœ self๋ฅผ ์„ ์–ธ ํ•˜์˜€์ง๋‚˜ ์ด๋ฅผ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ฆ‰, self ๋ฅผ ๋„˜๊ฒจ ์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธ์Šคํ„ด์Šค๋ฅผ ๋„˜๊ฒจ ์ฃผ๋ฉด ํ•ด๊ฒฐ์ด ๊ฐ€๋Šฅ ํ•ฉ๋‹ˆ๋‹ค.

Car.detail_info(car1)
# Current ID : 4376506320
# Car Detail Info : Ferrari 8000

car1.detail_info()
# Current ID : 4376506320
# Car Detail Info : Ferrari 8000

์ด์ „์— ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹น ํ›„, detail_info ๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฒฐ๊ณผ ์ž์ฒด๊ฐ€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ธ์Šคํ„ด์Šค์—์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœ ํ•  ๊ฒฝ์šฐ self ์ธ์ž๋ฅผ ์ž๋™ ์œผ๋กœ ๋„˜๊ฒจ ์ฃผ๋Š” ๊ฒƒ์ด๊ณ  Car.detail_info(car1) ๊ณผ ๊ฐ™๋Š” ๋ฐฉ๋ฒ•์€ ์šฐ๋ฆฌ๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋„˜๊ฒจ์ค€ ์ฐจ์ด ์ž…๋‹ˆ๋‹ค.


ํด๋ž˜์Šค ๋ณ€์ˆ˜ ์„ ์–ธ

ํด๋ž˜์Šค ๋ณ€์ˆ˜๋Š” __init__ ๋ฉ”์†Œ๋“œ์™€ ํด๋ž˜์Šค ์ด๋ฆ„ ์‚ฌ์ด ๊ณต๊ฐ„์— ์„ ์–ธ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

class Car():
    # ํด๋ž˜์Šค ๋ณ€์ˆ˜
    car_count = 0

    def __init__(self, company, details) -> None:
        self._company = company
        self._details = details

์ดํ›„, __dict__ ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ด๋ฅผ ์ถœ๋ ฅํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

car1.__dict__
# {'_company': 'Ferrari', '_details': {'color': 'white', 'horsepower': 400, 'price': 8000}}

ํ•˜์ง€๋งŒ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด car_count ๋ฅผ ์ ‘๊ทผํ•˜๋ฉด ๋˜ ์ ‘๊ทผ์€ ๊ฐ€๋Šฅ ํ•ฉ๋‹ˆ๋‹ค.

car1.car_count
# 0


ํด๋ž˜์Šค ์•ˆ์— ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์•ˆ์—๋Š” ์กด์žฌ ํ•˜์ง€ ์•Š์ง€๋งŒ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ˆ˜์ • ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, __init__ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ ๋งˆ๋‹ค car_count ๊ฐ€ ์ฆ๊ฐ€ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

class Car():
    # ํด๋ž˜์Šค ๋ณ€์ˆ˜
    car_count = 0

    def __init__(self, company, details) -> None:
        self._company = company
        self._details = details
        Car.car_count += 1

์ด๋ ‡๊ฒŒ ์ž‘์„ฑ ํ›„, ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

car1 = Car("Ferrari", {'color': 'white', 'horsepower': 400, 'price': 8000})
car2 = Car("BMW", {'color': 'Black', 'horsepower':200, 'price': 3000})
car3 = Car("Audi", {'color': 'Silver', 'horsepower': 300, 'price': 8000})

print(car1.car_count)
# 3


์ฆ‰, ํด๋ž˜์Šค ๋ณ€์ˆ˜๋Š” ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ดํ›„, dir ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐ์–ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

>>> dir(car1)
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_company', '_details', 'car_count', 'detail_info']

์œ„์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ์‚ดํŽด ๋ณด๋ฉด car_count ๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, __dict__ ๋Š” ์ธ์Šคํ„ด์Šค ๋งŒ์˜ ๋ณ€์ˆ˜๋งŒ ์ถœ๋ ฅ ํ•˜๋Š”๊ฒƒ์ด๊ณ , dir ๋Š” ํด๋ž˜์Šค ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ๋ณ€์ˆ˜, ์ƒ์†๋ฐ›์€ ๋ณ€์ˆ˜, ์ธ์Šคํ„ด์Šค ๋‚ด๋ถ€ ๋ณ€์ˆ˜ ๋ชจ๋‘ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋•Œ๋ฌธ์— ๋‚ด๋ถ€ ๋ณ€์ˆ˜๋ฅผ ํ™•์ธ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์— dir ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์™€ ํด๋ž˜์Šค ๋ณ€์ˆ˜๋ฅผ ๊ตฌ๋ถ„ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— _company ์™€ ๊ฐ™์ด _ ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌ๋ถ„ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.