{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 8. 텍스트와 바이너리 파일" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.1 두 가지 종류의 파일: 텍스트와 바이너리" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images_skill_up/8-1.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images_skill_up/8-2.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 1) 저수준 (low-level) 파일 접근 모드\n", " - 텍스트 모드: 개행 문자가 자동으로 변역되어 개행-캐리지 리턴(\\\\n\\\\r) 쌍을 대체함\n", " - 개행 문자를 지닌 텍스트 파일을 보여줄 때 실제 줄바꿈하여 보여줌 \n", " - 바이너리 모드: 위와 같은 대체 없음\n", " \n", " \n", "- 2) 저장되어지는 데이터 타입 \n", " - 텍스트 모드: 표준 파이썬 문자열 (ASCII/UNICODE) 을 사용하여 읽기/쓰기 수행 \n", " - 바이너리 모드: byte 타입을 사용하여 읽기/쓰기 수행\n", " \n", " \n", "- 3) 숫자 쓰기\n", " - 텍스트 모드: 모든 숫자 데이터는 문자열 타입으로 변환되어 저장됨\n", " - 바이너리 모드: 숫자 그 자체 byte 타입으로 저장됨\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.2 바이너리 파일을 사용하는 경우" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- struct 패키지\n", "- pickle 패키지 (이것만 알아도 됨)\n", "- shelve 패키지" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.3 파일/딕셔너리 시스템" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import os" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 프로세스를 시작, 종료, 반복하는 함수: **spawn, kill, abort, fork**\n", "- 파일/디렉토리 시스템을 변경하거나 탐색하는 함수: **rename, removedirs, chroot, getcwd, rmdir, listdir, makedir, mkdir**\n", "- 파일 플래그와 다른 속성들을 수정하는 함수: **chflags, chmod, chown**\n", "- 환경 변수를 가져오거나 조정하는 함수: **getenv, getenvb, putenv**\n", "- 신규 시스템 명령어를 실행하는 함수: **exec**\n", "- 파일 I/O에 저수준 접근을 하는 함수: **open, read, write**" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/git/supercharged_python\n" ] } ], "source": [ "print(os.getcwd())" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['13. 넘파이 고급 사용법.ipynb', 'assignment2021', 'tables_skill_up', 'python-e-learning', 'stuff.txt', '14. 여러 모듈과 RPN 예시.ipynb', '16. 부록 A_B.ipynb', '09. 클래스와 매직 메서드.ipynb', '.DS_Store', '11. Random과 Math 패키지.ipynb', '18. 부록 D.ipynb', 'r.py', '01. 파이썬 기초 돌아보기.ipynb', '20. 부록 F.예외 다루기.ipynb', 'images', 'example', '19. 부록 E.ipynb', '17. 부록 C.ipynb', 'stock_plot_v2.py', 'team_data.txt', 'images_skill_up', '04. 지름길, 커맨드 라인 그리고 패키지.ipynb', 't_copied.txt', 'rpn.txt', '__pycache__', 'stock_plot_v3.py', '08. 텍스트와 바이너리 파일.ipynb', 'README.md', 't.txt', 'stock_plot_v4.py', '.gitignore', '06. 정규 표현식, 파트 1.ipynb', '15. 인터넷에서 금융 데이터 가져오기.ipynb', 'stock_plot_v1.py', 'readme.txt', '07. 정규 표현식, 파트 2.ipynb', '.ipynb_checkpoints', '05. 정밀하게 텍스트 포매팅하기.ipynb', '.git', 'rpn2.txt', '12. 넘파이 패키지.ipynb', '10. 십진수, 돈 그리고 기타 클래스.ipynb', '03. 고급 리스트 기능.ipynb', '02. 고급 문자열 기능.ipynb', 'stock_demo.py', 'stock_load.py', '.idea'] 47\n" ] } ], "source": [ "print(os.listdir(), len(os.listdir()))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "os.mkdir(\"my_dir\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['13. 넘파이 고급 사용법.ipynb', 'assignment2021', 'tables_skill_up', 'python-e-learning', 'stuff.txt', '14. 여러 모듈과 RPN 예시.ipynb', '16. 부록 A_B.ipynb', '09. 클래스와 매직 메서드.ipynb', '.DS_Store', '11. Random과 Math 패키지.ipynb', '18. 부록 D.ipynb', 'r.py', '01. 파이썬 기초 돌아보기.ipynb', '20. 부록 F.예외 다루기.ipynb', 'images', 'example', '19. 부록 E.ipynb', '17. 부록 C.ipynb', 'stock_plot_v2.py', 'team_data.txt', 'images_skill_up', '04. 지름길, 커맨드 라인 그리고 패키지.ipynb', 't_copied.txt', 'rpn.txt', '__pycache__', 'stock_plot_v3.py', '08. 텍스트와 바이너리 파일.ipynb', 'README.md', 't.txt', 'stock_plot_v4.py', '.gitignore', '06. 정규 표현식, 파트 1.ipynb', '15. 인터넷에서 금융 데이터 가져오기.ipynb', 'stock_plot_v1.py', 'readme.txt', '07. 정규 표현식, 파트 2.ipynb', '.ipynb_checkpoints', '05. 정밀하게 텍스트 포매팅하기.ipynb', '.git', 'rpn2.txt', '12. 넘파이 패키지.ipynb', '10. 십진수, 돈 그리고 기타 클래스.ipynb', '03. 고급 리스트 기능.ipynb', '02. 고급 문자열 기능.ipynb', 'stock_demo.py', 'stock_load.py', 'my_dir', '.idea'] 48\n" ] } ], "source": [ "print(os.listdir(), len(os.listdir()))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(os.path.isfile(\"stock_load.py\"))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "print(os.path.isfile(\"my_dir\"))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "print(os.path.isdir(\"my_dir\"))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "my_dir/sub_dir_1/sub_dir_2\n" ] } ], "source": [ "print(os.path.join(\"my_dir\", \"sub_dir_1\", \"sub_dir_2\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.4\t파일을 열 때 발생하는 예외 다루기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 다양한 파일 처리 모드\n", "\n", "> f = open(fname, 'r')\n", "\n", "- open 내장 함수의 두번째 인자 mode 설명\n", " - 두번째 인자 mode 생략시에는 읽기 전용(r) 모드로 설정\n", "\n", "| Mode | 간단 설명 | 자세한 설명\n", "|--------|-----------------------------|------------|\n", "| 'r' | 읽기 전용(기본 모드) | 파일 객체를 읽기 모드로 생성하고, 파일 포인터를 파일 처음 위치에 놓는다.|\n", "| 'w' | 쓰기 전용(기존 파일 내용 삭제) | 파일이 존재하지 않으면 새로운 파일을 쓰기 모드로 생성하고, 해당 파일이 이미 존재하면 내용을 모두 없에면서 쓰기 모드로 생성하고, 파일 포인터를 파일 처음 위치에 놓는다. |\n", "| 'a' | 파일 끝에 추가(쓰기 전용) | 파일이 존재하지 않으면 새롭게 파일을 생성하면서 쓰기 모드로 생성하고, 해당 파일이 이미 존재하면 파일 객체을 쓰기 모드로 생성하면서 파일 포인터를 파일의 마지막 위치에 놓는다. 따라서, 이후 작성되는 내용은 파일의 뒷 부분에 추가됨.|\n", "| 'r+' | 읽고 쓰기 | 파일 객체를 읽고 쓸 수 있도록 생성한다. 파일 포인터를 파일 처음 위치에 놓는다. |\n", "| 'w+' | 읽고 쓰기(기존 파일 내용 삭제) | 파일 객체를 읽고 쓸 수 있도록 생성한다. 파일이 존재하지 않으면 새로운 파일을 생성하고, 해당 파일이 이미 존재하면 내용을 모두 없에면서 생성하고, 파일 포인터를 파일 처음 위치에 놓는다.|\n", "| 'a+' | 읽고 쓰기(파일 끝에 추가) | 파일 객체를 읽고 쓸 수 있도록 생성한다. 파일이 존재하지 않으면 새롭게 파일을 생성하고, 해당 파일이 이미 존재하면 파일 객체을 생성하면서 파일 포인터를 파일의 마지막 위치에 놓는다 (그래서, 이후 작성되는 내용은 파일의 뒷 부분에 추가). |" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 파이썬 예외 처리 구문\n", "" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Enter file to read:stock_load.py\n", "'''File stock_load.py -----------------------------\n", "\n", "주식 시세(ticker) 기호를 가져오기 위해서 주식 적재 작업을 수행한다.\n", "의존하고 있는 모듈은 없다.\n", "\n", "'''\n", "# pip install pandas_datareader\n", "import pandas_datareader.data as web\n", "def load_stock(ticker_str):\n", " ''' 주식 적재 함수.\n", " 인수로 주어진 문자열 ticker_str의 정보를 적재한다.\n", " 'MSFT'와 같이 정해진 주식의 정보를 pandas 데이터 프레임에 넣고 반환한다.\n", " '''\n", " df = web.DataReader(ticker_str, 'yahoo')\n", " df = df.reset_index()\n", " return df\n", "\n", "# 데이터 프레임(stock_df)을 가져와서 출력한다.\n", "if __name__ == '__main__':\n", " stock_df = load_stock('MSFT') \t# 'msft'를 입력해도 괜찮다.\n", " print(stock_df)\n", " print(stock_df.columns)\n", "\n" ] } ], "source": [ "try:\n", " fname = input('Enter file to read:')\n", " f = open(fname, 'r')\n", " print(f.read())\n", "except FileNotFoundError:\n", " print('File', fname, 'not found. Terminating.')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "while True:\n", " try:\n", " fname = input('Enter file name: ')\n", " if not fname: \t\t\t\t# 빈 문자열이 입력되면 종료한다.\n", " break\n", " f = open(fname) \t\t\t\t# 파일 열기를 시도한다.\n", " print(f.read())\n", " f.close()\n", " break\n", " except FileNotFoundError:\n", " print('File could not be found. Re-enter.')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "while True:\n", " fname = input('Enter file name: ')\n", " if not fname:\n", " break\n", " try:\n", " f = open(fname) \t\t\t\t# 파일 열기를 시도한다.\n", " except FileNotFoundError:\n", " print('File could not be found. Re-enter.')\n", " else:\n", " print(f.read())\n", " f.close()\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.5 'with' 키워드 사용하기\n", "- 파일을 Open한 이후 올바로 닫지 않고, 자원을 해제하지 않은 상태로 갑자기 종료가 되는 상황 발샐 가능\n", " - 파일 I/O를 잘 수행하다가 발생하는 예외 상황" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### with 구문" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "'''File stock_load.py -----------------------------\n", "\n", "주식 시세(ticker) 기호를 가져오기 위해서 주식 적재 작업을 수행한다.\n", "의존하고 있는 모듈은 없다.\n", "\n", "'''\n", "# pip install pandas_datareader\n", "import pandas_datareader.data as web\n", "def load_stock(ticker_str):\n", " ''' 주식 적재 함수.\n", " 인수로 주어진 문자열 ticker_str의 정보를 적재한다.\n", " 'MSFT'와 같이 정해진 주식의 정보를 pandas 데이터 프레임에 넣고 반환한다.\n", " '''\n", " df = web.DataReader(ticker_str, 'yahoo')\n", " df = df.reset_index()\n", " return df\n", "\n", "# 데이터 프레임(stock_df)을 가져와서 출력한다.\n", "if __name__ == '__main__':\n", " stock_df = load_stock('MSFT') \t# 'msft'를 입력해도 괜찮다.\n", " print(stock_df)\n", " print(stock_df.columns)\n" ] } ], "source": [ "with open('stock_load.py', 'r') as f:\n", " lst = f.readlines()\n", " for thing in lst:\n", " print(thing, end='')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.6 읽기/쓰기 연산의 요약" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](tables_skill_up/t0801-1.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](tables_skill_up/t0801-2.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.7 텍스트 파일 작업 상세하게 알아보기" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "To be or not to be\n", "That is the question.\n", "Whether tis nobler in the mind\n", "To suffer the slings and arrows\n", "\n" ] } ], "source": [ "with open('file.txt', 'w') as f:\n", " f.write('To be or not to be\\n')\n", " f.write('That is the question.\\n')\n", " f.write('Whether tis nobler in the mind\\n')\n", " f.write('To suffer the slings and arrows\\n')\n", "\n", "with open('file.txt', 'r') as f:\n", " print(f.read())" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "To be or not to be\n", "\n", "That is the question.\n", "\n", "Whether tis nobler in the mind\n", "\n", "To suffer the slings and arrows\n", "\n", "\n" ] } ], "source": [ "with open('file.txt', 'r') as f:\n", " s = ' ' \t\t\t# 빈 칸으로 초기화한다.\n", " while s:\n", " s = f.readline()\n", " print(s)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "To be or not to be\n", "That is the question.\n", "Whether tis nobler in the mind\n", "To suffer the slings and arrows\n", "\n" ] } ], "source": [ "with open('file.txt', 'r') as f:\n", " s = ' ' \t\t\t# 빈 칸으로 초기화한다.\n", " while s:\n", " s = f.readline()\n", " s = s.rstrip('\\n')\n", " print(s)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "To be or not to be\n", "That is the question.\n", "Whether tis nobler in the mind\n", "To suffer the slings and arrows\n" ] } ], "source": [ "with open('file.txt', 'r') as f:\n", " str_list = f.readlines()\n", " for s in str_list:\n", " print(s, end='')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.8 파일 포인터('seek') 사용하기\n", "- 파일에 대한 순차 접근이 아닌 임의 접근이 필요할 때 사용 (실용적으로는 잘 활용되지 않음)\n", "\n", "> f.seek(pos, orig)\n", "- orig로 지정된 위치를 기준으로 파일 내 임의 접근 위치 pos 로 이동한다.\n", "- orig\n", " - 0: 파일의 시작 지점\n", " - 1: 현재 위치\n", " - 2: 파일의 끝 지점\n", "\n", "> f.tell()\n", "- 파일 처음 시작 부터 계산하여 현재 위치를 반환한다." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "To be\n", "5\n", "********************************************************************************\n", "0\n", "To be\n" ] } ], "source": [ "with open('file.txt', 'r') as f:\n", " print(f.seekable())\n", " print(f.read(5))\n", " print(f.tell())\n", " print(\"*\" * 80)\n", " f.seek(0, 0)\n", " print(f.tell()) \n", " print(f.read(5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.9 RPN 프로젝트 안에서 텍스트 읽기\n", "\n", "### (생략)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.10\t바이너리 직접 읽기/쓰기\n", "- 바이트 타입의 값 생성\n", " - 문자열 바로 앞에 b 접두어 표기\n", " - 문자열 내용에 숫자만 있는 경우 일반적으로 \\\\x와 함께 16진수로 바이트(8비트) 표기" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "with open('my.dat', 'wb') as f:\n", " b = b'\\x01\\x02\\x03\\x0f\\x10\\x1f'\n", " print(type(b))\n", "\n", " f.write(b)\n", " \n", " b = b'hello'\n", " print(type(b))\n", "\n", " f.write(b)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['13. 넘파이 고급 사용법.ipynb', 'assignment2021', 'file.txt', 'tables_skill_up', 'python-e-learning', 'stuff.txt', '14. 여러 모듈과 RPN 예시.ipynb', '16. 부록 A_B.ipynb', '09. 클래스와 매직 메서드.ipynb', '.DS_Store', '11. Random과 Math 패키지.ipynb', '18. 부록 D.ipynb', 'r.py', '01. 파이썬 기초 돌아보기.ipynb', '20. 부록 F.예외 다루기.ipynb', 'images', 'example', '19. 부록 E.ipynb', '17. 부록 C.ipynb', 'stock_plot_v2.py', 'team_data.txt', 'images_skill_up', '04. 지름길, 커맨드 라인 그리고 패키지.ipynb', 't_copied.txt', 'rpn.txt', '__pycache__', 'stock_plot_v3.py', '08. 텍스트와 바이너리 파일.ipynb', 'README.md', 't.txt', 'stock_plot_v4.py', '.gitignore', '06. 정규 표현식, 파트 1.ipynb', '15. 인터넷에서 금융 데이터 가져오기.ipynb', 'stock_plot_v1.py', 'readme.txt', '07. 정규 표현식, 파트 2.ipynb', '.ipynb_checkpoints', '05. 정밀하게 텍스트 포매팅하기.ipynb', '.git', 'rpn2.txt', '12. 넘파이 패키지.ipynb', '10. 십진수, 돈 그리고 기타 클래스.ipynb', '03. 고급 리스트 기능.ipynb', '02. 고급 문자열 기능.ipynb', 'stock_demo.py', 'stock_load.py', 'my_dir', 'my.dat', '.idea']\n" ] } ], "source": [ "print(os.listdir())" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 11\n", "1 2 3 15 16 31 104 101 108 108 111 " ] } ], "source": [ "with open('my.dat', 'rb') as f:\n", " bss = f.read()\n", " print(type(bss), len(bss))\n", " for i in bss:\n", " print(i, end=' ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 바이너리 데이터를 저수준 (low-level)으로 직접 쓰고 읽는 작업은 잘 하지 않는다.\n", "### 대신 다음과 같은 고수준 (high-level) 방식으로 쓰고 읽는다.\n", "#### 1. struct 패키지 사용\n", "#### 2. pickle 패키지 사용 (가장 많이 이용하는 패키지) \n", "#### 3. shelve 패키지 사용" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.11 데이터를 고정-길이 필드로 변환하기 (struct)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### (생략)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.12 피클링 패키지 사용하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images_skill_up/8-3.PNG)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import pickle\n", "\n", "with open('goo.dat', 'wb') as f:\n", " pickle.dump([1, 2, 3], f)\n", " pickle.dump('Hello!', f)\n", " pickle.dump(3.141592, f)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " [1, 2, 3]\n", " Hello!\n", " 3.141592\n" ] } ], "source": [ "with open('goo.dat', 'rb') as f:\n", " a = pickle.load(f)\n", " b = pickle.load(f)\n", " c = pickle.load(f)\n", " print(type(a), a)\n", " print(type(b), b)\n", " print(type(c), c)" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The length of a is 3\n" ] } ], "source": [ "if type(a) == list:\n", " print('The length of a is {0}'.format(len(a)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- pickle의 유일한 단점: pickle로 여러 객체를 저장(dump)한 파일 내에 얼마나 많은 객체가 있는지 직접 확인할 수 없음\n", " - load 를 여러번 호출하여 객체를 가져오다 보면 더 이상 객체를 가져올 수 없을 때 --> **EOFError 예외 발생**" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " [1, 2, 3]\n", " Hello!\n", " 3.141592\n", "Loaded 3 items.\n" ] } ], "source": [ "loaded = []\n", "with open('goo.dat', 'rb') as f:\n", " while True:\n", " try:\n", " item = pickle.load(f)\n", " except EOFError:\n", " print('Loaded', len(loaded), 'items.')\n", " break\n", " print(type(item), item)\n", " loaded.append(item)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 8.13 shelve 패키지 사용하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(생략)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "***\n", "## [추가 내용] 파일과 디렉토리 다루기\n", "***\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "### 파일 다루기\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1-1 파일 목록 얻기\n", "- os.listdir('경로')\n", " - 디렉토리 안에 들어 있는 각 파일 목록 반환" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['13. 넘파이 고급 사용법.ipynb', 'assignment2021', 'file.txt', 'tables_skill_up', 'python-e-learning', 'stuff.txt', '14. 여러 모듈과 RPN 예시.ipynb', '16. 부록 A_B.ipynb', '09. 클래스와 매직 메서드.ipynb', '.DS_Store', '11. Random과 Math 패키지.ipynb', '18. 부록 D.ipynb', 'r.py', '01. 파이썬 기초 돌아보기.ipynb', '20. 부록 F.예외 다루기.ipynb', 'images', 'example', '19. 부록 E.ipynb', '17. 부록 C.ipynb', 'stock_plot_v2.py', 'team_data.txt', 'images_skill_up', '04. 지름길, 커맨드 라인 그리고 패키지.ipynb', 't_copied.txt', 'rpn.txt', '__pycache__', 'stock_plot_v3.py', '08. 텍스트와 바이너리 파일.ipynb', 'README.md', 't.txt', 'stock_plot_v4.py', '.gitignore', '06. 정규 표현식, 파트 1.ipynb', '15. 인터넷에서 금융 데이터 가져오기.ipynb', 'stock_plot_v1.py', 'goo.dat', 'readme.txt', '07. 정규 표현식, 파트 2.ipynb', '.ipynb_checkpoints', '05. 정밀하게 텍스트 포매팅하기.ipynb', '.git', 'rpn2.txt', '12. 넘파이 패키지.ipynb', '10. 십진수, 돈 그리고 기타 클래스.ipynb', '03. 고급 리스트 기능.ipynb', '02. 고급 문자열 기능.ipynb', 'stock_demo.py', 'stock_load.py', 'my_dir', 'my.dat', '.idea']\n", "\n", "['unity', 'python-e-learning', 'hands_on_ml_link', 'deeplink_public', 'crypto', 'auto_trading', 'web-apps-node-iot-hub-data-visualization.zip', 'rl_sortation', '.DS_Store', 'CsvReader.py', 'e_learning_rl_old', 'pwd', 'link_home', 'manuscriptlink', 'introduction_to_ml_with_python', 'ccxt', 'papers', '4thIR', 'out', 'starcraft2', 'trade', 'mxnet', 'gym-minigrid', 'test_world', 'web-old', 'link_rl_book_codes', 'supercharged_python', 'link_marl', 'link_rl', 'trade_rl', 'e_learning_rl', 'flask_rest', 'link_rl_book', 'auto_trading_old', 'tf_15', 'betcentrality', 'openshs', 'DeepRL', 'SparceReward', 'crawl', 'rotary_pendulum', '.gitignore', 'd2l-en', 'web-apps-node-iot-hub-data-visualization', 'link_vne', 'link_rl_book_old_latex_with_codes', 'paper_writings', 'VirtualDevice.py', '.git', 'or', 'journalhome', 'minimal_rl', 'ktccs-ktsde-website', 'etri-ksb', 'deeplink', 'rl', 'invest', 'upbit_auto_trade']\n" ] } ], "source": [ "import os\n", "\n", "print(os.listdir('.')) # 현재 디렉토리의 파일 목록 얻기\n", "print()\n", "\n", "print(os.listdir('../')) # 현재 디렉토리의 부모 디렉토리의 파일 목록 얻기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1-2 파일 종류 알아보기\n", "- os.path 모듈의 다음 함수들은 파일의 종류를 판단하여 True 또는 False를 반환한다.\n", " - isfile(filepath)\n", " - 순수 파일이면 True\n", " - isdir(filepath)\n", " - 디렉토리이면 True\n", " - islink(filepath)\n", " - 심볼릭링크이면 True" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "13. 넘파이 고급 사용법.ipynb :Regular file\n", "assignment2021 :Directory\n", "file.txt :Regular file\n", "tables_skill_up :Directory\n", "python-e-learning :Directory\n", "stuff.txt :Regular file\n", "14. 여러 모듈과 RPN 예시.ipynb :Regular file\n", "16. 부록 A_B.ipynb :Regular file\n", "09. 클래스와 매직 메서드.ipynb :Regular file\n", ".DS_Store :Regular file\n", "11. Random과 Math 패키지.ipynb :Regular file\n", "18. 부록 D.ipynb :Regular file\n", "r.py :Regular file\n", "01. 파이썬 기초 돌아보기.ipynb :Regular file\n", "20. 부록 F.예외 다루기.ipynb :Regular file\n", "images :Directory\n", "example :Directory\n", "19. 부록 E.ipynb :Regular file\n", "17. 부록 C.ipynb :Regular file\n", "stock_plot_v2.py :Regular file\n", "team_data.txt :Regular file\n", "images_skill_up :Directory\n", "04. 지름길, 커맨드 라인 그리고 패키지.ipynb :Regular file\n", "t_copied.txt :Regular file\n", "rpn.txt :Regular file\n", "__pycache__ :Directory\n", "stock_plot_v3.py :Regular file\n", "08. 텍스트와 바이너리 파일.ipynb :Regular file\n", "README.md :Regular file\n", "t.txt :Regular file\n", "stock_plot_v4.py :Regular file\n", ".gitignore :Regular file\n", "06. 정규 표현식, 파트 1.ipynb :Regular file\n", "15. 인터넷에서 금융 데이터 가져오기.ipynb :Regular file\n", "stock_plot_v1.py :Regular file\n", "goo.dat :Regular file\n", "readme.txt :Regular file\n", "07. 정규 표현식, 파트 2.ipynb :Regular file\n", ".ipynb_checkpoints :Directory\n", "05. 정밀하게 텍스트 포매팅하기.ipynb :Regular file\n", ".git :Directory\n", "rpn2.txt :Regular file\n", "12. 넘파이 패키지.ipynb :Regular file\n", "10. 십진수, 돈 그리고 기타 클래스.ipynb :Regular file\n", "03. 고급 리스트 기능.ipynb :Regular file\n", "02. 고급 문자열 기능.ipynb :Regular file\n", "stock_demo.py :Regular file\n", "stock_load.py :Regular file\n", "my_dir :Directory\n", "my.dat :Regular file\n", ".idea :Directory\n" ] } ], "source": [ "import os\n", "def filetype(fpath):\n", " print(fpath, ':', end=\"\")\n", "\n", " if os.path.isfile(fpath):\n", " print('Regular file')\n", "\n", " if os.path.isdir(fpath):\n", " print('Directory')\n", "\n", " if os.path.islink(fpath):\n", " print('Symbolic link')\n", "\n", "flist = os.listdir('.')\n", "for fname in flist:\n", " filetype(fname)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1-3 파일 조작하기\n", "#### 1) 파일 이름 변경하기\n", "- os.rename(old_filepath, new_filepath)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "s = \"\"\"Its power: Python developers typically report\n", "they are able to develop applications in a half\n", "to a tenth the amount of time it takes them to do\n", "the same work in such languages as C.\"\"\"\n", "\n", "with open('t.txt', 'w') as f:\n", " f.write(s) # 문자열을 파일에 기록" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import os\n", "os.rename('t.txt', 't1.txt') # t.txt를 t1.txt로 바꾼다" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2) 파일 이동하기\n", "- os.rename(old_filepath, new_filepath)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "os.mkdir('example')" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "os.rename('t1.txt', './example/t1.txt') # 현재 작업 디렉토리의 t1.txt를 example에 t1.txt이름으로 옮긴다." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3) 파일 복사하기\n", "- shutil 모듈 활용\n", "- shutil.copyfile(src_filepath, dest_filepath)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "data": { "text/plain": [ "'t_copied.txt'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import shutil\n", "\n", "s = \"\"\"Its power: Python developers typically report\n", "they are able to develop applications in a half\n", "to a tenth the amount of time it takes them to do\n", "the same work in such languages as C.\"\"\"\n", "\n", "with open('t.txt', 'w') as f:\n", " f.write(s) # 문자열을 파일에 기록\n", " \n", "shutil.copyfile('t.txt', 't_copied.txt')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1-4 파일 이름 다루기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1) 상대 경로를 절대 경로로 변환하기 [중요]\n", "- os.path.abspath(상대경로)\n", " - 실제 파일 존재와는 무관하게 절대경로로 변경함" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/git/supercharged_python/o.txt\n" ] } ], "source": [ "import os\n", "print(os.path.abspath('o.txt'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2) 주어진 경로의 파일이 존재하는지 확인 [중요]\n", "- os.path.exists(filepath)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "False\n", "False\n" ] } ], "source": [ "f = '/Users/yhhan/git/python-e-learning/sample.txt'\n", "print(os.path.exists(f))\n", "print(os.path.exists('sample.txt'))\n", "print(os.path.exists('asdf.txt'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3) 현재/부모 디렉토리를 가리키는 이름 얻기" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ".\n", "..\n" ] } ], "source": [ "print(os.curdir) #현재 디렉토리\n", "print(os.pardir) #부모 디렉토리" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 4) 디렉토리 분리 문자 얻기" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/\n" ] } ], "source": [ "print(os.sep)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1-5 경로명 분리하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1) 경로와 파일명으로 분리" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t.txt\n", "/Users/yhhan/git/python-e-learning\n" ] } ], "source": [ "f = '/Users/yhhan/git/python-e-learning/t.txt'\n", "\n", "print(os.path.basename(f)) # 파일명만 추출\n", "print(os.path.dirname(f)) # 디렉토리 경로 추출" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2) 경로명과 파일명을 한번에 분리" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('/Users/yhhan/git/python-e-learning', 't.txt')\n" ] } ], "source": [ "print(os.path.split(f))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3) MS 윈도우즈에서 드라이브명과 파일 경로명을 분리" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('', '/Users/yhhan/git/python-e-learning/t.txt')\n" ] } ], "source": [ "print(os.path.splitdrive(f))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 4) 확장자 분리" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('/Users/yhhan/git/python-e-learning/t', '.txt')\n" ] } ], "source": [ "print(os.path.splitext(f))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1-6 경로명 생성하기 [중요]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Linux and Mac" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/git/python-e-learning/t.txt\n" ] } ], "source": [ "path = os.path.join(\"/\", \"Users\", \"yhhan\", \"git\", \"python-e-learning\", \"t.txt\")\n", "print(path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Windows" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "c:\\/Users/yhhan\n" ] } ], "source": [ "path = os.path.join(\"c:\\\\\", \"Users\", \"yhhan\")\n", "print(path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "### 디렉토리 다루기\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2-1 디렉토리에 관련된 일반 작업" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1) 현재 작업 디렉토리 알아보기" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/git/supercharged_python\n" ] } ], "source": [ "import os\n", "print(os.getcwd())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2) 작업 디렉토리 변경하기" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/Public\n" ] } ], "source": [ "path = os.path.join(\"/\", \"Users\", \"yhhan\", \"Public\")\n", "#path = os.path.join(\"c:\\\\\", \"Users\", \"yhhan\", \"Public\")\n", "\n", "os.chdir(path)\n", "print(os.getcwd())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3) 디렉토리 만들기" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "ename": "FileExistsError", "evalue": "[Errno 17] File exists: 'temp_new'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mFileExistsError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmkdir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'temp_new'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 0755 기본 모드(rwxr-xr-x)로 만들어짐\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mget_ipython\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_line_magic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'ls'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'-al temp_new'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mFileExistsError\u001b[0m: [Errno 17] File exists: 'temp_new'" ] } ], "source": [ "import os\n", "\n", "os.mkdir('temp_new') # 0755 기본 모드(rwxr-xr-x)로 만들어짐\n", "\n", "%ls -al temp_new\n", "# os.mkdir('temp2', 0700) # 0700 모드(rwx------)로 만들어짐\n", "\n", "\n", "os.mkdir('temp_new_2', 0o700)\n", "os.makedirs('temp_new_2/level1/level2') #0755 기본 모드, 중간에 필요한 디렉토리도 모두생성" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [], "source": [ "import os\n", "\n", "os.mkdir('temp3', 0o700)\n", "\n", "path = os.path.join(\"temp3\", \"level1\", \"level2\")\n", "os.makedirs(path) #0755 기본 모드, 중간에 필요한 디렉토리도 모두생성" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 4) 디렉토리 삭제" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "ename": "OSError", "evalue": "[Errno 66] Directory not empty: 'temp'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mOSError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrmdir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'temp'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#디렉토리에 내용이 없을 때 삭제가능\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mOSError\u001b[0m: [Errno 66] Directory not empty: 'temp'" ] } ], "source": [ "os.rmdir('temp') #디렉토리에 내용이 없을 때 삭제가능" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "ename": "OSError", "evalue": "[Errno 66] Directory not empty: 'temp3'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mOSError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrmdir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'temp3'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#디렉토리에 다른 파일이 있으면 삭제할 수 없음\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mOSError\u001b[0m: [Errno 66] Directory not empty: 'temp3'" ] } ], "source": [ "os.rmdir('temp3') #디렉토리에 다른 파일이 있으면 삭제할 수 없음" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 5) 다단계 디렉토리 삭제\n", "- os.removedirs(filepath)\n", " - filepath에 지정된 디렉토리들 중 맨 오른쪽 디렉토리 부터 차례차례로 삭제한다.\n", " - 디렉토리에 다른 파일이 있으면 삭제하기 않고 중단" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "pycharm": { "name": "#%%\n" } }, "outputs": [ { "ename": "FileNotFoundError", "evalue": "[Errno 2] No such file or directory: 'temp2/level1/level2'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mFileNotFoundError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mremovedirs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'temp2/level1/level2'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/anaconda3/lib/python3.6/os.py\u001b[0m in \u001b[0;36mremovedirs\u001b[0;34m(name)\u001b[0m\n\u001b[1;32m 236\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 237\u001b[0m \"\"\"\n\u001b[0;32m--> 238\u001b[0;31m \u001b[0mrmdir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 239\u001b[0m \u001b[0mhead\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtail\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 240\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mtail\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'temp2/level1/level2'" ] } ], "source": [ "os.removedirs('temp2/level1/level2')" ] } ], "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": 4 }