์ง๋ ์๊ฐ์ ๋ฐฐ์ ๋ ๋ฉํ ํด๋์ค๊ฐ ๋์ด๋ ์ต์์ด์์ผ๋,
descriptor๋ ์ฝ๊ฒ ๋๊ปด์ง๊ฑฐ๋ผ๋ ๊ฐ์ฌ๋์ ๋ง์,, ์ฌ์ค์ด์๋ค. ๐ฅบ์์ ์ property ๋ฐฐ์ธ ๋ getter, setter๋ฅผ ๋ฐฐ์ ๋ค.
์ด ๋ด์ฉ์ ํ์ฅํ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ ๋ณต์ต์ ํ๊ณ ์ค์! (link๐)getter, setter๊ฐ high level์์ ์๋ํ๋ค๋ฉด, descriptor๋ low level์์ ์๋ํ๋ค.
descriptor๋ฅผ ์ด์ฉํด์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐฉํฅ์ผ๋ก ๊ฐ์ ํด์ ํ๋ก๊ทธ๋๋ฐ์ ํ ์ ์๋๋ก ํด๋ณด์
1. ๊ฐ์ฒด์์ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์์ฑ๊ฐ์ผ๋ก ๊ฐ์ง ๋ ์ฌ์ฉ๋๋ค.
๋ค๋ฅธ ๊ฐ์ฒด์ ์์ฑ์ผ๋ก์จ ์กด์ฌํ ๋, ๊ทธ ์์ฑ์ ๋ํ์ฌ ์ฝ๊ธฐ, ์ฐ๊ธฐ, ์ญ์ ๋ฑ์ ๋์์ ํ ๋, ๋์์ ๋ฐ๋ผ ๊ฐ ๊ตฌํ๋ method๊ฐ ํธ์ถ๋๋ ๊ฐ์ฒด์ด๋ค.
2. read, write, delete ๋ฑ์ ๋ฏธ๋ฆฌ ์ ์ ๊ฐ๋ฅํ๋ค.
3. โญ๏ธ ๋๊ฐ์ง ์ข ๋ฅ๋ก ๋๋๋ค.
- data descriptor (set, del) : ๋ฐ์ดํฐ๋ฅผ ์ง์ ์ฐ๊ฑฐ๋, ์ง์ฐ๋ ์์ ์ ํ๋ค.
- non-data descriptor (get) : ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ๋ง ํ๋ค.
์ฅ์
- ์ฝ๊ธฐ ์ ์ฉ ๊ฐ์ฒด ์์ฑ์ ํ ์ ์๋ค.
- ํด๋์ค๋ฅผ ์๋ํ๋ ๋ฐฉํฅ์ผ๋ก ์์ฑ ๊ฐ๋ฅํ๋ค.
__get__
, write๋ฅผ ํ __set__
, delete๋ฅผ ํ __delete__
name ์ด๋ผ๋ ์์ฑ์ ๋ํด์ ์ ๊ทผํ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์๋ค.
class descriptorEx1(object):
def __init__(self, name="Default"):
self.name = name
def __get__(self, obj, objtype):
return 'Get Method called -> self : {}, obj : {}, objtype: {}, name: {}'.format(
self, obj, objtype, self.name)
def __set__(self, obj, name):
print('set method called')
if isinstance(name, str):
self.name = name
else:
# ์กฐ๊ฑด์ ๋ฐ๋ผ ์๋ฌ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ค.
raise TypeError('Name should be string')
def __delete__(self, obj):
print('Delete method called.')
self.name = None
class Sample1(object):
name = descriptorEx1()
s1 = Sample1()
# __set__ ํธ์ถ
s1.name = 'Descriptor test1'
# set ๋ฉ์๋์์ ์์์ ๋ฌธ์์ด์ธ์ง ์ฒดํฌํ๊ณ ,
# name์ __init__์์ ํ ๋น์ ํด์ฃผ๋๋ฐ,
# ์ค์ ๋ก Sample1 class ๋ด๋ถ์ name์ ํ ๋น์ด ๋๋ค.
s1.name(10)
# ์์ธ ๋ฐ์ ; TypeError: 'str' object is not callable
# [atrr ํ์ธ]
# __get__ ํธ์ถ
print('ex 1>', s1.name)
# ex 1> Get Method called
# -> self : <__main__.descriptorEx1 object at 0x7f9576ac8fa0>,
# obj : <__main__.Sample1 object at 0x7f9576aa0820>,
# objtype: <class '__main__.Sample1'>,
# name: Descriptor test1
# __ delte__ ํธ์ถ
del s1.name
Sample1
์ name
๋ณ์๊ฐ ์์ ๋ ๋ descriptorEx1
๋ด๋ถ์
__set__
, __get__
๋ฑ์ด ์์์ ํธ์ถ๋๋ค.
โญ๏ธ ๊ธฐ์กด getter, setter๋ ๋ณ์์ ๋ฐ๋ผ์ ๊ฐ์๋ฅผ ๋๋ ค์ค์ผ ํ์ง๋ง
์์ ๊ฐ์ด descriptor ์ฒ๋ฆฌ๋ฅผ ํจ์ผ๋ก์ ์ฝ๋์ ์์ด ์ค์ด๋ค๊ฒ ๋๋ค.
์์ ์์ ๋ Property๋ Property ํด๋์ค ๋ณ๋๋ก, ์ฌ์ฉ์ ์ฌ์ฉ ํด๋์ค ๋ณ๋๋ก ํธ์ถ์ ํ๋ค.
์ด๋ฒ์ Property๋ฅผ ์ด์ฉํด์ ์์์ ๋ฒ์ฉ์ ์ธ ์ญํ ์ ํ๊ฒ ๊ตฌํ์ ํด๋ณด์.
class property(fget=None, fset=None, fdel=None, doc=None)
__get__, __set__
๊ณผ ๊ฐ์ด ๋ฐ๋ก ์ ํด์ง ๊ท์น์ด ์์ผ๋ฏ๋ก ๋ง์๋๋ก ๋ค์ด๋ฐ ํด์ฃผ์.class DescriptorEx2(object):
def __init__(self, value):
self._name = value
def getVal(self):
return 'Get method called -> self:{}, name: {}'.format(self, self._name)
def setVal(self, value):
print('set method called')
if isinstance(value, str):
self._name = value
else:
raise TypeError('name should ba string.')
def delVal(self):
print('delete method called')
self._name = None
# property ๋ฉ์๋๋ฅผ ํธ์ถํด์ ๋ณ๋๋ก ์ง์ ํ get,set,del,doc๋ฅผ ๋ฃ์ด์ ๋ง๋ค๊ธฐ
name = property(getVal, setVal, delVal,
'Property ํ
์คํธ๋ฅผ ํ๋ name ํ๋์
๋๋ค.')
s2 = DescriptorEx2('Descriptor Test2')
์์ ์์ ์ ๋์ผํ๊ฒ ๋์ํ๋ค.
[์ถ์ฒ]