class 클래스 이름: #헤더(Header)
pass #몸체(Body)
\n",
"- 인스턴스: 클래스로 부터 만들어낸 객체\n",
"- 모듈 vs. 클래스 vs. 인스턴스\n",
" - 모듈: 파일 단위로 이름 공간을 구성\n",
" - 클래스: 클래스 영역 내에 이름 공간을 구성\n",
" - 인스턴스: 인스턴스 영역 내에 이름 공간을 구성"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"\n",
"2\n",
"\n",
"['__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__', 'a', 'b']\n",
"['__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__', 'a']\n"
]
}
],
"source": [
"class S1:\n",
" a = 1\n",
" \n",
"print(S1.a)\n",
"print()\n",
"\n",
"S1.b = 2 # 클래스 이름 공간에 새로운 이름의 생성\n",
"print(S1.b)\n",
"print()\n",
"\n",
"print(dir(S1)) # S1에 포함된 이름들을 리스트로 반환\n",
"del S1.b # 이름 공간 S1에서 b삭제\n",
"print(dir(S1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 파이썬에서는 동적으로 인스턴스 외부에서 인스턴스 멤버를 추가할 수 있음\n",
" - 클래스와 독립적으로 각 인스턴스를 하나의 이름 공간으로 취급함"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"10\n",
"1\n"
]
}
],
"source": [
"x = S1() # x는 S1의 클래스 인스턴스\n",
"print(x.a)\n",
"\n",
"x.a = 10 # 클래스 인스턴스 x의 이름 공간에 이름 생성\n",
"print(x.a)\n",
"\n",
"print(S1.a) # 클래스 이름 공간과 클래스 인스턴스의 이름공간은 다르다"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"300\n",
"10\n",
"1\n"
]
}
],
"source": [
"y = S1() # S1 클래스의 또 다른 인스턴스 생성\n",
"\n",
"y.a = 300 # 클래스 인스턴스 y의 이름 공간에 이름 생성\n",
"\n",
"print(y.a)\n",
"print(x.a) # x 인스턴스 공간의 이름 a 확인\n",
"print(S1.a) # 클래스 이름 공간의 a 확인"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"class Simple:\n",
" pass\n",
"\n",
"s1 = Simple()\n",
"s2 = Simple()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1, 2, 3]\n",
"3\n",
"2\n",
"\n",
"[1]\n"
]
},
{
"ename": "AttributeError",
"evalue": "'Simple' object has no attribute 'stack'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32mdef
키워드 사용\n",
" - 일반 함수와 다른 점은 첫번째 인수로 self
사용 (self
라는 이름은 관례적)\n",
" - self
: 인스턴스 객체 자신의 레퍼런스를 지니고 있음\n",
" - 각 인스턴스들은 self
를 이용하여 자신의 이름 공간에 접근 "
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"class MyClass:\n",
" def set(self, v):\n",
" self.value = v\n",
" \n",
" def get(self):\n",
" return self.value"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 인스턴스 객체를 통하여 멤버 메소드를 호출할 때 self
인자는 없다고 생각"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"egg\n",
"egg\n"
]
}
],
"source": [
"c = MyClass() # 인스턴스 생성 \n",
"c.set('egg') # 메소드 set 호출\n",
"print(c.get()) # 메소드 get 호출\n",
"print(c.value) # 인스턴스 변수에 직접 접근"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 위 코드는 실제로 아래 코드와 동일함"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"egg\n",
"egg\n"
]
}
],
"source": [
"c = MyClass() # 인스턴스 생성 \n",
"MyClass.set(c, 'egg')\n",
"print(MyClass.get(c))\n",
"print(c.value)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 멤버 메소드 호출 종류\n",
" - Unbound method call: 클래스 객체를 이용한 메소드 호출\n",
" - 예: MyClass.set(c, 'egg')\n",
" - Bound method call: 인스턴스 객체를 통한 메소드 호출 (self 인자는 호출받은 객체가 자동으로 할당)\n",
" - 예: c.set('egg')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2-2 객체 내부에서의 다른 맴버 메쏘드 호출"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"\n",
"2\n"
]
}
],
"source": [
"class MyClass:\n",
" def set(self, v):\n",
" self.value = v\n",
" \n",
" def incr(self):\n",
" self.set(self.value + 1) # 내부 메소드 호출\n",
"\n",
" def get(self):\n",
" return self.value\n",
" \n",
"c = MyClass()\n",
"c.set(1)\n",
"print(c.get())\n",
"\n",
"print()\n",
"\n",
"c.incr()\n",
"print(c.get())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- [NOTE!!!] 만약 위 코드에서 self.set(self.value + 1)
를 set(self.value + 1)
으로 바꾸면 set
함수를 클래스 외부에서 찾는다. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"\n",
"set function outside function - 2\n",
"1\n"
]
}
],
"source": [
"def set(i):\n",
" print(\"set function outside function - \", i)\n",
" \n",
"class MyClass:\n",
" def set(self, v):\n",
" self.value = v\n",
" \n",
" def incr(self):\n",
" set(self.value + 1) # 클래스 외부에 존재하는 set 메소드 호출\n",
"\n",
" def get(self):\n",
" return self.value\n",
" \n",
"c = MyClass()\n",
"c.set(1)\n",
"print(c.get())\n",
"\n",
"print()\n",
"\n",
"c.incr()\n",
"print(c.get())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2-3 정적 메소드(static method)\n",
"- 정적 메소드: 인스턴스 객체와 무관하게 클래스 이름 공간에 존재하는 메소드로서 클래스 이름을 이용하여 직접 호출할 수 있는 메소드\n",
" - self를 인자로 할당하지 않음\n",
" - [주의] 해당 클래스의 인스턴스를 통해서도 호출 가능\n",
" \n",
"- 장식자(Decorator) @staticmethod
활용 "
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"static method 1 2\n",
"\n",
"static method 1 2\n"
]
}
],
"source": [
"class D:\n",
" @staticmethod\n",
" def spam(x, y): # self가 없다.\n",
" print('static method', x, y)\n",
" \n",
"D.spam(1, 2) # 인스턴스 객체 없이 클래스에서 직접 호출\n",
"\n",
"print()\n",
"d = D()\n",
"d.spam(1, 2) # 인스턴스 객체를 통해서도 호출 가능"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2-4 클래스 메소드(class method)\n",
"- 클래스 메소드: 인스턴스 객체와 무관하게 클래스 이름 공간에 존재하는 메소드로서 클래스 이름을 이용하여 호출하며 ***첫 인수로 클래스 객체를 자동으로 받는 메소드***\n",
" - [주의] 해당 클래스의 인스턴스를 통해서도 호출 가능\n",
"- 장식자(Decorator) @classmethod
활용 "
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"self
인자가 정의되어야 함\n",
" \n",
"- \\_\\_del__: 소멸자 메소드\n",
" - 객체가 소멸 (메모리에서 해제)될 때 자동으로 불리어지는 메소드\n",
" - 일반적으로 객체가 점유하고 있는 메모리나 기타 자원들의 해제하는 코드를 작성함\n",
" - self
인자가 정의되어야 함\n",
" - 개발자가 특별히 작성하지 않아도 될 메소드\n",
" - 이유: 파이썬에서는 객체가 점유하고 있는 메모리나 기타 자원들의 해제가 자동으로 되기 때문에\n",
"- [참고] \\_\\_ (연속된 두 개의 언더라인)의 의미: 예약된 (특수) 이름"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 다음 코드에 대한 설명\n",
" - mylife = Life()
로서 로컬 변수에 할당되는 인스턴스 mylife
가 생성되는 순간 \\_\\_init__ 생성자 메소드 호출\n",
" - sleep(3)
에 의해 3초간 sleep 상태\n",
" - 3초 이후 함수가 리턴됨 --> 로컬 변수, 즉 mylife 객체가 메모리에서 해제됨 --> \\_\\_del__ 소멸자 메소드 호출"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Birthday Wed Nov 28 22:30:18 2018\n",
"Sleeping for 3 sec\n",
"Deathday Wed Nov 28 22:30:21 2018\n"
]
}
],
"source": [
"# _*_ coding:utf-8 _*_\n",
"from time import ctime, sleep\n",
"\n",
"class Life:\n",
" def __init__(self): # 생성자\n",
" self.birth = ctime() # 현재시간에 대한 문자열을 얻는다.\n",
" print('Birthday', self.birth) # 현재 시간 출력\n",
" \n",
" def __del__(self): # 소멸자\n",
" print('Deathday', ctime()) # 소멸 시간 출력 \n",
"\n",
"def test():\n",
" mylife = Life()\n",
" print('Sleeping for 3 sec')\n",
" sleep(3) #3초간 sleep(block)상태에 있음 (즉, 3초간 CPU 점유 못함)\n",
"\n",
"test()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 인자를 받는 생성자 호출 가능\n",
"- [참고] \\_\\_str\\_\\_: print
예약어나 str()
내장함수 호출에 대응되는 메소드"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"self.i:10\n",
"self.i:10\n"
]
}
],
"source": [
"class Integer:\n",
" def __init__(self, i):\n",
" self.i = i\n",
" def __str__(self):\n",
" return \"self.i:\" + str(self.i)\n",
"\n",
"i = Integer(10)\n",
"print(i)\n",
"print(str(i))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.8" } }, "nbformat": 4, "nbformat_minor": 1 }