Skip to content

Latest commit

ย 

History

History
160 lines (120 loc) ยท 5.53 KB

File metadata and controls

160 lines (120 loc) ยท 5.53 KB

42. ๋น„๊ณต๊ฐœ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ณด๋‹ค๋Š” ๊ณต๊ฐœ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

1. private attribute

class MyObject:
    def __init__(self):
        self.public_field = 5
        self.__private_field = 10
        
    def get_private_field(self):
        return self.__private_field

foo = MyObject()
foo.__private_field

>>>
Traceback ...
AttributeError: 'MyObject' object has no attribute '__private_fieldโ€™
  • ๋ฐ‘์ค„ 2๊ฐœ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋Š” private
  • ์™ธ๋ถ€์—์„œ private attribute ์ ‘๊ทผ์€ ์˜ˆ์™ธ ๋ฐœ์ƒ
class MyParentObject:
    def __init__(self):
        self.__private_field = 71
        
class MyChildObject(MyParentObject):
    def get_private_field(self):
        return self.__private_field
        
baz = MyChildObject()
baz.get_private_field()

>>>
Traceback ...   
AttributeError: 'MyChildObject' object has no attribute '_MyChildObject__private_fieldโ€™
  • ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ private attribute ๋Š” ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ

  • python ์—์„œ์˜ private attribute ์ฒ˜๋ฆฌ ๋ฐฉ์‹

    • ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•จ
      • ex. MyChildObject ์˜ __private_field ๋Š” _MyChildObject__private_field ๋กœ ๋ณ€๊ฒฝ๋จ
    • ๊ทธ๋Ÿฌ๋ฏ€๋กœ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ์œ„์น˜์—์„œ ์ ‘๊ทผํ•˜๊ฒŒ ๋˜๋ฉด ์•Œ ์ˆ˜ ์—†๋Š” ์ด๋ฆ„์˜ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋กœ ๋ณ€ํ™˜๋˜์–ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•จ
  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ ‘๊ทผ ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ ์•ˆํ•จ

    def __init__(self):
        self.__private_field = 71
        
class MyChildObject(MyParentObject):
    def get_private_field(self):
        return self.__private_field
        
baz = MyChildObject()
assert baz._MyParentObject__private_field == 71

2. private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์“ฐ์ง€ ๋ง์•„์•ผ ํ•˜๋Š” ์ด์œ 

  • python ์—์„œ private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์—„๊ฒฉํ•˜๊ฒŒ ์ œํ•œํ•˜์ง€ ์•Š์Œ

    • python ๋ชจํ† 

      ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•˜๊ณ  ์‹ถ์€ ์ผ์„ ์–ธ์–ด๊ฐ€ ์ œํ•œํ•˜๋ฉด ์•ˆ๋œ๋‹ค

      ํŠน์ • ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ง€์˜ ์—ฌ๋ถ€๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ณ ๋ คํ•ด์•ผ ํ•  ์ผ, ์ด๋กœ ์ธํ•œ ์ฑ…์ž„์„ ๋‹คํ•˜๋ฉด ๋จ

    • ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ ์‚ฌ๋žŒ์ด ์˜ˆ๊ธฐ์น˜ ๋ชปํ•˜๊ฒŒ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ด์–ด๋‘ ์œผ๋กœ์จ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ๊ทธ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ์ ๋ณด๋‹ค ํฌ๋‹ค๊ณ  ์ƒ๊ฐ

    • ์• ํŠธ๋ฆฌ๋ทฐํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ›…์„ ์ œ๊ณตํ•จ

      • __getattr__
      • __getattribute__
      • __setattr__
  • python ์€ ๋‚ด๋ถ€์— ๋ชฐ๋ž˜ ์ ‘๊ทผํ•จ์œผ๋กœ์จ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋Š” ํ”ผํ•ด๋ฅผ ์ค„์ด๋Š”๋ฐ ์žˆ์–ด์„œ๋Š” ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ์˜ ๋ช…๋ช… ๊ทœ์•ฝ์„ ์ง€ํ‚ฌ ๊ฒƒ์„ ๋‹น๋ถ€ํ•จ

  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ค‘๊ฐ„์— MyStringClass ํด๋ž˜์Šค๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๊ณ  MyIntegerSubclass ์˜ ๋ถ€๋ชจ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ  ํ•˜๋ฉด get_value ์˜ ๋ฐ˜ํ™˜ ํ‘œํ˜„์‹์€ ํ‹€๋ฆฐ ํ‘œํ˜„์ด ๋˜๋ฒ„๋ฆผ

class MyBaseClass:
    def __init__(self, value):
        self._ _value = value
    def get_value(self):
        return self._ _value
        
class MyStringClass(MyBaseClass):
    def get_value(self):
        return str(super().get_value())         # ๋ณ€๊ฒฝ๋จ
        
class MyIntegerSubclass(MyStringClass):
    def get_value(self):
        return int(self._MyStringClass__value)  # ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ
  • ์ด ๊ฒฝ์šฐ ๋ถ€๋ชจ ํด๋ž˜์Šค์ชฝ์—์„œ protected ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ํŽธ์ด ๋” ๋‚˜์Œ
  • ๋ชจ๋“  protected ํ•„๋“œ์— ์„ค๋ช…์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์–ด๋–ค ํ•„๋“œ๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ณ  ์–ด๋–ค ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผ ํ• ์ง€ ๋ช…์‹œํ•ด์•ผ ํ•จ
class MyStringClass:
    def __init__(self, value):
        # ์—ฌ๊ธฐ์„œ ๊ฐ์ฒด์—๊ฒŒ ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค
        # ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ฐ’์€ ๋ฌธ์ž์—ด๋กœ ํƒ€์ž… ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ•˜๋ฉฐ
        # ์ผ๋‹จ ํ•œ๋ฒˆ ๊ฐ์ฒด ๋‚ด๋ถ€์— ์„ค์ •๋˜๊ณ  ๋‚˜๋ฉด 
        # ๋ถˆ๋ณ€ ๊ฐ’์œผ๋กœ ์ทจ๊ธ‰๋ผ์•ผ ํ•œ๋‹ค
        self._value = value
    ...

3. private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์จ์•ผํ•˜๋Š” ๊ฒฝ์šฐ๋Š”?

  • ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์‹ค์ˆ˜๋กœ ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ์ด๋ฏธ ์ •์˜ํ•œ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ •์˜ํ•˜์˜€์„ ๊ฒฝ์šฐ ์ถฉ๋Œ ๋ฐœ์ƒ
class ApiClass:
    def __init__(self):
        self._value = 5
    def get(self):
        return self._value

class Child(ApiClass):
    def __init__(self):
        super().__init__()
        self._value = 'hello'  # ์ถฉ๋Œ

a = Child()
print(f'{a.get()} ์™€ {a._value} ๋Š” ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.')

>>>
hello ์™€ hello ๋Š” ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋Ÿฐ ๋ฌธ์ œ ์œ„ํ—˜์„ฑ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋ถ€๋ชจ ํด๋ž˜์Šค์—์„œ ์• ํŠธ๋ฆฌ๋ทฐํŠธ ์ด๋ฆ„ ๊ฒน์นจ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋น„๊ณต๊ฐœ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
class ApiClass:
    def __init__(self):
        self.__value = 5      # ๋ฐ‘์ค„ ๋‘ ๊ฐœ#!

    def get(self):
        return self.__value   # ๋ฐ‘์ค„ ๋‘ ๊ฐœ#!

class Child(ApiClass):
    def __init__(self):
        super().__init__()
        self._value = 'hello'  # OK!

a = Child()
print(f'{a.get()} ์™€ {a._value} ๋Š” ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.')

>>>
5 ์™€ hello ๋Š” ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

4. ์ •๋ฆฌ

  • python ์—์„œ๋Š” private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์ž์‹ ํด๋ž˜์Šค๋‚˜ ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์—„๊ฒฉํ•˜๊ฒŒ ๊ธˆ์ง€ํ•˜์ง„ ์•Š์Œ
  • private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ํ•ด๋‹น ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ง‰๊ธฐ๋ณด๋‹ค๋Š” ํ•ด๋‹น ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์žฌํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ
  • ๋งŒ์ผ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ ‘๊ทผ์„ ๋ง‰์•„์•ผ ํ•œ๋‹ค๋ฉด private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค protected ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ ์ ˆํ•œ ๋ฌธ์„œํ™”๋ฅผ ํ•  ๊ฒƒ
  • private ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ๊ผญ ์‚ฌ์šฉํ•˜์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ์ด๋ฆ„ ์ถฉ๋Œ์ด ์ผ์–ด๋‚˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋ง‰๊ณ  ์‹ถ์„ ๋•Œ ์ด๋‹ค