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

์ฝ”๋“œ

class Car():
    """
    Car class
    Author : Lee
    Date : 2021
    Description : Class, Static, Instance Method
    """

    # ํด๋ž˜์Šค ๋ณ€์ˆ˜
    price_per_raise = 1.0

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

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

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


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

    def __del__(self):
        Car.car_count -= 1


Instance Method

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

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

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

์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ์ž‘์„ฑํ•ด์™”๋˜ ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ๋Š” self ์ธ์ž๋ฅผ ๋ฐ›์€๋ฐ ์ด๋Š” ๊ฐ์ฒด์˜ ๊ณ ์œ ํ•œ ์†์„ฑ๊ฐ’์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— ์ธ์Šคํ„ด์Šค๋งˆ๋‹ค ๊ณ ์œ ํ•œ ๋ฉ”์†Œ๋“œ์™€ ๋ฉ”์†Œ๋“œ ์•ˆ์—์„œ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.


๋ณ€์ˆ˜ ์ ‘๊ทผ

์•„๋ž˜์™€ ๊ฐ™์ด ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์— ๋Œ€ํ•ด์„œ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ ์ ‘๊ทผ ํ•  ๊ฒฝ์šฐ ๊ฐ’์ด ๋ณ€๊ฒฝ์ด ๊ต‰์žฅํžˆ ์ทจ์•ฝํ•จ์œผ๋กœ ์‹œ์Šคํ…œ ์ƒ์—์„œ ์น˜๋ช…์ ์ธ ๋ฌธ์ œ๋ฅผ ์ดˆ๋ž˜ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ ‘๊ทผ ํ•˜๊ณ ์ž ํ•˜๋Š” ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๊ฐ€ ์€ํ–‰ ์ด์ž์œจ์ด๋ผ๊ณ  ํ•ด๋ณด์ž.

car1._details.get('price')

๋•Œ๋ฌธ์— ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์˜ ํ˜ธ์ถœ์„ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ๋กœ ๊ฐ์‹ธ ์ค˜์•ผ ์ทจ์•ฝ์„ฑ์„ ๊ฐœ์„  ํ•  ์ˆ˜ ์žˆ๋‹ค.

def get_price(self):
    return f"Before Car price -> company : {self._company} price : { 					self._details.get('price')}"

๋˜ํ•œ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํด๋ž˜์Šค ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์ธ์Šคํ„ด์Šค ๋“ค์˜ ๊ฐ’์„ ์ผ๊ด„์ ์œผ๋กœ ์ˆ˜์ • ํ•  ์ˆ˜ ์žˆ๋‹ค.

print(car1.get_price())
print(car2.get_price())
Car.price_per_raise = 1.4
print(car1.get_price())
print(car2.get_price())

# Before Car price -> company : Ferrari price : 8000
# Before Car price -> company : BMW price : 3000
# Before Car price -> company : Ferrari price : 8000
# Before Car price -> company : BMW price : 3000


Class method(ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ)

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

ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ๋Š” @classmethod ๋ฅผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ, doc์˜ ๋‚ด์šฉ๋ฅผ ์‚ดํŽด ๋ณด์ž

classmethod(function) -> method

Convert a function to be a class method.

A class method receives the class as implicit first argument, just like an instance method receives the instance. To declare a class method, use this idiom:

  class C:
      @classmethod def f(cls, arg1, arg2, ...):


์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ class ๋ฅผ ๋ฐ›๋Š”๋‹ค๊ณ  ๋ช…์‹œํ•˜๊ณ  ์žˆ๋‹ค. ์ฆ‰ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.

@classmethod
    def raise_price(cls, per):
        cls.price_per_raise # = Car.price_per_raise

์—ฌ๊ธฐ์„œ cls ๋Š” class ์ธ์ž๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ self ๋กœ ๋ฐ›์•„์„œ ๊ณ ์œ ํ•œ ๊ฐ’์„ ์ฒ˜๋ฆฌ ํ•œ ๊ฒƒ ์ฒ˜๋Ÿผ, ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ๋Š” cls ๋ฅผ ๋ฐ›์•„์„œ ์ด๋ฅผ ๊ณ ์œ ํ•œ ํด๋ž˜์Šค๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค. ๋•Œ๋ฌธ์— cls.price_per_raise ์™€ ๊ฐ™์ด ์ž‘์„ฑํ•œ ๊ฒƒ์€ ์•ž์„œ ์ž‘์„ฑํ•œ Car.price_per_raise ์™€ ๊ฐ™์€ ์˜๋ฏธ์ด๋‹ค.

๋˜ํ•œ, @classmethod ๋ผ๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š”, ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ๋Š” ๋ชจ๋“  ์ธ์Šคํ„ด์Šค์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋งค์ฃผ ์ค‘์š”ํ•˜๋‹ค . ๋•Œ๋ฌธ์— ์ฃผ์˜๋ฅผ ์ง‘์ค‘์‹œ์ผœ ์ฃผ๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์ดํ•ด์— ๋„์›€์ด ๋œ๋‹ค.


๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ ์ž‘์„ฑ์„ ์ง„ํ–‰ ํ•œ๋‹ค.

@classmethod
def raise_price(cls, per):
    if per <= 1:
        print('Please Enter 1 or More')
        return
    cls.price_per_raise = per
    print('Succeed! price increased')

# Before Car price -> company : Ferrari price : 8000.0
# Succeed! price increased
# Before Car price -> company : Ferrari price : 12800.0


Static method (์ •์  ๋ฉ”์†Œ๋“œ)

ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ์™€ ๋‹ฌ๋ฆฌ ์•„๋ฌด ์ธ์ž๋„ ๋ฐ›์ง€ ์•Š๊ณ , ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์  ๋ฉ”์†Œ๋“œ๋ผ๊ณ  ํ•œ๋‹ค.

์ฆ‰, ์ •๋ฆฌ๋ฅผ ํ•˜๋ฉด ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ๋Š” self: ์ธ์Šคํ„ด์Šค ๋ฅผ ๋ฐ›๊ณ , ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ๋Š” cls:ํด๋ž˜์Šค ๋ฅผ ๋ฐ›๊ณ , ์ •์  ๋ฉ”์†Œ๋“œ๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ์™€ ๋™์ผํ•˜๊ฒŒ @staticmethod ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ์‚ฌ์šฉ ๋ชฉ์ ์— ๋งž๊ฒŒ ์ž„์˜๋กœ inst: instance ์ธ์ž๋ฅผ ๋ฐ›์•„ _company ์˜ ๊ฐ’์ด BWM ์ธ์ง€ ํ™•์ธ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑ ํ•ฉ๋‹ˆ๋‹ค.

@staticmethod
def is_bmw(inst):
    if inst._company == 'BMW':
        return f'OK! This is {inst._details}'
    return 'Sorry. This is car not BMW'


>>> print(car1.is_bmw(car1))
>>> print(car2.is_bmw(car2))
# Sorry. This is car not BMW
# OK! This is {'color': 'Black', 'horsepower': 200, 'price': 3000}

์ •์  ๋ฉ”์†Œ๋“œ์˜ ํŠน์ดํ•œ ์ ์€ ์ธ์Šคํ„ด์Šค ์•ˆ์—์„œ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ํด๋ž˜์Šค ์ž์ฒด์—์„œ ์‹คํ–‰์ด ๊ฐ€๋Šฅ ํ•˜๋‹ค๋Š” ์  ์ž…๋‹ˆ๋‹ค. (์ธ์ž๋ฅผ ๋ฐ›์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋Š ๊ฒƒ์—๋„ ์ข…์† ๋˜์ง€ ์•Š์Œ) -> ์œ ์—ฐ ํ•˜๊ฒŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

print(Car.is_bmw(car2))
# OK! This is {'color': 'Black', 'horsepower': 200, 'price': 3000}