├── requirements.txt ├── .gitattributes ├── preprocess_test.py ├── test_data ├── test2.gold.txt ├── test3.gold.txt ├── test3.json ├── test1.gold.txt ├── test2.json ├── test6.gold.txt ├── test1.json ├── test5.gold.txt ├── test5.json ├── test4.gold.txt └── test4.json ├── .gitignore ├── README.md └── preprocess.py /requirements.txt: -------------------------------------------------------------------------------- 1 | absl-py 2 | kss 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /preprocess_test.py: -------------------------------------------------------------------------------- 1 | import os 2 | import glob 3 | import json 4 | from absl.testing import absltest 5 | 6 | from preprocess import preprocess 7 | 8 | 9 | class UnitTests(absltest.TestCase): 10 | def test_preprocess_test(self): 11 | for filename in [os.path.splitext(os.path.basename(f))[0] for f in glob.glob("test_data/*.json")]: 12 | with open(os.path.join("test_data", f"{filename}.json")) as f: 13 | obj = json.load(f) 14 | with open(os.path.join("test_data", f"{filename}.gold.txt")) as f: 15 | gold = f.read() 16 | 17 | preprocessed = [doc for doc in preprocess(obj)] 18 | self.assertEqual("\n".join(preprocessed), gold) 19 | 20 | 21 | if __name__ == '__main__': 22 | absltest.main() 23 | -------------------------------------------------------------------------------- /test_data/test2.gold.txt: -------------------------------------------------------------------------------- 1 | % - 개요 2 | 백분율 기호며 퍼센트 기호라고도 한다. 3 | 유니코드는 U+0025이다. 4 | URL은 라틴 문자, 숫자, -, _ 등을 제외한 문자는 이스케이프해야 올바른 주소라는 것을 보장한다. 5 | URL escape code 참조. 어째서인지 \을 치면 %이 나오며 \\이라고 두 번 치면 \이 나온다. 6 | 두벌식 키보드 기준으로 Shift + 5로 입력이 가능하다. 7 | 세벌식 390 키보드는 두벌식 키보드와 동일하게 Shift + 5로 입력할 수 있으며, 세벌식 최종 키보드에서는 Shift + 로 입력한다. 8 | 전산에서는 정수의 나머지 연산 기호로 쓰이기도 한다. 9 | 13%3이라고 하면 13을 3으로 나눈 나머지인 1을 출력하는 식. 10 | 여담이지만 던전 앤 파이터에서는 입력할 수 없다. 11 | 정확히는 아이템 텍스트로는 가능한데, 유저가 채팅으로 칠 수는 없다. 12 | 13 | % - 역사 14 | 이 기호는 '100에 대하기'라는 의미의 이탈리아어 'per cento'의 축약형인 'P cento'에서 발전한 것이다. 15 | 15세기의 퍼센트 기호. 16 | 17세기의 퍼센트 기호. 17 | 현재의 퍼센트 기호. 18 | 15세기에는 'P'를 눕히고 그 밑에 'cento'를 작게 쓰는 모양으로 했는데, 이게 쓰기가 귀찮고 작은 글씨로 쓰기도 어렵다 보니까 17세기에 와서 밑의 'cento'를 '-o'로 축약해서 쓰게 되었고, 여기서 모양이 더 달라진 게 현재의 '%'이다. 19 | 20 | % - 기타 21 | '%'가 '응'을 옆으로 살짝 기울인 것처럼 보여서 '응'으로도 불리며, 야민정음과 비슷한 맥락. 22 | Apink의 미니앨범 8집인 PERCENT의 타이틀곡이 %%(응응)이다. 23 | -------------------------------------------------------------------------------- /test_data/test3.gold.txt: -------------------------------------------------------------------------------- 1 | 013 특수부대 - 개요 2 | 슈퍼로봇대전 Z 스페셜 디스크에서 나오는 특수부대. 등장 자체는 슈퍼로봇대전 Z 본편부터였지만, 당시에는 팬텀 페인과 호랑나비 부대, 두 부대로 각각 나뉘어서 등장하며, 013 특수부대란 명칭은 스페셜 디스크에서 붙여졌다. 3 | 4 | 013 특수부대 - 목적 5 | 표면적인 목적은 제우스에 대항 및 아사킴 드윈의 슈로우가 추적 및 노획 목적으로 신 지구연방이 각군의 에이스들을 뽑아다가 만든 특수부대로 등장한다. 6 | 허나 실제 목적은 흑의 카리스마가 자신이 만든 레므레스 시작형을 시험해보기 위해서 제우스와 비슷한 부대를 만든 것, 다시 말해 레므레스 시작형의 테스트 상대. 쉽게 말해 실제 창설자는 흑의 카리스마. 7 | 8 | 013 특수부대 - 구성원 9 | 기함: 이즈모 - 함장: 유르겐스 10 | 지휘관: 네오 로아노크 11 | 부장: 브란 브루타크 12 | 참모: 도미니크 소렐 (이즈모의 서브 파일럿으로 나온다.) 13 | 익스텐디드 휴먼: 스팅 오클레이, 아울 니더, 스텔라 루셰 14 | 제리드 메사 15 | 마우아 파라오 16 | 카크리콘 카크라 17 | 포우 무라사메 18 | 로자미아 바탐 19 | 프로스트 형제 - 샤기아 프로스트, 올바 프로스트 20 | 키드 호라, 게라바 게라바 21 | 팀프 샤론 22 | 아네모네 23 | 아스함 분 24 | 케지난, 엥게, 자보리 25 | 잭키 브롱코(시베리아 철도 대원) 26 | 신시아 렌 27 | 제이슨 벡 28 | 레벤 게네랄 29 | 슈란 오펠 30 | 31 | 013 특수부대 - 특징 32 | 지구의 최강급 세력들이 결집해서 만든 신 지구연방의 특수부대인 만큼 최신예 MS와 MA를 팍팍 지원받으며 보급도 빵빵하다. 33 | 여기서의 특징은 이상하리만치 가족적(…)이라는 것. 34 | 지휘관들은 출신을 떠나 성실하고, 포우와 로자미아는 스텔라를 동생처럼 돌보고, 스팅은 적인 카미유 비단과 포우의 데이트를 주선하고, 심지어 도망가라고까지 한다. 35 | 뭐냐 이 따뜻한 분위기는…. 36 | 그런 와중에도 유일의 예외로 프로스트 형제는 소속되기만 할 뿐 자신들 이외의 인간을 신뢰하지 않는 그들의 특성상 그 둘만 따로 노는 듯한 모습이다. 37 | 역시 변태형제. 38 | 39 | 013 특수부대 - 행적 40 | 마지막에 아사킴 드윈을 계속 추적하다가 갑자기 흑의 카리스마가 레므레스 시작형을 끌고 공격해오지만 의외로 역관광을 당해 레므레스 시작형이 박살이 나버리자 흑의 카리스마는 이때의 패전을 교훈삼아 레므레스를 강화하게 되는 계기가 된다. 41 | 레므레스 시작형이 파괴된 이후로는 목적을 달성했으므로 해산. 42 | -------------------------------------------------------------------------------- /test_data/test3.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": 0, 3 | "title": "013 특수부대", 4 | "text": "[목차]\n== 개요 ==\n[[슈퍼로봇대전 Z]] 스페셜 디스크에서 나오는 특수부대. 등장 자체는 슈퍼로봇대전 Z 본편부터였지만, 당시에는 [[팬텀 페인(기동전사 건담 SEED)|팬텀 페인]]과 호랑나비 부대, 두 부대로 각각 나뉘어서 등장하며, 013 특수부대란 명칭은 스페셜 디스크에서 붙여졌다.\n\n== 목적 ==\n표면적인 목적은 [[제우스]]에 대항 및 [[아사킴 드윈]]의 [[슈로우가]] 추적 및 노획 목적으로 [[신 지구연방]]이 각군의 에이스들을 뽑아다가 만든 특수부대로 등장한다. 허나 실제 목적은 [[흑의 카리스마]]가 자신이 만든 [[레므레스 시작형]]을 시험해보기 위해서 제우스와 비슷한 부대를 만든 것, 다시 말해 레므레스 시작형의 테스트 상대. 쉽게 말해 실제 창설자는 흑의 카리스마.\n\n== 구성원 ==\n * 기함: [[이즈모]] - 함장: [[유르겐스 함장|유르겐스]]\n * 지휘관: [[네오 로아노크]]\n * 부장: [[브란 브루타크]]\n * 참모: [[도미니크 소렐]] (이즈모의 서브 파일럿으로 나온다.)\n * [[익스텐디드 휴먼]]: [[스팅 오클레이]], [[아울 니더]], [[스텔라 루셰]]\n * [[제리드 메사]]\n * [[마우아 파라오]]\n * [[카크리콘 카크라]]\n * [[포우 무라사메]]\n * [[로자미아 바탐]]\n * [[프로스트 형제]] - [[샤기아 프로스트]], [[올바 프로스트]]\n * [[키드 호라]], 게라바 게라바\n * [[팀프 샤론]]\n * [[아네모네(교향시편 에우레카 세븐)|아네모네]]\n * [[아스함 분]]\n * [[케지난, 엥게, 자보리]]\n * 잭키 브롱코(시베리아 철도 대원)\n * [[신시아 렌]]\n * [[제이슨 벡]]\n * [[레벤 게네랄]]\n * [[슈란 오펠]]\n== 특징 ==\n지구의 최강급 세력들이 결집해서 만든 신 지구연방의 특수부대인 만큼 최신예 MS와 MA를 팍팍 지원받으며 보급도 빵빵하다.\n\n여기서의 특징은 이상하리만치 가족적(…)이라는 것. 지휘관들은 출신을 떠나 성실하고, 포우와 로자미아는 스텔라를 동생처럼 돌보고, 스팅은 적인 [[카미유 비단]]과 포우의 데이트를 주선하고, 심지어 도망가라고까지 한다. 뭐냐 이 따뜻한 분위기는…. \n\n그런 와중에도 유일의 예외로 [[프로스트 형제]]는 소속되기만 할 뿐 자신들 이외의 인간을 신뢰하지 않는 그들의 특성상 그 둘만 따로 노는 듯한 모습이다. 역시 '''변태형제'''.\n\n== 행적 ==\n마지막에 아사킴 드윈을 계속 추적하다가 갑자기 흑의 카리스마가 레므레스 시작형을 끌고 공격해오지만 의외로 역관광을 당해 레므레스 시작형이 박살이 나버리자 흑의 카리스마는 이때의 패전을 교훈삼아 레므레스를 강화하게 되는 계기가 된다. 레므레스 시작형이 파괴된 이후로는 목적을 달성했으므로[* 표면상으로는 슈로우가 노획을 성공했다고 발표하고 해산. 실제로는 검은 카리스마가 레므레스 시작형을 충분히 시험해봤으므로 해산.] 해산.\n[[분류:슈퍼로봇대전 시리즈]]", 5 | "contributors": [ 6 | "121.141.110.115", 7 | "lliilili", 8 | "115.93.198.117", 9 | "kjk6206", 10 | "satellite", 11 | "115.23.242.16", 12 | "kiwitree2", 13 | "namubot", 14 | "wmy1201" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /test_data/test1.gold.txt: -------------------------------------------------------------------------------- 1 | “……” - 개요 2 | 개그콘서트의 전 코너. 진짜로 코너 이름이 “……”이다. 3 | 언론에서는 이 코너를 언급할 때 '점점점' 또는 '점점점점점점'이라는 표현을 사용했다. 4 | 코너명의 유래는 흔히 쓰이는 말줄임표. 5 | 남자친구(남궁경호)와 여자친구(김희원)의 아버지(유민상) 간의 어색함을 다룬 코미디. 6 | 초창기엔 당시 조연을 맡았던 송필근보다 남궁경호의 비중이 높았으나, 6화부터 송필근이 남궁경호의 아버지 역(유민상과 사돈관계)으로 고정되면서 남궁경호의 비중은 줄어들었다. 7 | 심지어 아예 등장이 없는 회차도 간간이 나오게 되어, 사실상 유민상과 송필근의 투톱 체제가 된 코너. 8 | 송필근의 역할변경 후로는 주로 사돈 간의 어색함을 다루고 있다. 9 | 주된 패턴은 3,4명에서 시작해 누군가 자리를 비우면, 남은 2명은 어색함에 조용해하고 중간중간 어색함을 깨보려는 대사에도 계속되는 어색한 분위기가 주된 패턴. 침묵이 계속되면 자리마다 있는 괘종시계가 째깍째깍 울리는 것이 웃음 포인트다. 10 | 유민상이 사돈어른(송필근)이 오기 전 집안의 괘종시계를 미리 치워버린 에피소드도 있었는데, 사돈어른이 선물로 벽시계를 사오는 바람에 어색한 상황에서 째깍째깍 소리가 나게 되었다. 11 | 만약 제 3자(송필근)의 등장으로 남자친구가 자리를 비우면, 제3자와 아버지 간의 분위기가 어색해진다. 12 | 김희원은 코너 유일의 붙임성 있는 성격이지만, 눈치가 없는지라 말을 꺼내도 더 어색해진다. 13 | 코너 자체의 어색한 침묵이라는 주제 때문인지, 대화가 적은 현대사회의 모습을 은유한 것이라는 의견도 있다. 14 | 15 | “……” - 상세 16 | 7화(2013년 7월 14일 방송분)에서는 사돈어른이 2PM 춤 추다가 입원해서 놀림당했는데 건너편에 미라처럼 깁스를 하고 있던 유인석이 한 손을 뻗어 심장박동을 시전했다. 17 | 그리고 아빠와 딸이 모두 박X스를 한 박스씩 사왔는데, 병실 장롱에 박X스가 한가득 들어있었다. 18 | 유민상이 병문안 때는 박X스를 사가는 것이 좋다고 생각했는데, 알고보니 전에 병문안 왔던 사람들도 같은 생각을 했던 것. 19 | 9화(2013년 7월 28일 방송분)에서는 송필근이 김희원의 오빠 역할로 나왔다. 20 | 경호-희원 커플이 유민상 몰래 괌에 갔다온 것이 들통나면서 남궁경호가 괌을 "대전 구암(Guam)"이라고 말하니까 유민상의 드립이"난 몽둥이 구함~" 21 | 회가 거듭하면 거듭할수록 커플의 진도가 쭉쭉 잘 나가서 김희원이 배꼽티도 자랑했고, 11화(2013년 8월 25일 방송분)에서는 김희원이 웨딩드레스를 맞췄다. 22 | 14화(2013년 9월 15일 방송분)에서는 송필근이 사돈 유민상의 아버지 희수연을 기념하고자 화환을 보냈는데, 문제는 유민상 아버지의 본명이 유죽방이라 본인이 그 이름을 매우 싫어했다는 것. 23 | 그래서 현수막은 "유 할아버지"라고 걸려 있었다. 24 | 하지만 송필근이 그 사실을 몰랐기 때문에 하필 예식장에 그 이름 석자가 크게 적힌 화환이 배달되었으며, 뒤늦게 상황을 수습한답시고 글자를 어떻게 가려보려고 애를 썼는데, 마지막 글자를 가린 '유죽'도 이상해서 안 됐고, 이어 가운데 글자를 가린 것은 더 큰일나는 이름인 바람에... 유민상의 아버지로는 김재욱이 나왔다. 25 | 또한 딸 김희원이 아버지 유민상께 건강팔찌를 주고, 남자친구에겐 금팔찌를 주자 상황이 쎄해졌다. 26 | 김희원이 "이거 한 돈도 안돼!"라고 무마하려 하지만 유민상은 "이거는 돈이 안되고."라고 말한다. 27 | 15화(2013년 9월 22일 방송분)에서는 정태호가 너훈아 역할로 출연했다. 28 | 마지막화인 17화(2013년 10월 13일 방송분)에서는 박은영이 유민상과 송필근이 건강검진을 받으러 간 병원의 간호사 역할로 나왔다. 29 | 극중에서 부자관계로 나오는 27기 남궁경호와 송필근은 동갑이자 성남예고, 인덕대학 동기로 둘 다 91년 생이다. 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .nox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | db.sqlite3 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # IPython 77 | profile_default/ 78 | ipython_config.py 79 | 80 | # pyenv 81 | .python-version 82 | 83 | # celery beat schedule file 84 | celerybeat-schedule 85 | 86 | # SageMath parsed files 87 | *.sage.py 88 | 89 | # Environments 90 | .env 91 | .venv 92 | env/ 93 | venv/ 94 | ENV/ 95 | env.bak/ 96 | venv.bak/ 97 | 98 | # Spyder project settings 99 | .spyderproject 100 | .spyproject 101 | 102 | # Rope project settings 103 | .ropeproject 104 | 105 | # mkdocs documentation 106 | /site 107 | 108 | # mypy 109 | .mypy_cache/ 110 | .dmypy.json 111 | dmypy.json 112 | 113 | # Pyre type checker 114 | .pyre/ 115 | 116 | # 덤프 파일 117 | /namuwiki21* 118 | /corpus 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Namuwiki corpus 2 | 3 | 문장단위로 미리 분절된 나무위키 코퍼스. 4 | 5 | 목적이 LM등에서 사용하기 위한 데이터셋이라, 링크/이미지/테이블 등등이 잘려있습니다. 6 | 7 | 문장 단위 분절은 kss를 활용하였습니다. 8 | 9 | 라이선스는 나무위키에 명시된 바와 같이 [CC BY-NC-SA 2.0 KR](https://creativecommons.org/licenses/by-nc-sa/2.0/kr/)에 따라 이용할 수 있습니다. 10 | 11 | ## 사용법 12 | 13 | Releases에서 직접 다운로드받은 후 사용하시거나, [tfds-korean 패키지](https://github.com/jeongukjae/tfds-korean)([카탈로그 페이지](https://jeongukjae.github.io/tfds-korean/datasets/namuwiki_corpus.html))를 이용해 사용하세요. 14 | 15 | ## 포맷 16 | 17 | ```text 18 | 문서1 19 | 문장1 20 | 문장2 21 | 문장3 22 | 23 | 문서1 - 제목1 24 | 문장1 25 | 문장2 26 | 문장3 27 | 28 | 문서1 - 제목1 - 하위 제목1 29 | 문장1 30 | 문장2 31 | 문장3 32 | 33 | ... 34 | ``` 35 | 36 | 예시 37 | 38 | ```text 39 | 나성범 - 플레이 스타일 - 주루 40 | 2015 시즌 20-20 클럽에 가입한 경력을 갖고 있는 준족으로, 슬럼프를 겪었던 2016년과 부상으로 일찌감치 시즌을 마감한 2019년을 제외하고는 데뷔 이래 매년 두 자릿수의 도루를 기록했다. 41 | 상당한 거구의 사나이지만 팀 동료이자 리그를 대표하는 리드오프인 박민우보다도 순수 주력이 빠르다. 42 | 중심타선에 배치되는 타자임에도 어느 타구든지 가리지 않고 1루를 향해 전력질주를 하며, 이러한 플레이 덕분에 내야안타도 많이 생산해낸다. 43 | 그리하여 병살타가 될만한 타구도 본인의 발로 어찌어찌 모면하는 경우도 꽤 있다. 44 | 주루 센스 역시 좋은 선수이며 적극성 역시 뛰어난 편. 45 | 다만 2019 시즌 중반 십자인대가 파열되는 부상을 입으면서 예전처럼 적극적인 주루를 시도하지는 않게 되었다. 46 | 47 | 나성범 - 플레이 스타일 - 수비 48 | KBO 리그의 대표적인 강견 외야수 중 하나로, 투수로서도 시속 150km/h에 육박하는 공을 던질 수 있을 정도의 강한 어깨를 자랑한다. 49 | 지금은 공격력을 살리기 위해 우익수로 전향을 했지만 데뷔 초 2년 간 풀타임으로 중견수를 소화했을 정도의 수비력을 갖춘 선수이다. 50 | 나성범의 수비 RAA는 데뷔 시즌부터 꾸준히 플러스를 기록하는 중이며, 덕분에 WAR 등등의 종합 지표에서 굉장한 이득을 보고 있다. 51 | 세이버메트릭스로 봐도 프로 데뷔 이후 스탯티즈 기준 통산 WAR이 28.44로 동 시기 전체 야수 중 4위를 기록하고 있다. 52 | 그러나 2018년 메이저리그 스카우터 말에 따르면 "어깨가 강한 것은 긍정적이다. 그러나 수비 당시의 풋워크나 전반적인 수비 능력은 좀 더 향상될 필요가 있다”라고 한다. 53 | 2019 시즌에는 주전 중견수로 낙점한 김성욱이 시즌 초반부터 크게 부진하면서 5년 만에 중견수 자리로 돌아왔지만 큰 무리없이 좋은 수비를 보여주었다. 54 | 2020년에는 부상 여파로 RNG가 1/10로 폭락했고, 사실상 풀타임 지명타자로 출장했다. 55 | ``` 56 | 57 | ## 고려사항 58 | 59 | ### 이 스크립트 사용하기엔 파일 용량(>8GB)이 너무 큰데? 60 | 61 | 동적으로 처리할 수 있을 것 같긴한데, 32GB 머신에서 일단 다 로드해서 처리하는 중이예요. 62 | "미리 최소한으로 정제해서 사용하기 좋은 포맷으로 만들어두고, 후처리는 알아서 하면 되겠다"라는 생각이라 여러 파일로 나눠진 형태의 압축파일로 제공합니다. 63 | 메모리가 혹시 모자라시면 ijson 같은 라이브러리를 이용해서 수정하시거나 다른 램많은 분에게 부탁을 해주세요. 64 | 65 | --- 66 | 67 | 전처리 과정에서 오류가 있는 부분은 이슈로 알려주세요. 68 | -------------------------------------------------------------------------------- /test_data/test2.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": 0, 3 | "title": "%", 4 | "text": "[include(틀:다른 뜻1, other1=백분율, rd1=백분율)]\n[목차]\n== 개요 ==\n백분율 기호며 퍼센트 기호라고도 한다.\n\n유니코드는 U+0025이다. ~~하지만 정작 위의 주소창에는 %25라고 쓰여 있다~~[* 그냥 %만 입력할 시에는 [[HTTP/응답 코드#s-4|400 Bad Request]]가 뜬다.] URL은 [[라틴 문자]], [[숫자]], [[-]], [[_]] 등을 제외한 문자는 이스케이프해야 올바른 주소라는 것을 보장한다. [[URL escape code]] 참조.]어째서인지 [[\\\\]]을 치면 %이 나오며 \\\\\\\\이라고 두 번 치면 \\\\이 나온다.\n\n[[두벌식]] 키보드 기준으로 Shift + 5로 입력이 가능하다.\n[[세벌식]] 390 키보드는 [[두벌식]] 키보드와 동일하게 Shift + 5로 입력할 수 있으며, [[세벌식]] 최종 키보드에서는 Shift + [로 입력한다.\n\n전산에서는 [[정수]]의 [[나머지]] 연산 기호로 쓰이기도 한다. 13%3이라고 하면 13을 3으로 나눈 나머지인 1을 출력하는 식. \n\n여담이지만 [[던전 앤 파이터]]에서는 입력할 수 없다. 정확히는 아이템 텍스트로는 가능한데, 유저가 채팅으로 칠 수는 없다.\n\n== 역사 ==\n이 기호는 '100에 대하기'라는 의미의 이탈리아어 'per cento'의 축약형인 'P cento'에서 발전한 것이다.\n[[파일:percent15.png]]\n15세기의 퍼센트 기호.\n[[파일:percent17.png]]\n17세기의 퍼센트 기호.\n[[파일:percent18.png]]\n현재의 퍼센트 기호.\n\n15세기에는 'P'를 눕히고 그 밑에 'cento'를 작게 쓰는 모양으로 했는데, 이게 쓰기가 귀찮고 작은 글씨로 쓰기도 어렵다 보니까 17세기에 와서 밑의 'cento'를 '-o'로 축약해서 쓰게 되었고, 여기서 모양이 더 달라진 게 현재의 '%'이다.\n\n== 기타 ==\n'%'가 '응'을 옆으로 살짝 기울인 것처럼 보여서 ''''응''''으로도 불리며, [[야민정음]]과 비슷한 맥락. \n\n[[Apink]]의 미니앨범 8집인 [[PERCENT]]의 타이틀곡이 %%(응응)이다.\n[[분류:특수 문자]][[분류:합자]]\n", 5 | "contributors": [ 6 | "112.150.13.26", 7 | "125.186.248.118", 8 | "180.70.137.152", 9 | "115.140.21.108", 10 | "chovy_fan", 11 | "archevil", 12 | "fred6758", 13 | "49.142.40.51", 14 | "masterpiece98", 15 | "r:archevil", 16 | "kmg2473", 17 | "211.208.135.92", 18 | "hongdam_", 19 | "pump5458", 20 | "124.80.48.180", 21 | "quel", 22 | "121.165.123.67", 23 | "211.45.7.254", 24 | "175.212.11.46", 25 | "unofficialnamuimgserver", 26 | "jkmidal", 27 | "owb101", 28 | "obey_the_walrus", 29 | "zrwgy", 30 | "daressalaam", 31 | "hdjdhsisjch4", 32 | "dercsyong", 33 | "sasungkorea", 34 | "122.40.211.23", 35 | "namubot", 36 | "ssangmun2", 37 | "222.112.45.157", 38 | "218.54.9.80", 39 | "203.241.183.10", 40 | "actanonverba", 41 | "iron", 42 | "clouds" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /test_data/test6.gold.txt: -------------------------------------------------------------------------------- 1 | 아이작의 번제/아이템/패시브 아이템 - 개요 2 | 나무위키에서 작성한 아이작의 번제 시리즈의 아이템 중 애프터버스+ 버전 기준으로 패시브 아이템을 따로 분류한 문서다. 3 | 4 | 아이작의 번제/아이템/패시브 아이템 - 설명 5 | 액티브 아이템과 달리 대개 능력이나 스탯을 영구적으로 제공하기 때문에 액티브 아이템에 비해 유용한 편이다. 6 | 하지만 플레이어에게 피해를 줄 수 있거나, 능력치 페널티가 심하거나, 눈물이 날아가는 방식을 바꾸는 아이템들도 있는데, 이런 걸 잘못 먹으면 게임 진행이 매우 힘들어진다. 7 | 더군다나 패시브 아이템은 영구적이라 발동을 제어할 수 없고, 버터 장신구가 아니면 소지 아이템에서 제외할 수 없다. 8 | 그래도 결국은 케바케인지라, 조합이나 플레이어의 역량에 따라서는 기피 템이 사기 템이 되기도 한다. 9 | 아이템을 얻을수록 모습이 조금씩 기괴해지는 것이 특징. 그래서 이미지 중 몇 가지는 적용되는 것은 물론 드롭된 이미지라도 혐오스러울 수 있으니 주의. 그림체가 귀여운 편이라 엄청 혐오스럽다고 하긴 어려워도 고어한 아이템이 있다. 10 | 아이템 명칭은 기본적으로 영문을 기준으로 하며, 2016년 1월 23일 공개된 아이작의 번제: 애프터버스에서 한글화된 아이템들은 영문 명칭 옆에 한글 명칭도 기재하였다. 11 | 애프터버스 플러스에서는 한글화가 되지 않았으나 유저가 제작한 모드에 의해 임시로 한국어로 번역되어 있다. 12 | 이것에 대한 안내는 아이작 문서 틀에 있는 아이작/모드 문서 참고. 13 | 오리지널에 있던 아이템 일부가 변경되거나 삭제되었다. 14 | 거지 배열이 있으나, 거지 배열의 방이 없기 때문에 기부 후 나오는 해당 아이템을 D6로 돌리면 현재 방(특정방이 아닐 시 보물 방)배열의 아이템이 나온다. 15 | 돌 상자나 하얀 상자는 황금상자 배열을 따른다. 16 | 도전 방, 보스 도전 방, 보스 러시 배열이 존재하나 세 방 모두 보물 방 배열을 쓰기 때문에 실제로는 사용되지 않는 더미 데이터로 남게 되었다. 17 | 배열 간섭(예를 들어 Fate와 Pyro) 역시 사라진 것으로 보인다. 18 | ID는 콘솔에 쓰이는 번호이다. 19 | STAT항목에서 아이템 리스트를 대조할 때 쓰이기도 한다. 20 | 패밀리어 제한은 약 30마리이며 이후 생성되면 차례로 밀려난다. 21 | 언락조건이 없는것은 상시 언락이다. 22 | 주요 시너지 효과의 의미는 각 아이템을 찾아봤을 때 이 위치로 이동이 된다. 23 | 주요 시너지 설명에서 적용 안 됨이라고 쓰여 있는 아이템들이 있는데 이것은 해당 아이템이 시너지 목록에 있는 아이템 쪽으로 적용이 되는지의 여부를 말한다. 24 | 만약 반대로 시너지 목록에 있는 쪽이 해당 아이템에 적용이 안 되는 쪽이라면 적용 안 됨 표시가 아니라 별도로 해당 시너지 아이템이 적용이 안 된다는 식으로 서술되어 있다. 25 | 아무것도 없을 경우 시너지/상호작용이 없는 단일템이다. 26 | 27 | 아이작의 번제/아이템/패시브 아이템 - 설명 - 오리지널~애프터버스 리스트 28 | 현재 문서는 검색의 활용도를 위해 플러스를 기준으로 작성되었으며 이로 인해 구버전의 정보는 기록되어 있지 않다. 29 | 오리지널, 리버스, 애프터버스 때의 설명 및 변경사항은 이쪽의 r1181판을 참고. 30 | 31 | 아이작의 번제/아이템/패시브 아이템 - 설명 - 아이템 검색 방법 32 | PC에서는 Ctrl + F로 검색할 수 있는데 시너지 조합이 숨겨져 있음에도 검색 대상에 걸려 찾기 힘들 수 있다. 33 | 이때 Chrome 브라우저를 쓰면 아이템 이름을 영문으로 검색 시 오른쪽 스크롤에 노란색 막대가 생성된다. 34 | 이 막대가 생성된 위치로 스크롤을 이동하면 아이템을 빠르게 찾을 수 있다. 35 | 인터넷 익스플로러는 이 기능을 제대로 지원하지 않을 수 있으니 참고. 36 | PC버전의 다른 방법으로는 검색 시 아이템명 끝에 '('를 추가하는 것이다. 아이템 제목은 옆에 전부 (한글명)을 붙여놨는데 이를 이용해 mom's heart( 를 검색해서 빠르게 찾는 방법이다. 37 | 만약 mom's heart 처럼 띄어쓰기가 되어 있는 아이템 제목은 붙여쓰기로 수정하고 있다. 38 | 모바일에서는 기본 인터넷 앱으로도 찾기 기능을 이용해 바로 찾을 수 있다. 39 | 40 | 아이작의 번제/아이템/패시브 아이템 - 설명 - 스페셜 등급(Special Item) 41 | , #6d4600,#6d4600 다크 모드 색상일 때 42 | 리롤되는 #orange Special 아이템 리스트는 다음과 같다. 43 | 리롤 기준은 액티브 아이템은 획득했을 경우, 패시브 아이템은 발견했을 경우에 해당된다. 44 | 아래 스페셜 아이템의 링크를 누르면 해당 아이템의 위치로 이동한다. 45 | 액티브 아이템 46 | - D100 47 | - The D6 48 | 패시브 아이템 49 | - Brimstone 50 | - Dr. Fetus 51 | - Epic Fetus 52 | - Godhead 53 | - The Ludovico Technique 54 | - Mom's Knife 55 | - Mutant Spider 56 | - Polyphemus 57 | - Pyromaniac 58 | - Sacred Heart 59 | 60 | 아이작의 번제/아이템/패시브 아이템 - 오리지널 아이템 61 | 오리지널에서 나오는 아이템 목록이다. 62 | 오리지널에선 레어 등급이라고 하여 빨간색으로 표시하였으나 리버스로 넘어오면서 레어 등급이 대부분 강등되었다. 63 | 단, 리버스 이후에도 유지된 스페셜 아이템은 배경을 그 등급의 색으로 표시하였다. 64 | 65 | 아이작의 번제/아이템/패시브 아이템 - 리버스에 추가된 아이템 66 | 더 바인딩 오브 아이작: 리버스에 새로 등장한 아이템들이다. 67 | 68 | 아이작의 번제/아이템/패시브 아이템 - 애프터버스에 추가된 아이템 69 | 더 바인딩 오브 아이작: 애프터버스에 새로 등장한 아이템들이다. 70 | 애프터버스 DLC를 구매하지 않으면 쓸수 없으며 설명 및 시너지에 대한 내용은 애프터버스 플러스의 최신패치에 맞춰 수정된 내용이다. 71 | 구버전 혹은 패치전에 대한 내용은 문서 맨위에 있는 지난 판 내용을 참고하자. 72 | 73 | 아이작의 번제/아이템/패시브 아이템 - 애프터버스 †에 추가된 아이템 74 | ※ 여기서부터는 애프터버스와 달리 한글로 된 아이템 이름 및 습득시 대사는 비공식 모드에서 참고한 것이다. 75 | 후속작에서 한글화가 될 경우 이름이 바뀔 가능성이 있으며 문서에 기재된 한글명칭에 대한 부분과 적용방법은 아이작/모드문서를 참고하자. 76 | 77 | 아이작의 번제/아이템/패시브 아이템 - 애프터버스 †에 추가된 아이템 - 부스터 팩 #1에 추가된 아이템 78 | 본래 부스터 팩에서 추가된 아이템들은 딱히 언락 조건 없이 처음부터 나왔지만, 부스터 팩 #5 업데이트로 부스터 팩에서 추가된 아이템들에 언락 조건이 생겨났다. 79 | -------------------------------------------------------------------------------- /test_data/test1.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": 0, 3 | "title": "“……”", 4 | "text": "||<-2> [[파일:201308252140773269_5219fbbd1a7b5_59_20130825214304.jpg]] ||\n|| '''코너명''' || “……” ||\n|| '''시작''' || [[2013년]] [[5월 26일]] ||\n|| '''종료''' || [[2013년]] [[10월 13일]] ||\n|| '''출연진''' || [[유민상]], [[김희원(코미디언)|김희원]], [[송필근]], [[남궁경호]] ||\n|| '''유행어''' || XX는 더 이상합니다[* 어색한 상황을 수습해보려는 변명이 더 안 좋은 결과를 낼 때 나오는 말.] ||\n\n[목차]\n[clearfix]\n== 개요 ==\n[[개그콘서트]]의 전 코너. '''진짜로 코너 이름이 “……”[* 큰 따옴표도 포함된다.]이다'''. 언론에서는 이 코너를 언급할 때 '점점점' 또는 '점점점점점점'이라는 표현을 사용했다. 코너명의 유래는 흔히 쓰이는 [[...|말줄임표]].\n\n남자친구(남궁경호)와 여자친구(김희원)의 아버지(유민상) 간의 어색함을 다룬 코미디.\n\n초창기엔 당시 조연을 맡았던 송필근보다 남궁경호의 비중이 높았으나, 6화[* 2013년 6월 30일 방송분]부터 송필근이 남궁경호의 아버지 역(유민상과 사돈관계)으로 고정되면서 남궁경호의 비중은 줄어들었다. 심지어 아예 등장이 없는 회차도 간간이 나오게 되어, 사실상 유민상과 송필근의 투톱 체제가 된 코너.\n\n송필근의 역할변경 후로는 주로 사돈 간의 어색함을 다루고 있다. 주된 패턴은 3,4명에서 시작해 누군가[* 주로 여자친구 혹은 커플.] 자리를 비우면, 남은 2명은 어색함에 조용해하고 중간중간 어색함을 깨보려는 대사에도 계속되는 어색한 분위기가 주된 패턴. 침묵이 계속되면 자리마다 있는 [[괘종시계]]가 째깍째깍 울리는 것이 웃음 포인트다. 유민상이 사돈어른(송필근)이 오기 전 집안의 괘종시계를 미리 치워버린 에피소드도 있었는데, 사돈어른이 선물로 벽시계를 사오는 바람에 어색한 상황에서 째깍째깍 소리가 나게 되었다.\n\n만약 제 3자(송필근)의 등장으로 남자친구가 자리를 비우면, 제3자와 아버지 간의 분위기가 어색해진다. 김희원은 코너 유일의 붙임성 있는 성격이지만, [[눈치 없는 새끼|눈치가 없는지라]] 말을 꺼내도 더 어색해진다.\n\n\n코너 자체의 어색한 침묵이라는 주제 때문인지, 대화가 적은 현대사회의 모습을 은유한 것이라는 의견도 있다.\n\n== 상세 ==\n7화(2013년 7월 14일 방송분)에서는 사돈어른이 [[2PM]] 춤 추다가 입원해서 놀림당했는데 건너편에 미라처럼 깁스를 하고 있던 유인석이 한 손을 뻗어 심장박동을 시전했다. ~~캔 유 필 마 핫빗?~~ 그리고 아빠와 딸이 모두 [[박카스|박X스]]를 한 '''박스'''씩 사왔는데, 병실 장롱에 '''박X스가 한가득''' 들어있었다. 유민상이 병문안 때는 박X스를 사가는 것이 좋다고 생각했는데, 알고보니 전에 병문안 왔던 사람들도 같은 생각을 했던 것.\n\n9화(2013년 7월 28일 방송분)에서는 송필근이 김희원의 오빠 역할로 나왔다. 경호-희원 커플이 유민상 몰래 괌에 갔다온 것이 들통나면서 남궁경호가 [[괌]]을 \"'''[[대전광역시|대전]] [[구암동|구암]]'''(Guam)\"이라고 말하니까 유민상의 드립이\"난 '''몽둥이 구함~'''\"\n\n회가 거듭하면 거듭할수록 커플의 진도가 쭉쭉 잘 나가서 김희원이 '''[[배꼽티]]'''도 자랑했고, 11화(2013년 8월 25일 방송분)에서는 김희원이 웨딩드레스를 맞췄다.\n\n14화(2013년 9월 15일 방송분)에서는 송필근이 사돈 유민상의 아버지 희수연을 기념하고자 화환을 보냈는데, 문제는 유민상 아버지의 본명이 유[[죽빵|죽방]]이라 본인이 그 이름을 매우 싫어했다는 것. 그래서 현수막은 \"유 할아버지\"라고 걸려 있었다. ~~이 정도면 개명을...~~ 하지만 송필근이 그 사실을 몰랐기 때문에 하필 예식장에 그 이름 석자가 크게 적힌 화환이 배달되었으며, 뒤늦게 상황을 수습한답시고 글자를 어떻게 가려보려고 애를 썼는데, 마지막 글자를 가린 '유죽'도 이상해서 안 됐고, 이어 '''[[유방(신체)|가운데 글자를 가린 것은 더 큰일나는 이름인 바람에]]'''... 유민상의 아버지로는 [[김재욱(코미디언)|김재욱]]이 나왔다.\n\n또한 딸 김희원이 아버지 유민상께 건강팔찌를 주고, 남자친구에겐 금팔찌를 주자 상황이 쎄해졌다. 김희원이 \"이거 한 돈도 안돼!\"라고 무마하려 하지만 유민상은 \"이거는 돈이 안되고.\"라고 말한다.\n\n15화(2013년 9월 22일 방송분)에서는 [[정태호]]가 [[나훈아|너훈아]] 역할로 출연했다.\n\n마지막화인 17화([[2013년]] [[10월 13일]] 방송분)에서는 [[박은영(개그우먼)|박은영]]이 유민상과 송필근이 [[건강검진]]을 받으러 간 병원의 간호사 역할로 나왔다.[* 이날 방송분에서 직접적으로 마지막 회라고 언급했더니 방청객들이 아쉬워하자 유민상이 모든 사람들에게 다 까라고 그런다.]\n\n극중에서 부자관계로 나오는 27기 남궁경호와 송필근은 동갑이자 성남예고, [[인덕대학]] 동기로 둘 다 91년 생이다.\n\n[[분류:2013년 종영/개그콘서트 코너]]", 5 | "contributors": [ 6 | "milkbutter", 7 | "116.122.29.64", 8 | "211.54.69.240", 9 | "180.68.220.42", 10 | "관리자", 11 | "coffebay", 12 | "121.170.49.141", 13 | "cinjuwikicjwk", 14 | "124.199.172.169", 15 | "203.246.73.87", 16 | "63.141.228.226", 17 | "211.54.69.220", 18 | "r:bidulgiya99", 19 | "r:usaminseijin", 20 | "hoon345", 21 | "211.54.69.2", 22 | "218.209.125.191", 23 | "175.113.212.161", 24 | "jec1025", 25 | "gorgeousfriend", 26 | "61.76.218.49", 27 | "solentis", 28 | "syntax", 29 | "dream33", 30 | "124.50.19.73", 31 | "14.39.201.151", 32 | "116.122.26.7", 33 | "211.104.174.13", 34 | "125.141.77.128", 35 | "110.11.67.47", 36 | "jhp0148", 37 | "1.243.79.148", 38 | "211.54.69.238", 39 | "211.221.114.166", 40 | "211.104.174.124", 41 | "fairy", 42 | "beforesunrising", 43 | "uranium235", 44 | "qolonq", 45 | "heffykuma", 46 | "king0816", 47 | "foredit", 48 | "116.122.29.212", 49 | "61.109.103.72", 50 | "abc", 51 | "211.54.69.235", 52 | "175.255.246.14", 53 | "147.47.105.158", 54 | "yul", 55 | "owb101", 56 | "r:angryphw", 57 | "112.173.70.173", 58 | "220.121.109.116", 59 | "jihs7507", 60 | "175.198.119.105", 61 | "heyyeyaaeyaaaeyaeyaa", 62 | "pluk", 63 | "121.173.30.40", 64 | "121.174.125.92", 65 | "112.166.94.23", 66 | "103.16.26.184", 67 | "keepcalmandcarryon", 68 | "119.69.162.140", 69 | "59.8.45.41", 70 | "gamzadongza", 71 | "116.125.231.90", 72 | "116.123.57.187", 73 | "rofcause", 74 | "175.210.183.195", 75 | "sdf7175", 76 | "1.235.157.85", 77 | "kiwitree2", 78 | "116.122.26.99", 79 | "183.101.131.246", 80 | "namubot", 81 | "dhdjudidiishssh", 82 | "ahnj2000", 83 | "24.114.36.181", 84 | "202.14.90.182", 85 | "211.104.174.109", 86 | "59.31.55.56", 87 | "116.123.57.58", 88 | "klejyo", 89 | "kimgeonwoo", 90 | "116.122.29.180", 91 | "222.112.45.157", 92 | "aottkd3014", 93 | "samduk" 94 | ] 95 | } 96 | -------------------------------------------------------------------------------- /preprocess.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import json 4 | import unicodedata 5 | from multiprocessing import Pool 6 | from typing import Dict, Any, Generator 7 | 8 | import kss 9 | from absl import app, flags 10 | from tqdm import tqdm 11 | 12 | FLAGS = flags.FLAGS 13 | 14 | flags.DEFINE_string("dump", "", help='나무위키 덤프 파일 위치') 15 | flags.DEFINE_string("output", "", help='output path') 16 | flags.DEFINE_integer("chars_per_file", 100000000, help='chars per file') 17 | 18 | def main(argv): 19 | assert FLAGS.dump and FLAGS.output 20 | 21 | os.makedirs(FLAGS.output, exist_ok=True) 22 | 23 | with open(FLAGS.dump) as f: 24 | obj = json.load(f) 25 | 26 | file_index = 0 27 | file_handler = open(os.path.join(FLAGS.output, f"namu_{file_index:06d}"), 'w') 28 | num_chars = 0 29 | with Pool(12) as pool: 30 | for result in tqdm(pool.imap_unordered(preprocess, obj)): 31 | for doc in result: 32 | num_chars += len(doc) 33 | file_handler.write(f"{doc}\n") 34 | 35 | if num_chars > FLAGS.chars_per_file: 36 | file_handler.close() 37 | 38 | file_index += 1 39 | file_handler = open(os.path.join(FLAGS.output, f"namu_{file_index:06d}"), 'w') 40 | num_chars = 0 41 | 42 | 43 | def preprocess(x: Dict[str, Any]) -> Generator[str, None, None]: 44 | results = [] 45 | 46 | titles = [x['title']] 47 | 48 | doc_title = x['title'] 49 | doc_text = f"" 50 | is_in_table = False 51 | is_in_syntax = False 52 | is_in_folding = False 53 | 54 | for line in x['text'].split("\n"): 55 | line: str = line.strip() 56 | line = unicodedata.normalize("NFC", line) 57 | 58 | if line.startswith("##"): # 주석 59 | continue 60 | 61 | if is_in_folding: 62 | if "}}}" not in line: 63 | continue 64 | is_in_folding = False 65 | line = line[line.index("}}}") + 3:].strip() 66 | 67 | if is_in_syntax: 68 | if "}}}" not in line: 69 | continue 70 | is_in_syntax = False 71 | line = line[line.index("}}}") + 3:].strip() 72 | 73 | if is_in_table: 74 | if line.endswith("||"): 75 | is_in_table = False 76 | continue 77 | 78 | # [목차], [clearfix], [include ....], [[분류:....]] 등의 텍스트는 스킵 79 | # 혹시 멀티모달같은거 시도하시려면 여기서 이미지 처리 해주시면 됩니당 80 | if line.startswith("[") and line.endswith(']'): 81 | continue 82 | 83 | # 접기 - 중간에 들어갈 경우 어색해짐 84 | if line.startswith("{{{#!folding"): 85 | if not line.endswith("}}}"): 86 | is_in_folding = True 87 | continue 88 | 89 | # 코드 블럭 90 | if line.startswith("{{{"): # 원래는 {{{#!syntax 로 시작해야 하지만, {{{만으로 시작하는 것이 많이 보임 91 | if not line.endswith("}}}"): 92 | is_in_syntax = True 93 | continue 94 | 95 | # 표 96 | if line.startswith("||"): 97 | if not line.endswith("||"): 98 | is_in_table = True 99 | continue 100 | 101 | # redirect, .. 102 | if line.startswith("#redirect") or line.startswith("#넘겨주기"): 103 | continue 104 | 105 | # block quotes 106 | if line.startswith(">"): 107 | continue 108 | 109 | line = re.sub(r"\[\[[^\]\|]+\|([^\]\|]+)\]\]", r"\1", line) # 링크 110 | line = re.sub(r"\[\[([^\]\|]+)#[^\]]+\]\]", r"\1", line) # anchor가 있는 링크 111 | line = re.sub(r"\[\[([^\]\|]+)\]\]", r"\1", line) # 링크 112 | line = re.sub(r"\[\*[^\]]+\]", r"", line) # 각주 113 | line = re.sub(r"\[anchor[^\]]+\]", r"", line) # anchor 114 | 115 | line = re.sub(r"{{{(#|\+)[a-f0-9]{3,6} ([^}]+)}}}", r"\1", line) # 색상, 크기 116 | 117 | # 텍스트 스타일 118 | line = re.sub(r"'''([^']+)'''", r"\1", line) # 굵게 119 | line = re.sub(r"''([^']+)''", r"\1", line) # 기울임 120 | line = re.sub(r"___([^_]+)___", r"\1", line) # 기울임 121 | line = re.sub(r"\(--[^-]+--\)", r"", line) # 괄호안 취소선을 넣는 사람이 보인다.. 122 | line = re.sub(r"\(~~[^~]+~~\)", r"", line) # 괄호안 취소선을 넣는 사람이 보인다.. 123 | line = re.sub(r"~~[^~]+~~", r"", line) # 보통 취소선은 없는게 자연스럽다고 느껴져 삭제 124 | line = re.sub(r"--[^-]+--", r"", line) # 취소선 125 | line = re.sub(r"\^\^[^\^]+\^\^", r"", line) # 윗첨자 삭제 126 | line = re.sub(r",,[^,]+,,", r"", line) # 아랫첨자 삭제 127 | line = re.sub(r"{{{([^}]+)}}}", r"\1", line) # 리터럴 128 | 129 | # 문자 이스케이프 130 | line = re.sub(r"\\([\\_-])", r"\1", line) 131 | 132 | # 섹션 제목 133 | if line.startswith("==") and line.endswith("=="): 134 | # title 135 | if doc_text: 136 | results.append(f"{doc_title}\n{doc_text}") 137 | 138 | heading = re.sub("^=+ (.+) =+$", "\\1", line).strip() 139 | heading_level = re.search("^=+", line).span()[1] - 1 140 | titles = titles[:heading_level] 141 | titles.append(heading) 142 | doc_title = ' - '.join(titles) 143 | doc_text = "" 144 | continue 145 | 146 | # 휴리스틱 147 | line = re.sub(r"다. ?#$", r"다.", line) # 맨 끝에 링크 있는 경우 148 | line = re.sub(r"다.# ", r"다. ", line) # 문장 끝에 링크 있는 경우 149 | line = line.replace("(...)", " ") # 의미없는 문자열 삭제. Ellipsis 문자 같은 경우에 실제 의미가 있지만, 의미없이 해당문자가 들어가 있는 경우가 많아 삭제 150 | line = re.sub(r"[\s]+", ' ', line) # 띄어쓰기 normalize 151 | 152 | # 리스트 153 | if line.startswith("* "): 154 | line = line[2:].strip() 155 | 156 | if line == '': 157 | continue 158 | 159 | sentences = '\n'.join(kss.split_sentences(line, safe=True)) 160 | doc_text += f"{sentences}\n" 161 | 162 | if doc_text: 163 | results.append(f"{doc_title}\n{doc_text}") 164 | 165 | return results 166 | 167 | if __name__ == "__main__": 168 | app.run(main) 169 | -------------------------------------------------------------------------------- /test_data/test5.gold.txt: -------------------------------------------------------------------------------- 1 | C++ - 개요 2 | C언어를 부분집합으로 갖고 객체 지향 및 일반화 프로그래밍과 같은 멀티 패러다임을 지원하는 프로그래밍 언어이다. 3 | C언어의 문법과 기능을 모두 사용할 수 있다. 4 | 1979년에 C언어에서 직접적으로 파생된 C with Classes라는 이름의 언어로 시작되었다가, 1983년에 지금의 이름을 갖게 되었다. 5 | 온라인 상으로 코드를 실행시켜 보고 싶다면 여기로. 6 | 7 | C++ - 특징 8 | 비아르네 스트로우스트루프(Bjarne Stroustrup)가 C언어를 바탕으로 만들었다. 9 | C 계열 언어에서 "++"라는 것은 1을 더해서 원래 변수에 대입하라는 뜻이다. 10 | C는 B 언어를 계승한다는 의미에서 C가 되었는데 왜 C++가 D가 아니라 C++가 되었냐 하면 C 언어를 거의 그대로 두고 필요한 만큼만 향상시켰기 때문이다. 11 | 그래서 C에서 되는 게 C++에서도 된다. 12 | 비슷한 이름인 C\#과의 차이도 이러한 점에서 나타난다. 13 | C++ 커뮤니티는 C++가 단순히 객체지향 프로그래밍 언어라고 분류되는 것을 오류라고 여긴다. 14 | C++의 제작자인 Bjarne Stroustrup은 C++가 단순한 객체 지향 프로그래밍 언어가 아니라고 설명했다. 15 | # C++는 프로그래머의 자유도가 높은 언어로써, 객체 지향이나 절차 지향 등의 설계에 제한을 두지 않는다. 16 | 다만, 객체지향과 일반화 프로그래밍을 사실상 거의 주된 패턴으로 사용하기 때문에 (프로그래머 입장에서는) 객체지향 언어에 가깝다. 17 | C++에서는 객체지향 프로그래밍 패러다임과 동등한 강도로 일반화 프로그래밍 패러다임을 강조하고 있다. 18 | 스트로우스트루프의 책 The C++ Programming Language 4판을 참고하면 "3부 추상화 메커니즘" 단원의 절반(7개 섹션)은 객체지향, 나머지 절반(7개 섹션)은 일반화 프로그래밍에 할애하고 있다. 19 | 그리고 "4부 표준 라이브러리" 단원의 1/3이 STL이고, 2/3는 나머지 표준 라이브러리를 설명하고 있다. 20 | 쉽게 말하자면 C++는 기존의 C 문법이 대표하는 절차적 프로그래밍, 클래스가 대표하는 객체지향 프로그래밍, 템플릿이 대표하는 일반화 프로그래밍의 세 기둥으로 지지되고 있는 언어이다. 21 | 유사한 의견으로 Effective C++의 저자 스콧 마이어스는 C++가 4가지 하위언어의 연합체라고 언급한다. 22 | C, 객체지향 C++, 템플릿 C++, STL. 현재의 모던 C++ 표준 라이브러리가 스테파노프(Stephanov)와 리(Lee)가 1990년대에 개발한 Standard Template Library(STL)의 아이디어를 많이 수용한 것은 사실이나, C++의 표준안 그 어디에도 STL이라는 표현은 등장하지 않는다. 23 | Effective C++의 저자인 스콧 마이어스(Scott Meyers)와 같이 나이 많은 거장 프로그래머들이 1990년대의 관습 그대로 STL이라는 용어를 자신의 저작물에 지속적으로 사용하는 바람에 STL이라는 용어가 아직도 널리 사용되고 있으나, STL과 C++ 표준 라이브러리의 차이가 뭔지 묻는 수많은 구글 검색 결과가 보여주듯이 초보자들에게 꽤 커다란 혼돈을 주는 요소이다. 24 | 스테파노프와 리가 직접 작성한 Hewlet-Packard 버전의 STL이나, 실질적으로 더 널리 쓰이던 Silicon Graphics 버전의 SGI STL은 더 이상 관리가 되지 않고 방치가 된 지 오래이고, SGI STL을 계승하려고 노력하던 STLPort도 개발이 중단되었다. 25 | 결국 초창기 STL의 구현체는 모두 사라지고 그 아이디어만이 살아남아서 C++의 표준 라이브러리에 흡수되었으므로, STL을 따로 떼어 지칭하는 것이 이제 의미가 없다. 26 | 각각의 '하위 언어' 들의 규칙과 구현이 전부 다르므로 복잡도가 상당히 높으며 'C with classes'라는 초기 명칭과는 한참 차이가 날 정도로 확장되었다. 27 | 쓸 때는 C++라고 쓰지만 읽을 때는 시 플러스 플러스, 혹은 줄여서 시플플이라고 읽는다. 28 | 한국에서는 사실상 속어에 가까운 씨쁠쁠로 불린다. 29 | '씨뿔뿔'로 발음되는 경우도 많다. 30 | 연세가 꽤 있으신 교수님 중에는 간혹 '시 더블 플러스'라고 읽는 경우도 있다. 31 | 미국에서는 그냥 씨 플러스 플러스 또는 CPP(시피피)라고 읽는다. 32 | 한국에서 컴퓨터공학과를 다닐 경우 배울 수 있는 프로그래밍 언어 3개 중에 속한다. 33 | 나머지 둘은 C와 Java. 그러나 실상 C++11 이후의 모던 C++ 기능을 가르쳐주는 곳이 매우 드물어서 C++의 객체 지향만 조금 배울 수 있다. 34 | C++의 객체 지향은 다른 언어에 비해서 좀 더 복잡하다. 35 | 제대로 다루기 위해서는 별도의 서적을 참고하는 것이 권장되며, 실제 프로젝트의 코드에 대해 탐구하고 경험해보는 것이 좋다. 36 | 37 | C++ - 특징 - C와의 차이점 38 | C++의 개발이 C언어를 기반으로 이루어졌기 때문에 대부분의 C 프로그램은 C++ 컴파일러에서도 문제없이 컴파일된다. 39 | 초기 C++ 컴파일러는 일단 C++ 코드를 C로 변환하고 그걸 C로 컴파일하는 방식을 사용했을 정도. 다만, C가 항상 C++의 부분집합이었던 것은 아니라서 공통적인 부분에서 몇몇 차이점이 있으며, 순수 C 소스 코드를 C++로 컴파일 할 때 문제의 여지가 생길 가능성이 있다. 40 | C++는 C와 프로그래밍 패러다임이 크게 다르다. 41 | 그래서 C로 작성된 프로그램에서 C++ 방식으로 코딩하려면 해당 코드에서 C++에 새로 도입된 것을 추가하는 게 아니라, 설계부터 시작해서 완전히 새로 해야 하는 경우가 많다. 42 | C++의 객체지향이 다른 객체지향 언어에 비해 이해하기가 만만한 개념이 아닌 데다가 C++의 객체지향은 C언어를 하위 요소로서(항상 그래온 것은 아니지만) 유지하면서 여러 문법 요소를 추가했기 때문에 신경 써야 할 부분이 많다. 43 | 다른 객체지향 언어에서보다 잘 다루는데 더 많은 공부가 필요하다. 44 | 따라서, 초심자 입장에서는 C와 C++는 완전히 다른 언어로 파악하고 접근하는 것이 좋다. 45 | C++ → C 테크도 만만치가 않다. 46 | C → C++는 절차지향 언어의 사고방식, C++ → C는 객체지향 언어의 사고방식이 머릿속에 굳어버리기 때문이다. 47 | C++가 C의 모든 기능을 포괄하고 있으므로 C++를 할 줄 알면 C도 할 줄 안다고 생각하기 쉽지만, 사실 C++가 명시적으로 비교적 간단히 사용할 수 있도록 제공하는 기능들을 C에서는 암묵적으로 여러 가지 수많은 '트릭'을 통해서 쥐어짜내듯이 만들어 사용하는 경우가 많다. 48 | GNOME의 핵심 라이브러리인 Glib이 대표적으로 C 언어로 객체지향을 짜도록 구성되어 있다. 49 | incomplete type declaration 트릭을 이용하여 캡슐화를 흉내내고, 매크로와 컴파일러 확장을 이용해서 type-generic function을 만들어 쓰고, struct hack을 이용하여 vector를 흉내 내는 식이다. 50 | 게다가, 저런 트릭은 언어 차원에서 정식으로 제공한다기보다 말 그대로 '트릭'에 가까우므로 이상한 조건들이 붙는 경우가 종종 있고, 그것들을 정확히 파악하고 있지 않으면 상당히 찾아내기 어려운 에러를 내는 경우도 많다. 51 | 그래서 많은 대학에서 컴공 1학년 1학기 때 C를 먼저 가르치고 빠르면 2학기, 늦어도 2학년에 C++를 가르치지만, 교수가 절차지향이 머리에 굳어버린다며 컴공에서 C 대신 C++와 객체를 먼저 가르치고 C는 아예 건드리지도 않고 다른 하드웨어 관련 학과에서만 가르치는 대학들도 많다. 52 | 객체지향만 배운다면 Java부터 시작하는 게 낫지만, 포인터 등을 통해 메모리와 각종 저수준(low level) 프로그래밍과 객체지향을 함께 배울 수 있기 때문이다. 53 | 컴공의 경우에는 C++를 모르면 2학년부터는 강의를 전혀 이해할 수 없기 때문에 의외로 많은 학생들이 중도포기를 하게 되며 컴공을 나왔는데도 프로그래밍을 전혀 못하는 학생들이 수두룩하게 발생하고 있다. 54 | 학교마다 다르지만 1학년때 아예 C를 배우고 2학년 1학기때 Java, 2학기때 C++ 과목이 생기는 곳도 있다. 55 | 서울대학교의 경우에는 1학년 1학기에 Python으로 코딩을 입문하고(--2019년까지는 기계어 -> 어셈블리 -> C언어라는 끔찍한 수업이었지만--), 1학년 2학기에 C언어로 어느 정도 큰 프로젝트를 짜 보고, 2학년 1학기에 C++과 Java를 배우면서 객체지향 프로그래밍을 배우게 된다. 56 | C++ 수업에 잘 적응하려면, C → Java → C++ 순으로 듣는 것을 권장한다. 57 | C를 알고 있다고 C++를 쉽게 할 수 있는 것은 아니다. 58 | 두 언어는 추구하는 설계 구조가 상당히 다르기 때문이다. 59 | C언어는 절차 지향이지만 C++는 절차 지향, 객체 지향, 일반화 프로그래밍, 함수형 프로그래밍을 모두 지원하는 언어다. 60 | 그래서 C언어를 알고 있는 사람이 C++ 초보자용 교재를 1권 끝내고 프로그램을 만들어 보라고 해도 대부분 C 방식에서 벗어나지 못한다. 61 | C++ 방식을 잘 활용하려면 STL까지 배운 다음 자료구조와 스트림, 템플릿 정도는 쓸 수 있어야 한다. 62 | C++이 C언어의 변형버전은 어느정도는 맞는 이야기긴 하다. 63 | 한편, C, C++ 중 어디가 쉽다라던가 하는 건 어디까지나 간단한 프로그램의 예일 뿐이다. 64 | 둘의 설계 구조가 다르고 성능상 미묘한 차이밖에 안 난다. 65 | C의 함수구조에서는 다중의 인자값 전달이 필수적인데 구조체에 전부 때려박더라도 전역변수가 아닌 이상 적어도 1개는 전달해야 한다. 66 | 반면에 C++ 측은 클래스의 this를 활용하면 인자 전달 없이 클래스에 속한 멤버함수 호출만 할 수 있다. 67 | 헤더참조 구조가 중복정의로 복잡해지는 건 덤. Node.js 모듈구조를 참고 해 보면 module.exports로만 다른 모듈과 상호작용 할 수 있는데 C 계열은 헤더를 넣으면 그 안에 있는 모든 건 상호작용되고 원치 않으면 소스파일과 분리해야 한다. 68 | 다만, C++의 경우 C++20 개정판부터 모듈 개념이 도입될 예정이므로 이러한 단점은 점차 시간이 지남에 따라 어느 정도 극복될 것이다. 69 | 다른 모듈에서 정의된 매크로는 사용하지 못하기 때문에, 매크로로 떡칠된 코드는 다 뜯어 고쳐야 할 수도 있다. 70 | 이 때문에 수많은 기존 프로젝트는 여전히 헤더를 사용할 것으로 보이며, C와의 호환성을 위해 헤더 참조 구조는 표준에서 없어지지 않을 것이다. 71 | 또한 C++98 초과의 최신판은 메인을 제외한 함수에 반환값의 자료명을 꼭 명시해 주어야 한다. 72 | 이외에도 C에서만 지원되는 문법이 몇 있다. 73 | 그 예로, K&R 스타일의 함수 정의 구문의 지원과 C99에서 추가된 지정 초기자(Designated Initializers) 의 일부 형태 등이 있다. 74 | 75 | C++ - 특징 - C++에서의 객체지향 프로그래밍 76 | C++는 객체 지향 프로그래밍을 지원하지만, C++의 객체지향은 다른 객체지향 언어에서와는 성격이 좀 다르다. 77 | 대부분의 객체지향 언어에서는 많은 부분을 런타임에 처리하며 메모리를 자동으로 관리하는 반면, C++에서는 최대한 많은 것을 컴파일 타임에 처리하는 것을 지향하며 메모리 등을 프로그래머가 직접 관리하게 하기 때문에 전반적인 클래스 디자인 자체가 상당한 차이를 보이게 된다. 78 | Java 등의 다른 객체지향 언어에서와 같은 방식으로 C++ 클래스를 디자인하면 거의 틀림없이 컴파일이 제대로 안 되거나 메모리 문제가 발생한다. 79 | 특히 가비지 컬렉션을 지원하는 Java에서 C++ 테크를 탄 학생이라면 처음에는 메모리가 줄줄 새는 프로그램을 만들게 될 것이다. 80 | 반면 C++ 스타일로 다른 객체지향 언어에서 프로그래밍을 하는 경우 특별히 안 될 것은 없지만, 해당 언어의 스타일로 작성한 코드에 비해 시간이 많이 걸리고 너저분해 보이며 클래스 구조가 경직되어 수정하기 어려워진다. 81 | 소멸자가 호출되지 않는 등의 차이점은 있지만 심각한 문제가 되는 경우는 많지 않다. 82 | 대표적인 예가 함수 내부에서 객체를 동적으로 생성해서 그 포인터를 반환하는 것. 83 | C++에서는 이는 메모리 문제를 일으키기 딱 맞는 방식이라서 클래스 디자인 단계에서 이런 종류의 함수가 필요없게 하기 위한 고려가 필요하다. 84 | 거의 대부분의 프로그램은 실행되고 있는 코드의 각 분기점에 대한 변수를 스택 영역에 저장하는데, 한 함수의 실행이 완료되면 그 함수의 스택 영역 변수를 위한 메모리는 모두 삭제된다. 85 | 그리고 이 변수는 쓰레기 데이터로 남아있다가 다른 함수를 호출할 때 덮어씌워진다. 86 | 해당 함수가 끝나더라도 공유 자원과 같은 특정 데이터를 유지하려면 힙 영역에 할당해야 한다. 87 | 그러나 가비지 컬렉션이 자동으로 되는 언어에서는 매우 흔히 사용되는 방법이다. 88 | 이런 차이 때문에, Java, C# 등의 언어를 먼저 접한 프로그래머들은 C++의 객체지향이 짝퉁이라며 싫어하기도 한다. 89 | 하지만 객체지향 프로그래밍 언어임을 전면에 내세우는 Java나 C#과 달리, 객체지향 패러다임도 지원하는 멀티패러다임 언어 C++ 입장에서는 얼마나 순수하게 객체지향의 이상을 잘 따르는가보다 C++가 제공하는 다른 패러다임까지 아우르는 내적 일관성이 더 중요하므로 해당 언어들과 C++를 동일선상에 놓고 비교할 수는 없다. 90 | 이러한 차이가 생기는 것은 대부분의 객체지향 언어는 직접적으로 Smalltalk의 영향을 받은 반면, C++는 Smalltalk보다 먼저 객체지향의 초보적인 개념을 제시한 시뮬레이션 전용 언어인 Simula에서 직접 영향을 받았기 때문이다. 91 | 이는 C 프로그램과의 호환성을 고려한 결과이기도 하지만, 기본적으로 C++에서 프로그램의 성능을 희생시키지 않기 위해서였다. 92 | Smalltalk의 경우 당시의 기술적 한계도 있고 해서 C보다 대체로 수십 배 정도 느렸고, 이는 C++에서 지향하는 결과가 아니었기 때문이다. 93 | 다만 이런 제한이 생기는 건 오래된 스타일의 C++ 코드에서나 그런 것이고, Modern C++에서는 스마트 포인터를 사용하거나 이를 move하는 방식으로 그들과 완전히 같은 문법이 구현 가능하기 때문에 더 이상 해당이 없는 사항이다. 94 | C++의 스마트 포인터는 예를 들어 한 동적 객체를 여러 소유권자가 공유하는 경우 (참조 대상에 대한 횟수를 기록하는) 레퍼런스 카운팅을 지원하는 std::shared_ptr를, 단일 소유자만 존재하는 경우 std::unique_ptr를 사용한다. 95 | 또한 레퍼런스 카운팅으로 인해 발생하는 std::shared_ptr의 순환 참조 문제를 피하기 위해서 참조만 할 뿐 소유권은 지니지 않는 std::weak_ptr을 사용한다. 96 | 더 정확히 말하자면 std::weak_ptr은 객체 대신 std::shared_ptr을 참조한다고 보면 된다. 97 | 하나의 std::shared_ptr과 다수의 std::weak_ptr을 사용하면 여러 소유권자가 하나의 객체를 공유하면서도 순환 참조 문제를 해결할 수 있다. 98 | 99 | C++ - 특징 - C++에서의 일반화 프로그래밍 100 | C++에서는 템플릿을 이용한 일반화 프로그래밍(Generic Programming)이 매우 폭넓게 사용된다. 101 | 특히 C++11을 시작으로 하는 모던 C++는 일반화 프로그래밍을 빼고 이야기하는 것이 불가능하다. 102 | 당장 매우 널리 사용되는 std::string만해도 실제로 들여다보면 std::basic_string와 같은 형태의 클래스 템플릿의 특수화에 지나지 않는다. 103 | 또, C와는 달리 배열 생성에 포인터 혹은 기본 배열 타입 대신 std::vector를 기본으로 사용하라고 가르치는데, 이 std::vector 또한 저장될 변수의 타입을 템플릿 파라미터로 받아들이는 클래스 템플릿이다. 104 | (예를 들어 std::vector) 정적 배열이 꼭 필요할 경우 std::array를 쓴다. 105 | 일반화 프로그래밍의 결과물으로는 C++ 표준 라이브러리의 일부분으로 포함된 컨테이너, STL 같은 것들이 있으므로, C++ 표준 라이브러리를 사용하는 순간 일반화 프로그래밍의 도움을 받는 것이다. 106 | 따라서 '나는 C++를 사용하지만 템플릿을 이용한 일반화 프로그래밍은 어려우니까 패스하겠다'는 말은 애초에 성립하지 않는다. 107 | 중급 이하 개발자는 이런 결과물을 일상적으로 쉽게 가져다 쓰면 되고, 직접 만들어 쓸 필요는 없다. 108 | 이는 중급 개발자 정도로는 템플릿을 사용한 일반화 프로그래밍 기법을 정확하게 적용하는 것이 무척 까다롭고, 디버깅할 때 이해 불가능한 컴파일러 메세지를 받게 되는 경우가 많아서 발견된 오류를 수정하기도 어렵기 때문이다. 109 | 이런 이유로 C++ 학습 초반에 템플릿 프로그래밍을 직접 하는 것을 피하고 기껏해야 컨테이너 클래스만 사용하는 습관이 들다 보니, C++는 객체지향 언어이고 STL이라는 템플릿 라이브러리를 덤으로 쓸 수 있는 정도라는 오해가 널리 퍼진 것이라 생각된다. 110 | 하지만, 특수 목적의 컨테이너를 설계하거나 범용 라이브러리를 설계하는 수준의 고급 개발자가 되려면 템플릿을 사용한 일반화 프로그래밍을 해야 한다. 111 | Java나 C\#에서 찾아볼 수 있는 Generics가 지금 설명한 C++ 일반화 프로그래밍의 아주 제한된 형태의 적용례에 해당한다. 112 | 113 | C++ - 특징 - C++에서의 일반화 프로그래밍 - 템플릿 메타 프로그래밍 114 | TMP, Template Meta Programming 115 | 템플릿 문법을 응용해서 컴파일 시점에 자동 코드 생성 및 계산 같은 것을 한다는 개념이다. 116 | 영문위키백과 배우기 어렵고 알아보기도 힘들고, 오류 찾기도 힘들다. 117 | 당연히 C++의 템플릿을 모를 경우에는 아예 이해할 수가 없는 개념이기도 하다. 118 | 하지만 알아두면 은근 써먹을 데가 많다. 119 | 예를 들어, 피보나치 수열을 템플릿을 이용하여 컴파일 시점에 계산하는 코드는 다음과 같이 쓸 수 있다. 120 | constepxr을 활용하면 더 간결하게 쓸 수 있다. 121 | 여기서 arr은 길이가 13인 배열이 된다. 122 | 템플릿을 남용하면 바이너리 크기가 n배로 증가하는 참사가 발생할 수도 있다. 123 | 이럴 경우 명령어 캐시의 실패 확률이 늘어나서 오히려 성능이 하락할 수도 있다. 124 | 하지만 제대로 구현하면 바이너리 크기에서 손해를 보지 않으면서도 컴파일 시점에 다양한 처리나 계산을 할 수 있기에 라이브러리 구현에 종종 이용된다. 125 | 그리고 처음에는 너무 병맛이라 입에서 욕이 튀어나올 수 있다. 126 | 악용에 가까운 테크닉으로는 다음이 있다. 127 | SFINAE(Substitution Failure Is Not An Error): 함수를 오버로딩 하는데 있어 조건에 따라 일부러 문법적으로 틀린 템플릿의 구현 코드를 발생시켜 틀리지 않은 문법이 되는 특정 오버로드만 선택되게 만드는 테크닉이다. 128 | C++ 문법의 틈새에 존재하는 문법 오류이지만 컴파일 에러가 아닌 상황을 적극 활용하는 것이다. 129 | 직역하면 '대입 실패가 에러라는 뜻은 아니다'라는 뜻이다. 130 | Expression Templates: 디자인 패턴의 일종인 Proxy pattern 기반의 Lazy evaluation이 적용되는 효율적인 계산 코드를 컴파일 시점에 자동으로 생성하는 테크닉. 일반적으로 연산 도중의 임시 객체 생성 문제를 이 기법을 통해 해결하는 경우가 있다. 131 | RVO(Return Value Optimization)를 감안하더라도 C++ 특성상 연산자를 활용하는 과정에서, 직접적인 연산을 시도하면 임시 객체의 생성을 완전히 막을 수는 없기 때문이다. 132 | 이 개념은 C++ 템플릿이 코드를 컴파일 시점에 확장하는 방식이라는 것과 비타입 인수도 줄 수 있다는 것을 이용한다는 점을 이용하는 것으로 다른 언어에서는 비슷한 것도 찾기 힘들다. 133 | 전술한대로 Java나 C\#에 있는 제네릭은 TMP가 아닌 일반화 프로그래밍(Generic Programming)의 개념이다. 134 | 같은 템플릿 문법을 사용하지만 앞 문단에서 강조한 일반화 프로그래밍과는 엄연히 목표가 다르다. 135 | 일반화 프로그래밍이 코드의 범용성 증대를 목표로 한다면 템플릿 메타 프로그래밍은 컴파일러를 고문해 어떻게든 실행시간의 이득을 얻은 것을 목표로 한다. 136 | 근본적으로 C++의 템플릿 문법이 compile-time turing complete하기 때문에 이런 일이 가능한 것이다. 137 | C++ 안에 컴파일 타임 전용의 또 다른 언어가 숨어있는 것과 같은 상황이다. 138 | 139 | C++ - 특징 - 성능 140 | C는 유닉스라는 OS를 만들기 위해 어셈블리 대체용으로 만들어진 언어라, 머신 컨트롤의 저수준 작업이 주된 임무 중 하나였다. 141 | 그리고, C++은 그 이름에서 보이듯이 사실상 C를 대체하기 위한 언어였기 때문에 C가 제공하던 머신 컨트롤의 저수준 작업들을 포기하지 않고 그대로 지원한다. 142 | 거기다 그 위에 여러 가지 추상적인 고수준 기능들을 집어넣어 추상적인 시스템 위에서만 노는 게 아니라, 저수준의 기계 제어까지 가능한 추상화라는 요상한 철학을 지지한다. 143 | 그래서, Java 같은 언어들이 객체 지향 프로그래밍을 구현하면서 동적 바인딩(C++의 가상 함수)을 디폴트로 쓰고 쓰레기 수집을 지원할 때 C++은 정적 바인딩을 디폴트로 하고 수동 메모리 관리를 유지한 것이다. 144 | 일반적으로 추상화 수준이 높은 언어일수록 프로그래머 머리로 해야할 구체적인 것들을 컴퓨터가 대신 해주고, 이것이 항상 최적화된 방식은 아니기 때문에 프로그램의 실행 속도가 상대적으로 느리게 마련이지만, C++ 프로그램은 위와 같은 이유로 성능 하락이 거의 없다. 145 | 추상화의 가장 큰 이유와 장점은 그것을 추상화시킴으로서 그 아래 감춰진 디테일한 부분을 신경쓸 필요가 없게 만드는 것이다. 146 | 따라서 저수준 제어와 고수준 추상화의 두 가지 개념은 서로 완전히 충돌하는 부분이다. 147 | C++는 저수준 제어를 포기하지 않았기 때문에 프로그래머는 C++로 저수준 작업을 할 때는 디테일한 부분까지 신경써야만 한다. 148 | 반대로 C++에서 고수준 기능을 사용하려면 프로그래머가 저런 부분을 감안하여 C++ 방식으로 변형되어 적용된 코딩 문화(RAII 등)를 알고 있어야 한다. 149 | 템플릿이 사용된 모든 타입에 대해 컴파일 시간에 확장하도록 설계된 이유 또한 실행 성능을 포기하지 않기 위해서이다. 150 | C++과 비슷한 정도의 기능을 가진 언어 중에서 C++만큼 빠른 실행 성능을 내는 언어 구현은 흔치 않다. 151 | 대신 프로그래머가 언어의 이상한 부분까지 신경쓰지 않으면 안 되는 디자인이 되어 제대로 쓰는 게 굉장히 어려운 언어가 되고 말았다. 152 | 뭔가 딜레마 같지만 C++과 비슷한 정도의 고수준 기능을 제공하는 언어는 절대로 C++만큼 복잡하지 않다. 153 | 덤으로, 템플릿 같은 경우엔 실행 성능을 포기하지 않는 대신 컴파일 시간을 심각하게 포기했다. 154 | 심지어 디버깅도 힘들다. 155 | 다만 디버그 문제는 자기가 원하는 템플릿에 맞춰 중단점을 거는 게 가능해지는 등 많이 개선된 편이다. 156 | 애초에 C 언어의 기능을 모두 포함했던 이유는 생산성과 함께 C를 대체하겠다는 두마리의 토끼가 목적이었기 때문이다. 157 | 그러나, OS를 만드는 유닉스 커뮤니티들이 C++로의 전환을 거부해서 한마리 토끼는 놓쳤고... 그럼에도 Java라는 강력한 언어가 등장하기 전까지는 C에 비해 압도적인 생산성으로 어플리케이션 소프트웨어 쪽에서 순식간에 대세언어가 되었으나... 158 | Java의 등장과 각종 스크립트 언어들의 부상, 그리고 비주얼 베이직에서 Python으로 이어지는 하이퍼 고 생산성 언어들의 등쌀에 현재는 포지션이 좀 애매해진 경향이 있다. 159 | 애초에 C의 기능을 전부 포함했던게 공짜로 된 것이 아니라 그만큼 복잡해지고, 컴파일 속도까지 희생하는 역효과도 포함하고 있었고, 덕분에 Java나 C# 등의 기타 고생산성 언어들에 비해 생산성은 떨어지면서 정작 노리고 있던 C의 대체도 날아간 상황. 160 | 현재는 클라이언트 쪽에서는 퍼포먼스가 엄청나게 중요하면서 동시에 개발속도도 크리티컬한 게임, 포토샵, 웹 브라우저 등의 데스크탑 어플리케이션, 업무 연속성이 중요한 금융권 IT망 및 금융공학에서 주로 사용된다. 161 | 사실 그 외에도 퍼포먼스를 중시하는 경우 여전히 많이 사용된다. 162 | 구글에서도 상당히 많이 사용하는 언어이다. 163 | 이미 구글에서 2009년에 개발한 컴파일 기반 언어인 Go가 나와 있었는데도 텐서플로우가 C++로 개발되었다는 점이 하나의 예시이다. 164 | 165 | C++ - 특징 - 단점 - 난이도 166 | 선요약을 하자면 기능이 다양하고, 성능이 프로그래밍 언어 중 손에 꼽힐 정도로 좋지만 그만큼 양이 방대하고 배우기가 어렵다. 167 | 그리고 방대한 기능이나 특성을 잘 활용하는 것도 어렵다. 168 | 그래서 중도 포기하기 쉽다. 169 | 또한 C++11이 발표된 2011년을 기점으로 매 3년마다 개정된 표준을 발표하는 것이 관례화 되면서, 기능과 성능은 더 늘어나거나 개선되었지만 그만큼 배워야 할 것은 더욱 늘어나게 되었다. 170 | Java나 C언어에 비해 C++는 변화의 폭이 제법 큰 편이기 때문이다. 171 | C++을 배우려는 초보자가 인터넷에 문의를 해보면 보통 초보자용 1개, 중급자용 1개, STL 1개 등등등 해서 여러 개 읽으라는 답변들이 많이 달리며, 개중에는 1000쪽이 넘어가는 책들도 있다. 172 | 물론 반드시 1000쪽짜리 책으로 공부해야 한다는 건 아니지만 C++ 교재들은 대체로 다른 언어 교재에 비해 두꺼운 편이다. 173 | C++는 자유도가 높은 언어인만큼 기능도 많고 다른 언어에 비해 구조나 설계에 제한이 적지만, 실수하기 쉽고 설계가 어렵다는 단점이 있다. 174 | 다른 언어도 마찬가지이지만 특히 C++는 교재를 꼼꼼히 공부한다고 해도 한참 부족하다. 175 | Boost와 같이 잘 설계된 라이브러리나 여러 소프트웨어의 소스 코드를 참고하고, 직접 소프트웨어를 설계하고 제작하여 실무 경험을 쌓는 것이 실력을 향상시키는데 있어 매우 중요하다. 176 | C++11 이후 점차 추가되어가는 표준 라이브러리 기능들을 사용한 코드를 보면 당최 C와 기반이 같은 언어라고는 생각이 들지 않을 정도로 차이가 크다. 177 | 이는 3년마다 타 언어의 장점을 흡수하고 단점을 개선하면서 더더욱 심화될 수 있는데, 기존의 C++의 스타일과 많이 달라지고 있기 때문에 잘 알아둘 필요가 있다. 178 | C++98을 잘 알고 있다는 가정 하에, 모던 C++의 새로운 기능을 배우고 싶다면 이들을 자세히 구글링하여 찾고 부족한 내용은 C++ 표준 라이브러리를 정리한 사이트에서 알아보는 것이, 가장 최신의 C++ 기능들을 빠르게 익힐 수 있는 방법이다. 179 | C++에서 할 수 있는 것을 다 할 수 있으면서 좀 더 쉽게 다룰 수 있도록 C++을 리엔지니어링해서 만든 D언어도 있지만, 인지도가 적고 퍼포먼스를 위해 GC(쓰레기 수집)를 사용하지 않을 때 제한되는 사항 때문에 성장이 정체되어 있다. 180 | 2010년에는 모질라 재단이 만든 Rust 언어가 발표되고 2015년에 정식판이 나왔는데, TIOBE 검색 순위상으로는 D언어보다도 떨어지지만, 2017년 Stack Overflow 사이트의 설문조사에서 가장 좋아하는 언어 1위를 달성했다. 181 | C언어와 같거나 빠른 속도를 목표로 하여 GC를 배제했고, 메모리 안정성을 최우선시하여 객체의 수명 관리를 컴파일 타임에 모두 결정할 수 있도록 설계되었기 때문에 C++의 실질적인 대안이 될 수 있는 비전 있는 언어로 평가받고 있다. 182 | 그러나 사용할 수 있는 안정적인 라이브러리가 많이 부족하고 기존 소프트웨어 인프라는 이미 다른 언어가 차지하고 있어서, 소프트웨어 시장 내 수요가 적으며 전문 인력을 구하기 어렵다. 183 | C++도 2011년 이후로 3년마다 새 표준이 나오며 개정되고 있기 때문에, C++를 대체하기까지는 오랜 시간이 걸릴 것으로 보인다. 184 | 185 | C++ - 특징 - 단점 - 애매한 위치 186 | 리눅스 진영의 주축인 리누스 토르발스가 메일링 리스트를 통해 언급한 2007년도 비판이 자주 인용된다. 187 | 리누스 토르발스에 의하면 C++는 어중간한 지점에 위치한 언어라고 한다. 188 | 프로토타이핑 용도나 단순한 GUI 프로그래밍 용도로 사용하기에는 C++가 일을 충분히 쉽게 하도록 도와주는 친절한 언어가 아니고, 반대로 단순하고 직접적인 구조의 프로그래밍을 장려하는 C언어처럼 날씬한 운영 체제 프로그래밍용 언어도 아니라는 것이다. 189 | 다만 리누스 토르발스가 OS 개발자인 만큼 C를 선호할 수밖에 없다는 점과 해당 발언이 모던 C++ 이전의 비판임을 참고해서 이해해야 한다. 190 | 하지만, 아무리 C++이 예전과는 다르게 3년마다 표준을 내놓으면서 발전한다 해도 점유율은 생산성이 높은 다른 언어나 도구에 밀려 꾸준히 떨어지고 있다. 191 | 오늘날 소프트웨어 시장이 데스크톱 애플리케이션 중심에서 웹 애플리케이션 중심으로 변화한 것도 점유율 하락에 영향을 미쳤다. 192 | 다만 Tensorflow나 게임, 드라이버, 임베디드가 C++로 개발되고 있는 것과 마찬가지로 성능이나 자원 절약이 최우선시되는 경우 C/C++가 유일한 선택지이기 때문에 많은 프로젝트에서 여전히 사용하고 있다. 193 | 194 | C++ - 특징 - 단점 - 성능 저하 요소 195 | C++의 고성능에 대한 철학은 흔히 "don't pay for what you don't use", 즉 성능에 군더더기 없는 기능으로 대표된다. 196 | 하지만 두 가지 언어 요소가 이를 정면으로 어기는 기능으로 여겨지는데, 하나는 RTTI(Run-Time Type Information)이고, 다른 하나가 바로 예외(Exception) 이다. 197 | 198 | C++ - 특징 - 단점 - 성능 저하 요소 - RTTI 199 | RTTI(Run-Time Type Information)는 컴파일 타임이 아니라 런타임에 객체의 타입이 결정되는 C++의 매커니즘이다. 200 | 프로그램이 실행될 때, 객체에 대한 정보를 저장하고 확인해야 하기 때문에 오버헤드가 발생한다. 201 | 다음 문법이 대표적인 예이다. 202 | - dynamic_cast 203 | - virtual 204 | 의 경우 50% 정도의 성능 하락이 있을 수 있지만, 현대 컴퓨터에서는 분기 예측을 잘 활용하여 평균 5~10% 정도의 성능 하락을 보여준다. 205 | 그리고 이러한 성능 하락은 어디까지나 함수 호출 비용으로만 계산한 것이기 때문에 특수한 상황이 아니라면 고민하지 않아도 된다. 206 | 많은 소프트웨어가 이 문법을 자주 사용한다. 207 | 208 | C++ - 특징 - 단점 - 성능 저하 요소 - 예외 209 | 예외도 마찬가지로, 설계상 예외 핸들러를 찾기 위해 (RTTI와 동일한 맥락으로) 던져지는 예외의 타입별로 타입 캐스팅을 해야 하기 때문에 런타임 타입 정보가 필요하다. 210 | 따라서 예외를 던질 때마다 적지 않은 성능 패널티가 부과된다. 211 | 심지어 예전에는 try 블럭을 설치하는 것과, 소멸자가 있는 오브젝트를 정의하는 것만으로도 프로그램 성능이 크게 하락했었다. 212 | 최신 컴파일러는 zero-cost exception을 사용하기 때문에 성능 하락이 거의 없다. 213 | 현대 컴파일러에서 if문 처리는 분기 예측에 따라 1~20 cpu cycle를 소모하고, 예외처리는 대략 5000 cpu cycle를 소모한다#는 점을 고려하여, 불필요한 예외는 사용하지 말아야 하며 성능이 중요한 부분에서만 예외 처리를 사용하지 않는 것을 추천한다. 214 | RTTI와 달리 C++의 표준 라이브러리를 사용하고 에러 처리를 동반하는 한 예외는 현실적으로 피할 수 없다. 215 | C++에서 객체의 생성이나 복사를 실패시킬 수 있는 문법적 기능은 예외가 유일하며 표준 라이브러리는 이를 적극적으로 활용하기 때문이다. 216 | 에러 처리 수단은 수많은 프로그래밍 언어의 핵심 매커니즘이다. 217 | 하지만 이런 상당한 단점이 있게 되자, 대규모 프로젝트에서는 성능 상의 이유로 예외의 사용을 금지하게 되고, 오히려 C에서 흔히 쓰는 에러코드 등의 매커니즘으로 회귀하게 되었다. 218 | 심지어 에러 처리를 일관적으로 예외로 하던 표준마저도 어느 정도 스탠스를 바꾸어, C++17의 filesystem 라이브러리의 경우 예외 처리와 에러코드용 인터페이스를 혼용해서 제공해버릴 정도로 C++의 예외 처리는 처리 비용이 상당하다. 219 | 이렇게 성능 상의 문제로 예외 처리를 기피하는 상황이 발생하자, 아예 에러코드 방식을 확장시킨 Boost.Outcome 혹은 std::expected 등으로 발전하려고 하고 있다. 220 | 타입 캐스팅을 포기하고 에러코드와 예외의 장점을 섞은 표준안이 제안되고 있으므로 #P0709 언젠간 개선되리라는 희망을 가질 수는 있겠지만, 아직도 많은 논의가 계속되고 있기 때문에# 당분간은 적용이 요원하다. 221 | 222 | C++ - 역사 - 클래식 C++ - C with Classes (1979년) 223 | 1979년에 비아르네 스트로우스트루프가 속도가 느리지만 객체 지향적인 언어인 Simula의 컨셉을 C언어에 접목시키면서 C with Classes라는 이름으로 만들었다. 224 | 225 | C++ - 역사 - 클래식 C++ - C++ (1983년) 226 | 1983년에 가상 함수, 연산자 오버로딩, 참조, const, new/delete 연산자 등을 포함한 새로운 기능들이 추가되면서 언어 이름도 C with Classes에서 C++로 변경되었다. 227 | 이 시점에서 이미 클래식 C++의 틀은 완전히 잡혔다고 할 수 있으며, 이때까지는 거의 스트로우스트루프가 언어 개발을 전담하다시피 했다. 228 | 1985년에 본인이 쓴 책인 The C++ Programming Language를 통해 C++라는 언어를 정의하여 레퍼런스 컴파일러를 배포하는 식으로 개발되었다. 229 | 한편, 컴파일러 쪽에서는 백엔드는 여전히 C 컴파일러이지만 프론트엔드만 Cfront라는 이름으로 새로 개발되었다. 230 | 231 | C++ - 역사 - 클래식 C++ - C++ 2.0 (1989년) 232 | 1989년에 다중 상속, 추상 클래스, static 멤버 함수, const 멤버 함수 및 protected 멤버 등의 새로운 기능들이 추가된 C++ 2.0이 발표되었으며, 컴파일러의 프론트엔드도 Cfront 2.0으로 업그레이드되었다. 233 | 1990년에 C++ 2.0에 추가된 기능 외에 템플릿, 예외, 네임스페이스, new casts 및 bool 타입 등의 새로운 기능들이 추가된 '주석이 달린 C++ 레퍼런스 메뉴얼'이 발표되었고 1991년에 컴파일러 프론트엔드가 Cfront 3.0으로 업그레이드되었으며, The C++ Programming Language의 첫 번째 개정판이 발행되었다. 234 | 235 | C++ - 역사 - 클래식 C++ - C++98 (1998년) 236 | 1998년에 최종 승인된 C++의 첫 공식 표준안으로, C++ 2.0 이후 C++가 안정적으로 정착하고 수요가 폭증함에 따라 여러 회사에서 상업용으로 컴파일러를 만들었고, 이에 따라 코드가 컴파일러에 따라 중구난방이 되는 것을 막기 위해 표준화의 필요성이 제기된다. 237 | 그래서 1990년에 ANSI에서 C++ 표준화를 위한 위원회가 설립되었으나 1991년에 ISO로 넘기면서 스트로우스트루프를 비롯한 프로그래밍 언어학자 및 컴파일러 제조사들을 모아 표준화 작업을 하기 시작한다. 238 | 그렇게 C++의 표준안이 ISO/IEC 14882:1998라는 공식 명칭으로 처음 제정되었으며, 이를 줄여 C++98이라 부른다. 239 | 240 | C++ - 역사 - 클래식 C++ - C++03 (2003년) 241 | 2003년에 C++98 문서의 애매모호했던 부분들을 보완한 C++03이 ISO/IEC 14882:2003라는 정식 명칭으로 제정되었는데, 이는 그냥 표준화 문서상 불명확했던 것을 교정한 버전이다. 242 | 예를 들어 std::vector가 배열처럼 연속된 메모리를 차지하도록 표준에 명시했다. 243 | 사실 당시 컴파일러들 대다수가 이미 C++03 제정 이전부터 이러한 부분들을 잘 구현한지라, 실제 프로그래머 입장에서 변한 건 없다. 244 | 245 | C++ - 역사 - 모던 C++ 246 | 각종 주요 컴파일러들과 모던 C++의 호환성은 여기서 볼 수 있다. 247 | 248 | C++ - 역사 - 모던 C++ - C++TR1 (2007년) 249 | 2005년 6월 24일에 표준 라이브러리를 확장하는 것을 골자로 하는 C++ 테크니컬 리포트의 초안이 작성되어 2007년 11월에 제정되었다. 250 | 첫 번째 테크니컬 리포트라고 해서 C++TR1으로 알려져 있는데 혹자는 이를 표준안과 동급으로 간주하고 C++07/TR1이라 부르기도 한다. 251 | 정식 명칭은 ISO/IEC TR 19768:2007이며, C++ 표준화 이후 사실상 언어에 변화를 가한 첫 번째 사양이지만 엄밀하게 표준안은 아니라서 컴파일러 제작사가 원하면 넣고 아니면 마는 수준의 선택적인 확장안이었다. 252 | 그래서인지 전부 std 네임스페이스에 들어가 있지 않고 대신 std::tr1 네임스페이스로 분리되어 들어간다. 253 | 이후 C++TR1의 기능들은 대부분 C++11 표준 사양으로 흡수된다. 254 | C++TR1 초안이 발표되기 2달 전인 2005년 4월 29일에 C++TR2의 초안에 대한 작업을 시작했었다. 255 | 여기에는 유니코드, XML/HTML, 네트워킹, 파일 시스템 등의 기능이 포함될 예정이었으나, 이는 무산되었다. 256 | 대신, 각각의 라이브러리와 기능들을 "Technical Specifications"이라는 별도의 비표준 기술 사양으로 별도로 제정하기 시작했다. 257 | 여기에는 파일 시스템, 병렬 컴퓨팅, 트랜잭셔널 메모리, 컨셉트, Range, 코루틴, 네트워킹, 모듈, 리플렉션 그리고 심지어 그래픽까지 있지만, 이러한 것들이 추후 표준에 포함될 지 또는 얼마나 수정될 지는 미정이다. 258 | C++TR2의 일부 사양이 C++11에 포함되었으며, C++17, C++20에 해당하는 기능들까지 포함되어 있는 등 실험적인 성격의 사양임을 짐작할 수 있다. 259 | 이러한 시범 사양은 std::experimental이라는 네임스페이스에 포함되어, MSVC나 Clang에서 일부 지원한다. 260 | 시범적인 사양은 이 사이트에서 확인할 수 있다. 261 | 262 | C++ - 역사 - 모던 C++ - C++11 (2011년) 263 | 새로운 기능들이 많이 포함되었던 C++TR1이 정식 표준으로 채택되지 못 해서 대부분의 프로그래머들에게 있어서 C++은 C++98 이후 13년 간 정체된 언어나 다름 없었다. 264 | 2011년 8월 12일에 최신 컴퓨팅 환경을 지원하기 위해 급격한 변화의 첫 단추를 끊은 새로운 표준안인 C++11이 ISO/IEC 14882:2011라는 정식 명칭으로 최종 승인되었다. 265 | 최종 승인되기 전까지 표준안 개발 당시엔 C++0x라 불리었는데, 2000년대 안에는 표준화가 될 것이라는 의미였다. 266 | 하지만 결국 2000년대가 끝나고 2011년 8월에서야 정식 C++ 표준이 되어서 11이 붙었다. 267 | # 여담이지만 추가된 많은 기능 중 상당수 항목들이 boost 라이브러리를 다수 참조했다. 268 | C++11에서 r-value/move, constexpr, std::initializer_list, Range-based for loop, lambda expression, 스마트 포인터, 정규표현식, 멀티쓰레드 등등 중요한 신 개념과 편의 기능들이 많이 추가되었으므로 반드시 확인할 필요가 있다. 269 | C++11에 추가된 내용만 적절히 활용해도 C++ 코드의 작성과 관리가 보다 명확하고 더 쉬워진다. 270 | C++ 표준 위원회는 C++98에서 C++11까지 업데이트가 나오는 데 시간이 매우 오래 걸린 것이 업데이트가 잘 완성된 후에 발표하려고 했던 접근 방식 때문이었다고 자평한 뒤, 이러한 완벽주의를 버리고 3년에 한 번씩 그때까지 정리된 업데이트만 발표하는 형식(기차 모델)으로 규칙적인 업데이트를 하는 것이 훨씬 생산적인 접근방식이라고 결정하였다. 271 | 272 | C++ - 역사 - 모던 C++ - C++14 (2014년) 273 | 2014년 8월에 ISO/IEC 14882:2014라는 정식 명칭으로 C++14이 제정되었다. 274 | 표준안 작성 당시 C++0x라 불리었던 C++11처럼 C++14도 C++1y라는 코드네임으로 불렸으며, 주로 C++11에 추가된 요소들을 다듬고 확장하는 데 치중한 비교적 마이너 표준안이다. 275 | 276 | C++ - 역사 - 모던 C++ - C++17 (2017년) 277 | 2017년 12월에 C++1z로 알려졌던 C++17 표준이 ISO/IEC 14882:2017이라는 정식 명칭으로 최종 승인되었다. 278 | C++11의 추가 요소들을 다듬고 향상시키는데 주력했던 C++14에 비해, C++17은 표준 라이브러리의 새로운 기능에 비교적 주력한다. 279 | 초안 단계에서부터 논란이 많은 표준안이기도 하다. 280 | C++11/14의 실정에 맞추어 옛날 기능을 삭제하자는 안이 많기 때문인데, deprecated 판정을 받은 std::auto_ptr이나 삼중자(trigraph) 등이 삭제되었다. 281 | 이는 옛 코드에 대한 호환성을 포기하는 것이기 때문에, 오래된 코드들이 최신 컴파일러에서 컴파일되지 않을 가능성이 크다. 282 | 이 때문에 IBM에서 문자체계의 문제를 내세워 삼중자를 제거하지 말라고 회사 차원에서 표준화 위원회에 진정서를 제출했었다. 283 | C++17에는 파일 시스템, STL 병렬 알고리즘 처리 등이 추가되었다. 284 | 그외의 새로운 기능들은 이곳에 잘 정리되어 있다. 285 | 예를 들면 C++17에 추가된 structured binding을 잘 활용하면 두 개 이상의 값을 반환받을때, 값들을 선언과 동시에 초기화하는 기능을 이용할 수 있다. 286 | 287 | C++ - 역사 - 모던 C++ - C++20 (2020년) 288 | 더 놀라운 점은 C++20에 추가된 기능들과 C++20에 다 반영되지 못한 대신 다음 C++ 표준에 포함될 예정인 기능들이 대부분 C++TR2 제안서에 이미 언급되어 있던 사양이라는 특징이 있다. 289 | 표준화로서 최소 15년만에 빛을 발하게 된 셈. 290 | 291 | C++ - 방언 및 확장 - C++/CLI 292 | 2005년 비주얼 스튜디오 2005에 도입된 .NET Framework의 CLR에 맞물려 동작하는 C++. 보통 프레임워크 정도로 제공되는 다른 라이브러리와 달리 .NET의 메모리 구조에 맞추어 언어 자체가 다르다. 293 | 2002년에 비주얼 스튜디오 .NET 2002에 도입되었던 Managed Extensions for C++는 정말 못 써먹을 언어였기 때문에 Managed C++을 대체하기 위한 언어로 나왔으며, 적어도 스펙상으로는 게임을 만들기에도 부족함이 없는 고속의 언어임에도 생산성은 C++에 비해서 높다고 한다. 294 | 특히 C\#과 C++를 이어주는 래퍼 등의 모듈을 만들기에는 아주 제격이며, C/C++로 만들어진 프로젝트를 시간적 여유를 두고 닷넷 기반으로 바꾸는 용도로도 많이 쓰이고 있다. 295 | 필요에 따라 단계적으로 모듈을 바꿔치기 하다보면 어느새 순수 닷넷 애플리케이션 완성. 그러나 지원 및 이식성이 떨어져서 업계 표준으로 쓰기에는 무리다. 296 | C++/CLI 코드 내에서는 관리와 비관리 클래스를 혼용할 수 있으므로 래핑 없이 모든 모듈을 C++/CLI로 작성해도 되지만, C++/CLI 내의 C++ 클래스는 순수 네이티브 라이브러리에서 만들어진 C++ 클래스에 비해 성능이 다소 떨어진다. 297 | 따라서 성능이 중요한 모듈은 별도의 네이티브 코드로 작성하고, C++/CLI는 이 모듈의 래핑을 담당하는 모듈만을 작성하는 것이 좋다. 298 | 여담이지만 .NET 출시 당시 마이크로소프트가 Managed 언어를 강력하게 밀어줘서(C\# 등) 기존에 쓰이던 Win32 API C++나 MFC는 찬밥 신세라는 인상을 줬다. 299 | 특히 닷넷 기술이 막 도입되던 비주얼 스튜디오 2005 당시 C++와 C#을 비교해 보면 대놓고 C++를 죽이려 한다는 느낌이 팍팍 들었을 정도. (하지만 MS가 자사의 핵심 코드를 .NET으로 바꾸거나 핵심 플랫폼 기능들을 열어주거나 한 케이스가 거의 없다.) VS 2008부터는 지원이 다시 강화되는 추세이며, C++11, 14, 17 지원 및 C++ AMP의 도입 등 여러가지 확장을 하고 있다. 300 | 물론 이것도 예전에 비해 나아졌다 수준이고, 인텔리센스나 코드 리팩토링 등의 기능을 보면 여전히 C#에 비해 지원이 미흡하다. 301 | 특히 언리얼 엔진으로 비주얼 스튜디오에서 C++ 코딩을 하다 보면 그 끔찍하게 느린 인텔리센스 속도에 경악하게 된다. 302 | 303 | C++ - 방언 및 확장 - CUDA 304 | 2007년 6월에 발표된 NVIDIA의 GPU에서 동작하는 C++ 기반 GPGPU 언어. 305 | 306 | C++ - 방언 및 확장 - OpenCL 307 | 2009년 8월에 발표된 개방형 GPGPU 언어. 308 | 원래는 C 기반이었으나 2015년 11월 16일에 발표된 OpenCL 2.1부터 C++14를 기반으로 문법이 확장되었다. 309 | 310 | C++ - 방언 및 확장 - C++/CX 311 | 2012년에 WinRT 및 XAML을 지원하기 위해 마이크로소프트에서 고안한 확장 언어. 라이브러리는 Windows Runtime C++ Template Library(WRL)을 사용했으나 2015년 6월 23일에 발표된 C++/WinRT로 대체되었다. 312 | 313 | C++ - 도서 314 | C++는 초기에 배울 내용이 무척 많고 최종 목표로 하는 어플리케이션의 종류에 따라서 중상급 레벨에서 가는 길이 크게 갈리기 때문에, 어디에서 시작할 것인가가 꽤나 학습 방향에 중요하게 작용해서 입문 및 초급자용 도서 추천이 매우 곤란하다. 315 | 거기에 몇 년도 C++ 버전을 기준으로 썼는지도 고려해야 한다. 316 | 아래의 도서들은 한국어 번역본이 존재하는 도서를 우선시하였다. 317 | 사족으로, "Visual C++"이라고 굳이 제목에 Visual을 넣는 책들은 조금 오래된 서적들이니 주의할 것. 318 | "C/C++"이라고 C언어와 C++을 혼용해서 서술하거나, 명색이 C++ 참고서라면서 정작 내용은 C언어에 대한 것만으로 절반 가까이 채운 책들도 있는데, 이런 종류 역시 별로 추천하지 않는다. 319 | 320 | C++ - 관련 문서 321 | 인라인 함수 322 | STL 323 | Boost 324 | 템플릿 325 | 컴퓨터공학과 326 | 객체 지향 프로그래밍 327 | 328 | C++ - 외부 링크 329 | 레퍼런스 위키 사이트 330 | 비아르네 스트로우스트루프의 C++11 FAQ 331 | Classpert C++ 과정 332 | 가장 최근에 나온 C++을 기준으로 계속 업데이트되는 가이드라인 333 | -------------------------------------------------------------------------------- /test_data/test5.json: -------------------------------------------------------------------------------- 1 | {"namespace": 0, "title": "C++", "text": "[include(틀:하위 문서, top1=C++/문법)]\n\n[include(틀:프로그래밍 언어)]\n||<-5>
'''{{{#white TIOBE 선정 올해의 프로그래밍 언어}}}''' ||\n|| ''없음'' || → || 2003년[br][[C++]] || → || 2004년[br][[PHP]] ||\n[[파일:C++ 로고.svg|width=190&align=right]]\n[목차]\n\n== 개요 ==\n## 아래 예제 부분을 수정 전 https://namu.wiki/thread/AStimulatingAndRomanticLaugh 토론을 반드시 확인하고 수정하시기 바랍니다.\n## http://www.stroustrup.com/hello_world.c\n{{{#!syntax cpp\n#include \n\nint main () {\n std::cout << \"Hello, world!\\n\";\n}\n}}}[* 예제 코드나 대회 제출용 코드를 보면, 헤더 파일 호출 부분 아래에 {{{using namespace std;}}}를 입력하여 std 네임스페이스를 생략하는 경우가 있는데, 실무에서는 사용하지 말 것을 강력히 권장한다. 다른 네임스페이스에 같은 이름의 함수나 변수가 존재할 수 있으며, 이러한 경우 using문으로 전역 네임스페이스에 포함하면 충돌이 일어날 수 있기 때문이다. [[https://isocpp.org/wiki/faq/coding-standards#using-namespace-std|출처]]]\n[* 많은 헬로월드 예제 코드들이 std::endl을 사용하지만, std::endl은 그저 불필요한 오버헤드가 추가된 개행문자일 뿐이다. 위키러들은 쓰지 말것.[[https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rio-endl|출처]]]\n{{{#!syntax cpp\nimport std.core;\n\nusing std::cout;\n\nint main() {\n cout << \"Hello, world!\\n\";\n}\n}}}[* 헤더파일 구조 대신 C++20에 추가된 모듈을 활용한 예시이다.]\n\n\n> '''“A light-weight abstraction programming language” ''' (가볍게 추상화한 프로그래밍 언어)\n> - Bjarne Stroustrup\n\n[[C언어]]를 부분집합[* 다만, 오래된 표준은 부분집합으로 갖지 않았던 적도 있다.]으로 갖고 [[객체 지향]] 및 일반화 프로그래밍과 같은 멀티 패러다임을 지원하는 [[프로그래밍 언어]]이다. C언어의 문법과 기능을 모두 사용할 수 있다. 1979년에 [[C언어]]에서 직접적으로 파생된 C with Classes라는 이름의 언어로 시작되었다가, 1983년에 지금의 이름을 갖게 되었다.\n\n온라인 상으로 코드를 실행시켜 보고 싶다면 [[https://repl.it/languages/cpp|여기]]로.\n== 특징 ==\n비아르네 스트로우스트루프(Bjarne Stroustrup)[* [[http://www.stroustrup.com/bs_faq.html#personal|읽는 법]]. 발음을 자주 물어 보는지 아예 본인이 wav 파일로 읽는 법을 올려두었다.]가 [[C언어]]를 바탕으로 만들었다. C 계열 언어에서 \"++\"라는 것은 1을 더해서 원래 변수에 대입하라는 뜻이다.[* 간단하게 'C=C+1' 정도 의미다. [[수학교육과]] 등에서는 '다음수'라는 개념으로 가르친다. 간단히 for문에 들어가는 {{{for (i = 0; i < 10; }}}{{{+2 {{{i++}}}}}}{{{) { foo.bar(); } }}}을 생각하면 쉽다.] C는 B 언어를 계승한다는 의미에서 C가 되었는데 왜 C++가 D가 아니라 C++가 되었냐 하면 C 언어를 거의 그대로 두고 필요한 만큼만 향상시켰기 때문이다. 그래서 C에서 되는 게 C++에서도 된다. 비슷한 이름인 [[C\\#]]과의 차이도 이러한 점에서 나타난다.\n\nC++ 커뮤니티는 C++가 단순히 객체지향 프로그래밍 언어라고 분류되는 것을 오류라고 여긴다. C++의 제작자인 Bjarne Stroustrup은 '''C++가 단순한 객체 지향 프로그래밍 언어가 아니'''라고 설명했다. [[http://www.stroustrup.com/oopsla.pdf|#]] C++는 프로그래머의 자유도가 높은 언어로써, 객체 지향이나 절차 지향 등의 설계에 제한을 두지 않는다. 다만, 객체지향과 일반화 프로그래밍을 사실상 거의 주된 패턴으로 사용하기 때문에 (프로그래머 입장에서는) 객체지향 언어에 가깝다. C++에서는 객체지향 프로그래밍 패러다임과 동등한 강도로 일반화 프로그래밍 패러다임을 강조하고 있다. 스트로우스트루프의 책 The C++ Programming Language 4판을 참고하면 \"3부 추상화 메커니즘\" 단원의 절반(7개 섹션)은 객체지향, 나머지 절반(7개 섹션)은 일반화 프로그래밍에 할애하고 있다. 그리고 \"4부 표준 라이브러리\" 단원의 1/3이 [[표준 템플릿 라이브러리|STL]]이고, 2/3는 나머지 표준 라이브러리를 설명하고 있다. 쉽게 말하자면 C++는 기존의 C 문법이 대표하는 절차적 프로그래밍, 클래스가 대표하는 객체지향 프로그래밍, 템플릿이 대표하는 일반화 프로그래밍의 세 기둥으로 지지되고 있는 언어이다.\n\n유사한 의견으로 Effective C++의 저자 스콧 마이어스는 C++가 4가지 하위언어의 연합체라고 언급한다. C, 객체지향 C++, 템플릿 C++, [[표준 템플릿 라이브러리|STL]]. 현재의 모던 C++ 표준 라이브러리[* 이를 구현한 대표적인 예로는 [[GCC]]의 libstdc++, [[Clang]]의 libc++가 있다.]가 스테파노프(Stephanov)와 리(Lee)가 1990년대에 개발한 Standard Template Library(STL)의 아이디어를 많이 수용한 것은 사실이나, C++의 표준안 그 어디에도 STL이라는 표현은 등장하지 않는다. Effective C++의 저자인 스콧 마이어스(Scott Meyers)와 같이 나이 많은 거장 프로그래머들이 1990년대의 관습 그대로 STL이라는 용어를 자신의 저작물에 지속적으로 사용하는 바람에 STL이라는 용어가 아직도 널리 사용되고 있으나, STL과 C++ 표준 라이브러리의 차이가 뭔지 묻는 수많은 구글 검색 결과가 보여주듯이 초보자들에게 꽤 커다란 혼돈을 주는 요소이다. 스테파노프와 리가 직접 작성한 Hewlet-Packard 버전의 STL이나, 실질적으로 더 널리 쓰이던 Silicon Graphics 버전의 SGI STL은 더 이상 관리가 되지 않고 방치가 된 지 오래이고, SGI STL을 계승하려고 노력하던 STLPort도 개발이 중단되었다. 결국 초창기 STL의 구현체는 모두 사라지고 그 아이디어만이 살아남아서 C++의 표준 라이브러리에 흡수되었으므로, STL을 따로 떼어 지칭하는 것이 이제 의미가 없다. 각각의 '하위 언어' 들의 규칙과 구현이 전부 다르므로 복잡도가 상당히 높으며 'C with classes'라는 초기 명칭과는 한참 차이가 날 정도로 확장되었다.\n\n쓸 때는 C++라고 쓰지만 읽을 때는 시 플러스 플러스, 혹은 줄여서 시플플이라고 읽는다. [[한국]]에서는 사실상 속어에 가까운 '''씨쁠쁠'''로 불린다.(...) '[[씨뿔뿔]]'로 발음되는 경우도 많다. 연세가 꽤 있으신 교수님 중에는 간혹 '시 더블 플러스'라고 읽는 경우도 있다. 미국에서는 그냥 씨 플러스 플러스 또는 CPP(시피피)라고 읽는다.\n\n한국에서 컴퓨터공학과를 다닐 경우 배울 수 있는 프로그래밍 언어 3개 중에 속한다. 나머지 둘은 [[C(프로그래밍 언어)|C]]와 [[Java]]. 그러나 실상 C++11 이후의 모던 C++ 기능을 가르쳐주는 곳이 매우 드물어서 C++의 객체 지향만 조금 배울 수 있다. C++의 객체 지향은 다른 언어에 비해서 좀 더 복잡하다. 제대로 다루기 위해서는 별도의 서적을 참고하는 것이 권장되며, 실제 프로젝트의 코드에 대해 탐구하고 경험해보는 것이 좋다.\n=== C와의 차이점 ===\nC++의 개발이 C언어를 기반으로 이루어졌기 때문에 대부분의 C 프로그램은 C++ [[컴파일러]]에서도 문제없이 컴파일된다. 초기 C++ 컴파일러는 일단 C++ 코드를 C로 변환하고 그걸 C로 컴파일하는 방식을 사용했을 정도. 다만, C가 항상 C++의 부분집합이었던 것은 아니라서 공통적인 부분에서 몇몇 차이점이 있으며[* \"잘 짜인 C 프로그램은 C++ 컴파일러로 컴파일할 수 있어야 한다\"는 말도 1999년에 C99 표준이 나오면서 틀린 말이 되었다.], 순수 C 소스 코드를 C++로 컴파일 할 때 문제의 여지가 생길 가능성이 있다.\n\nC++는 C와 프로그래밍 패러다임이 크게 다르다. 그래서 C로 작성된 프로그램에서 C++ 방식으로 코딩하려면 해당 코드에서 C++에 새로 도입된 것을 추가하는 게 아니라, 설계부터 시작해서 완전히 새로 해야 하는 경우가 많다. ~~[[rm -rf /]]~~ C++의 객체지향이 다른 객체지향 언어에 비해 이해하기가 만만한 개념이 아닌 데다가 C++의 객체지향은 C언어를 하위 요소로서(항상 그래온 것은 아니지만) 유지하면서 여러 문법 요소를 추가했기 때문에 신경 써야 할 부분이 많다. 다른 객체지향 언어에서보다 잘 다루는데 더 많은 공부가 필요하다. 따라서, 초심자 입장에서는 '''C와 C++는 완전히 다른 언어로 파악하고 접근하는 것이 좋다.'''[* C로 프로그래밍에 발을 들어 놓은 후 C++/Java로 업그레이드(...) 테크를 타는 학생에게 C++ 프로그래밍을 해 오라 하면, C에서는 구조체라는 개념이 있더라도 잘해봐야 C++의 입출력 객체를 이용하는 정도를 넘지 못하고 절차적 프로그래밍을 그대로 따라가는 영락없는 C 스타일의 프로그램이 튀어나오기 일쑤다.] \n\nC++ → C 테크도 만만치가 않다. C → C++는 절차지향 언어의 사고방식, C++ → C는 객체지향 언어의 사고방식이 머릿속에 굳어버리기 때문이다. C++가 C의 모든 기능을 포괄하고 있으므로 C++를 할 줄 알면 C도 할 줄 안다고 생각하기 쉽지만, 사실 C++가 명시적으로 비교적 간단히 사용할 수 있도록 제공하는 기능들을 C에서는 암묵적으로 여러 가지 수많은 '트릭'을 통해서 쥐어짜내듯이 만들어 사용하는 경우가 많다. [[GNOME]]의 핵심 라이브러리인 Glib이 대표적으로 C 언어로 객체지향을 짜도록 구성되어 있다. incomplete type declaration 트릭을 이용하여 캡슐화를 흉내내고, 매크로와 컴파일러 확장을 이용해서 type-generic function을 만들어 쓰고, struct hack을 이용하여 vector를 흉내 내는 식이다. 게다가, 저런 트릭은 언어 차원에서 정식으로 제공한다기보다 말 그대로 '트릭'에 가까우므로 이상한 조건들이 붙는 경우가 종종 있고, 그것들을 정확히 파악하고 있지 않으면 상당히 찾아내기 어려운 에러를 내는 경우도 많다.\n\n그래서 많은 대학에서 컴공 1학년 1학기 때 C를 먼저 가르치고 빠르면 2학기, 늦어도 2학년에 C++를 가르치지만, 교수가 절차지향이 머리에 굳어버린다며 컴공에서 C 대신 C++와 객체를 먼저 가르치고 C는 아예 건드리지도 않고 다른 하드웨어 관련 학과에서만 가르치는 대학들도 많다. 객체지향만 배운다면 [[Java]]부터 시작하는 게 낫지만, 포인터 등을 통해 메모리와 각종 저수준(low level) 프로그래밍과 객체지향을 함께 배울 수 있기 때문이다. 컴공의 경우에는 C++를 모르면 2학년부터는 강의를 전혀 이해할 수 없기 때문에 의외로 많은 학생들이 중도포기를 하게 되며 컴공을 나왔는데도 프로그래밍을 전혀 못하는 학생들이 수두룩하게 발생하고 있다. 학교마다 다르지만 1학년때 아예 C를 배우고 2학년 1학기때 Java, 2학기때 C++ 과목이 생기는 곳도 있다. [[서울대학교]]의 경우에는 1학년 1학기에 [[Python]]으로 코딩을 입문하고(--2019년까지는 [[기계어]] -> [[어셈블리]] -> [[C언어]]라는 끔찍한 수업이었지만--), 1학년 2학기에 [[C언어]]로 어느 정도 큰 프로젝트를 짜 보고, 2학년 1학기에 C++과 [[Java]]를 배우면서 객체지향 프로그래밍을 배우게 된다. C++ 수업에 잘 적응하려면, C → Java → C++ 순으로 듣는 것을 권장한다. \n\nC를 알고 있다고 C++를 쉽게 할 수 있는 것은 아니다. 두 언어는 추구하는 설계 구조가 상당히 다르기 때문이다. C언어는 절차 지향이지만 C++는 절차 지향, 객체 지향, 일반화 프로그래밍, 함수형 프로그래밍을 모두 지원하는 언어다. 그래서 C언어를 알고 있는 사람이 C++ 초보자용 교재를 1권 끝내고 프로그램을 만들어 보라고 해도 대부분 C 방식에서 벗어나지 못한다. C++ 방식을 잘 활용하려면 [[표준 템플릿 라이브러리|STL]]까지 배운 다음 자료구조와 스트림, 템플릿 정도는 쓸 수 있어야 한다. C++이 C언어의 변형버전은 어느정도는 맞는 이야기긴 하다.\n\n한편, C, C++ 중 어디가 쉽다라던가(...) 하는 건 어디까지나 간단한 프로그램의 예일 뿐이다. 둘의 설계 구조가 다르고 성능상 미묘한 차이밖에 안 난다. C의 함수구조에서는 다중의 인자값 전달이 필수적인데 구조체에 전부 때려박더라도 전역변수가 아닌 이상 적어도 1개는 전달해야 한다. 반면에 C++ 측은 클래스의 this를 활용하면 인자 전달 없이 클래스에 속한 멤버함수 호출만 할 수 있다. 헤더참조 구조가 중복정의로 복잡해지는 건 덤. [[Node.js]] 모듈구조를 참고 해 보면 {{{module.exports}}}로만 다른 모듈과 상호작용 할 수 있는데 C 계열은 헤더를 넣으면 그 안에 있는 모든 건 상호작용되고 원치 않으면 소스파일과 분리해야 한다. 다만, C++의 경우 C++20 개정판부터 모듈 개념이 도입될 예정이므로 이러한 단점은 점차 시간이 지남에 따라 어느 정도 극복될 것이다. 다른 모듈에서 정의된 매크로는 사용하지 못하기 때문에, 매크로로 떡칠된 코드는 다 뜯어 고쳐야 할 수도 있다. 이 때문에 수많은 기존 프로젝트는 여전히 헤더를 사용할 것으로 보이며, C와의 호환성을 위해 헤더 참조 구조는 표준에서 없어지지 않을 것이다.\n\n또한 C++98 초과의 최신판은 메인을 제외한 함수에 반환값의 자료명을 꼭 명시해 주어야 한다.\n\n이외에도 C에서만 지원되는 문법이 몇 있다. 그 예로, K&R 스타일의 함수 정의 구문[* {{{f(int a, int b) { ... } }}} 를 {{{f(a, b) int a; int b; { ... } }}} 로 작성하는 것.]의 지원과 C99에서 추가된 지정 초기자(Designated Initializers) 의 일부 형태 등이 있다.\n=== C++에서의 객체지향 프로그래밍 ===\nC++는 [[객체 지향 프로그래밍]]을 지원하지만, C++의 객체지향은 다른 객체지향 언어에서와는 성격이 좀 다르다. 대부분의 객체지향 언어에서는 많은 부분을 런타임에 처리하며 메모리를 자동으로 관리하는 반면, C++에서는 최대한 많은 것을 컴파일 타임에 처리하는 것을 지향하며 메모리 등을 프로그래머가 직접 관리하게 하기 때문에 전반적인 클래스 디자인 자체가 상당한 차이를 보이게 된다. [[Java]] 등의 다른 객체지향 언어에서와 같은 방식으로 C++ 클래스를 디자인하면 거의 틀림없이 컴파일이 제대로 안 되거나 메모리 문제가 발생한다. 특히 [[가비지 컬렉션]]을 지원하는 Java에서 C++ 테크를 탄 학생이라면 처음에는 메모리가 줄줄 새는 프로그램을 만들게 될 것이다. 반면 C++ 스타일로 다른 객체지향 언어에서 프로그래밍을 하는 경우 특별히 안 될 것은 없지만, 해당 언어의 스타일로 작성한 코드에 비해 시간이 많이 걸리고 너저분해 보이며 클래스 구조가 경직되어 수정하기 어려워진다. 소멸자가 호출되지 않는 등의 차이점은 있지만 심각한 문제가 되는 경우는 많지 않다.\n\n대표적인 예가 함수 내부에서 객체를 동적으로 생성해서 그 포인터를 반환하는 것. C++에서는 이는 메모리 문제를 일으키기 딱 맞는 방식이라서 클래스 디자인 단계에서 이런 종류의 함수가 필요없게 하기 위한 고려가 필요하다. 거의 대부분의 프로그램은 실행되고 있는 코드의 각 분기점에 대한 변수를 [[스택(자료구조)|스택 영역]]에 저장하는데, 한 함수의 실행이 완료되면 그 함수의 스택 영역 변수를 위한 메모리는 모두 삭제된다. 그리고 이 변수는 쓰레기 데이터로 남아있다가 다른 함수를 호출할 때 덮어씌워진다. 해당 함수가 끝나더라도 공유 자원과 같은 특정 데이터를 유지하려면 힙 영역에 할당해야 한다. 그러나 가비지 컬렉션이 자동으로 되는 언어에서는 매우 흔히 사용되는 방법이다. 이런 차이 때문에, Java, C# 등의 언어를 먼저 접한 프로그래머들은 C++의 객체지향이 짝퉁이라며 싫어하기도 한다. 하지만 객체지향 프로그래밍 언어임을 전면에 내세우는 Java나 C#과 달리, 객체지향 패러다임'''도''' 지원하는 멀티패러다임 언어 C++ 입장에서는 얼마나 순수하게 객체지향의 이상을 잘 따르는가보다 C++가 제공하는 다른 패러다임까지 아우르는 내적 일관성이 더 중요하므로 해당 언어들과 C++를 동일선상에 놓고 비교할 수는 없다.\n\n이러한 차이가 생기는 것은 대부분의 객체지향 언어는 직접적으로 [[Smalltalk]]의 영향을 받은 반면, C++는 Smalltalk보다 먼저 객체지향의 초보적인 개념을 제시한 시뮬레이션 전용 언어인 Simula에서 직접 영향을 받았기 때문이다. 이는 C 프로그램과의 호환성을 고려한 결과이기도 하지만, 기본적으로 C++에서 프로그램의 성능을 희생시키지 않기 위해서였다. Smalltalk의 경우 당시의 기술적 한계도 있고 해서 C보다 대체로 수십 배 정도 느렸고, 이는 C++에서 지향하는 결과가 아니었기 때문이다.\n\n다만 이런 제한이 생기는 건 오래된 스타일의 C++ 코드에서나 그런 것이고, Modern C++에서는 스마트 포인터를 사용하거나 이를 move[* 원본 객체가 필요없는 경우, 새로 객체를 생성할 때 원본 객체의 포인터와 값들을 그대로 사용하여, 오버헤드 없이 기존 객체의 메모리를 재활용할 수 있도록 하는 기능이다.]하는 방식으로 그들과 완전히 같은 문법이 구현 가능하기 때문에 더 이상 해당이 없는 사항이다. C++의 스마트 포인터는 예를 들어 한 동적 객체를 여러 소유권자가 공유하는 경우 (참조 대상에 대한 횟수를 기록하는) 레퍼런스 카운팅을 지원하는 {{{std::shared_ptr}}}를, 단일 소유자만 존재하는 경우 {{{std::unique_ptr}}}를 사용한다. 또한 레퍼런스 카운팅으로 인해 발생하는 {{{std::shared_ptr}}}의 순환 참조 문제를 피하기 위해서 참조만 할 뿐 소유권은 지니지 않는 {{{std::weak_ptr}}}을 사용한다. 더 정확히 말하자면 {{{std::weak_ptr}}}은 객체 대신 {{{std::shared_ptr}}}을 참조한다고 보면 된다. 하나의 {{{std::shared_ptr}}}과 다수의 {{{std::weak_ptr}}}을 사용하면 여러 소유권자가 하나의 객체를 공유하면서도 순환 참조 문제를 해결할 수 있다.\n\n=== C++에서의 일반화 프로그래밍 ===\nC++에서는 [[템플릿]]을 이용한 [[https://en.wikipedia.org/wiki/Generic_programming|일반화 프로그래밍]](Generic Programming)이 매우 폭넓게 사용된다. 특히 C++11을 시작으로 하는 모던 C++는 일반화 프로그래밍을 빼고 이야기하는 것이 불가능하다. 당장 매우 널리 사용되는 {{{std::string}}}만해도 실제로 들여다보면 {{{std::basic_string}}}와 같은 형태의 클래스 템플릿의 특수화에 지나지 않는다. 또, C와는 달리 배열 생성에 포인터 혹은 기본 배열 타입 대신 {{{std::vector}}}를 기본으로 사용하라고 가르치는데, 이 {{{std::vector}}} 또한 저장될 변수의 타입을 템플릿 파라미터로 받아들이는 클래스 템플릿이다. (예를 들어 {{{std::vector}}}) 정적 배열이 꼭 필요할 경우 {{{std::array}}}를 쓴다.\n\n일반화 프로그래밍의 결과물으로는 C++ 표준 라이브러리의 일부분으로 포함된 컨테이너, [[표준 템플릿 라이브러리|STL]] 같은 것들이 있으므로, C++ 표준 라이브러리를 사용하는 순간 일반화 프로그래밍의 도움을 받는 것이다. 따라서 '나는 C++를 사용하지만 템플릿을 이용한 일반화 프로그래밍은 어려우니까 패스하겠다'는 말은 애초에 성립하지 않는다.\n\n중급 이하 개발자는 이런 결과물을 일상적으로 쉽게 가져다 쓰면 되고, 직접 만들어 쓸 필요는 없다. 이는 중급 개발자 정도로는 템플릿을 사용한 일반화 프로그래밍 기법을 정확하게 적용하는 것이 무척 까다롭고, 디버깅할 때 이해 불가능한 컴파일러 메세지를 받게 되는 경우가 많아서 발견된 오류를 수정하기도 어렵기 때문이다.\n\n이런 이유로 C++ 학습 초반에 템플릿 프로그래밍을 직접 하는 것을 피하고 기껏해야 컨테이너 클래스만 사용하는 습관이 들다 보니, C++는 객체지향 언어이고 [[표준 템플릿 라이브러리|STL]]이라는 템플릿 라이브러리를 덤으로 쓸 수 있는 정도라는 오해가 널리 퍼진 것이라 생각된다. 하지만, 특수 목적의 컨테이너를 설계하거나 범용 라이브러리를 설계하는 수준의 고급 개발자가 되려면 템플릿을 사용한 일반화 프로그래밍을 해야 한다.\n\n[[Java]]나 [[C\\#]]에서 찾아볼 수 있는 Generics가 지금 설명한 C++ 일반화 프로그래밍의 아주 제한된 형태의 적용례에 해당한다.\n\n==== 템플릿 메타 프로그래밍 ====\nTMP, '''T'''emplate '''M'''eta '''P'''rogramming\n\n템플릿 문법을 응용해서 컴파일 시점에 자동 코드 생성 및 계산 같은 것을 한다는 개념이다. [[https://en.wikipedia.org/wiki/Template_metaprogramming|영문위키백과]] 배우기 어렵고 알아보기도 힘들고, 오류 찾기도 힘들다. 당연히 C++의 [[템플릿]]을 모를 경우에는 아예 이해할 수가 없는 개념이기도 하다. 하지만 알아두면 은근 써먹을 데가 많다.\n\n예를 들어, [[피보나치 수열]]을 템플릿을 이용하여 컴파일 시점에 계산하는 코드는 다음과 같이 쓸 수 있다.\n{{{#!syntax cpp\ntemplate \nstruct Fibonacci\n{\n\tstatic constexpr size_t Value = Fibonacci::Value + Fibonacci::Value;\n};\n\ntemplate<>\nstruct Fibonacci<0>\n{\n\tstatic constexpr size_t Value = 0;\n};\n\ntemplate<>\nstruct Fibonacci<1>\n{\n\tstatic constexpr size_t Value = 1;\n};\n\nint arr[Fibonacci<7>::Value];\n}}}\nconstepxr을 활용하면 더 간결하게 쓸 수 있다.[* constexpr은 C++11에 추가되었지만, if constexpr은 C++17에 추가되었다.]\n{{{#!syntax cpp\ntemplate\nconstexpr size_t Fibonacci()\n{\n\tif constexpr (N < 2) return N;\n\telse return Fibonacci() + Fibonacci();\n}\n\nint arr[Fibonacci<7>()];\n}}}\n여기서 arr은 길이가 13인 배열이 된다.\n\n템플릿을 남용하면 바이너리 크기가 n배로 증가하는 참사가 발생할 수도 있다. 이럴 경우 명령어 캐시의 실패 확률이 늘어나서 오히려 성능이 하락할 수도 있다. 하지만 제대로 구현하면 바이너리 크기에서 손해를 보지 않으면서도 컴파일 시점에 다양한 처리나 계산을 할 수 있기에 라이브러리 구현에 종종 이용된다.\n\n그리고 처음에는 너무 병맛이라 입에서 욕이 튀어나올 수 있다. 악용에 가까운 테크닉으로는 다음이 있다.\n\n * SFINAE('''S'''ubstitution '''F'''ailure '''I'''s '''N'''ot '''A'''n '''E'''rror): 함수를 오버로딩 하는데 있어 조건에 따라 일부러 문법적으로 틀린 템플릿의 구현 코드를 발생시켜 틀리지 않은 문법이 되는 특정 오버로드만 선택되게 만드는 테크닉이다. C++ 문법의 틈새에 존재하는 문법 오류이지만 컴파일 에러가 아닌 상황을 적극 활용하는 것이다. 직역하면 '대입 실패가 에러라는 뜻은 아니다'라는 뜻이다.\n * Expression Templates: 디자인 패턴의 일종인 Proxy pattern 기반의 Lazy evaluation이 적용되는 효율적인 계산 코드를 컴파일 시점에 자동으로 생성하는 테크닉. 일반적으로 연산 도중의 임시 객체 생성 문제를 이 기법을 통해 해결하는 경우가 있다. RVO(Return Value Optimization)를 감안하더라도 C++ 특성상 연산자를 활용하는 과정에서, 직접적인 연산을 시도하면 임시 객체의 생성을 완전히 막을 수는 없기 때문이다.\n\n이 개념은 C++ 템플릿이 코드를 컴파일 시점에 확장하는 방식이라는 것과 비타입 인수도 줄 수 있다는 것을 이용한다는 점을 이용~~악용~~하는 것으로 다른 언어에서는 비슷한 것도 찾기 힘들다. 전술한대로 [[Java]]나 [[C\\#]]에 있는 제네릭은 TMP가 아닌 일반화 프로그래밍(Generic Programming)의 개념이다.\n\n같은 템플릿 문법을 사용하지만 앞 문단에서 강조한 일반화 프로그래밍과는 엄연히 목표가 다르다. 일반화 프로그래밍이 코드의 범용성 증대를 목표로 한다면 템플릿 메타 프로그래밍은 컴파일러를 고문해 어떻게든 실행시간의 이득을 얻은 것을 목표로 한다. 근본적으로 C++의 템플릿 문법이 compile-time [[튜링완전|turing complete]]하기 때문에 이런 일이 가능한 것이다. C++ 안에 컴파일 타임 전용의 또 다른 언어가 숨어있는 것과 같은 상황이다.\n\n=== 성능 ===\nC는 [[유닉스]]라는 OS를 만들기 위해 어셈블리 대체용으로 만들어진 언어라, 머신 컨트롤의 저수준 작업이 주된 임무 중 하나였다. 그리고, C++은 그 이름에서 보이듯이 사실상 C를 대체하기 위한 언어였기 때문에 C가 제공하던 머신 컨트롤의 저수준 작업들을 포기하지 않고 그대로 지원한다.\n\n거기다 그 위에 여러 가지 추상적인 고수준 기능들을 집어넣어 추상적인 시스템 위에서만 노는 게 아니라, 저수준의 기계 제어까지 가능한 추상화라는 요상한 철학을 지지한다. 그래서, [[Java]] 같은 언어들이 객체 지향 프로그래밍을 구현하면서 동적 바인딩(C++의 가상 함수)을 디폴트로 쓰고 [[쓰레기 수집]]을 지원할 때 C++은 정적 바인딩을 디폴트로 하고 수동 메모리 관리를 유지한 것이다. 일반적으로 추상화 수준이 높은 언어일수록 프로그래머 머리로 해야할 구체적인 것들을 컴퓨터가 대신 해주고, 이것이 항상 최적화된 방식은 아니기 때문에 프로그램의 실행 속도가 상대적으로 느리게 마련이지만, C++ 프로그램은 위와 같은 이유로 성능 하락이 거의 없다.\n\n추상화의 가장 큰 이유와 장점은 그것을 추상화시킴으로서 그 아래 감춰진 디테일한 부분을 신경쓸 필요가 없게 만드는 것이다. 따라서 저수준 제어와 고수준 추상화의 두 가지 개념은 서로 완전히 충돌하는 부분이다. C++는 저수준 제어를 포기하지 않았기 때문에 프로그래머는 C++로 저수준 작업을 할 때는 디테일한 부분까지 신경써야만 한다. 반대로 C++에서 고수준 기능을 사용하려면 프로그래머가 저런 부분을 감안하여 C++ 방식으로 변형되어 적용된 코딩 문화(RAII[* Resource Acquisition Is Initialization. 이를 직역하면 \"자원 흭득은/이 초기화다.\"는 뜻으로, 실행 흐름이 특정 범위를 벗어나면 그 안에서 할당한 자원을 다시 반납하도록 만드는 디자인 패턴이다. 해당 범위의 시작과 끝에 {{{new}}}나 {{{delete}}}를 사용하여 동적 배열과 같은 힙 영역 메모리의 관리를 직접 수행할 수도 있지만, 이를 하나의 객체에 묶음으로써 해당 범위에서 자동적으로 생성자와 소멸자가 호출되어 메모리를 자동으로 관리되도록 할 수 있다. 이러한 디자인을 이용한 설계는 메모리 누수를 예방할 수 있다는 장점이 있다. 이에 대한 대표적인 예시는 스마트 포인터인 {{{std::unique_ptr}}}나 [[뮤텍스]]인 {{{std::lock_guard}}}가 대표적인 예이다.] 등)를 알고 있어야 한다.\n\n템플릿이 사용된 모든 타입에 대해 컴파일 시간에 확장하도록 설계된 이유 또한 실행 성능을 포기하지 않기 위해서이다. C++과 비슷한 정도의 기능을 가진 언어 중에서 C++만큼 빠른 실행 성능을 내는 언어 구현은 흔치 않다. 대신 프로그래머가 언어의 이상한 부분까지 신경쓰지 않으면 안 되는 디자인이 되어 제대로 쓰는 게 굉장히 어려운 언어가 되고 말았다. 뭔가 딜레마 같지만 C++과 비슷한 정도의 고수준 기능을 제공하는 언어는 절대로 C++만큼 복잡하지 않다. 덤으로, [[템플릿]] 같은 경우엔 실행 성능을 포기하지 않는 대신 컴파일 시간을 '''심각하게''' 포기했다. 심지어 디버깅도 힘들다. 다만 디버그 문제는 자기가 원하는 템플릿에 맞춰 중단점을 거는 게 가능해지는 등 많이 개선된 편이다.\n\n애초에 C 언어의 기능을 모두 포함했던 이유는 생산성과 함께 C를 대체하겠다는 두마리의 토끼가 목적이었기 때문이다. 그러나, OS를 만드는 [[유닉스]] 커뮤니티들이 C++로의 전환을 거부해서 한마리 토끼는 놓쳤고... 그럼에도 [[Java]]라는 강력한 언어가 등장하기 전까지는 C에 비해 압도적인 생산성으로 어플리케이션 소프트웨어 쪽에서 순식간에 대세언어가 되었으나...Java의 등장과 각종 스크립트 언어들의 부상, 그리고 [[비주얼 베이직]]에서 [[Python]]으로 이어지는 하이퍼 고 생산성 언어들의 등쌀에 현재는 포지션이 좀 애매해진 경향이 있다. 애초에 C의 기능을 전부 포함했던게 공짜로 된 것이 아니라 그만큼 복잡해지고, 컴파일 속도까지 희생하는 역효과도 포함하고 있었고, 덕분에 Java나 C# 등의 기타 고생산성 언어들에 비해 생산성은 떨어지면서 정작 노리고 있던 C의 대체도 날아간 상황.\n\n현재는 클라이언트 쪽에서는 퍼포먼스가 엄청나게 중요하면서 동시에 개발속도도 크리티컬한 게임[* C#을 스트립트 언어로 쓰는 유니티 엔진도 내부 소스는 C++로 이루어져 있다. 즉, 스크립팅용으로만 [[C\\#]]을 쓰는 셈이다. 심지어 C#으로 짜놓은 코드를 C++로 변환하는 [[https://docs.unity3d.com/kr/2018.1/Manual/IL2CPP.html|IL2CPP]]라는 기능도 제공한다. ~~닷넷 프레임워크 위에 엔진 올리고 3D게임 만들다간 머리빠진다.~~ ], 포토샵, 웹 브라우저 등의 데스크탑 어플리케이션, 업무 연속성이 중요한 [[금융]]권 IT망 및 [[금융공학]]에서 주로 사용된다. 사실 그 외에도 퍼포먼스를 중시하는 경우 여전히 많이 사용된다. [[구글]]에서도 상당히 많이 사용하는 언어이다.[[https://web.archive.org/web/20111228034932/http://panela.blog-city.com/python_at_google_greg_stein__sdforum.htm|#]] 이미 구글에서 2009년에 개발한 컴파일 기반 언어인 [[Go(프로그래밍 언어)|Go]]가 나와 있었는데도 [[텐서플로우]]가 C++로 개발되었다는 점이 하나의 예시이다.\n\n=== 단점 ===\n==== 난이도 ====\n선요약을 하자면 기능이 다양하고, 성능이 프로그래밍 언어 중 손에 꼽힐 정도로 좋지만 그만큼 양이 방대하고 배우기가 어렵다. 그리고 방대한 기능이나 특성을 잘 활용하는 것도 어렵다. 그래서 중도 포기하기 쉽다. 또한 C++11이 발표된 2011년을 기점으로 매 3년마다 개정된 표준을 발표하는 것이 관례화 되면서, 기능과 성능은 더 늘어나거나 개선되었지만 그만큼 배워야 할 것은 더욱 늘어나게 되었다. [[Java]]나 [[C언어]]에 비해 C++는 변화의 폭이 제법 큰 편이기 때문이다.\n\nC++을 배우려는 초보자가 인터넷에 문의를 해보면 보통 초보자용 1개, 중급자용 1개, [[표준 템플릿 라이브러리|STL]] 1개 등등등 해서 여러 개 읽으라는 답변들이 많이 달리며, 개중에는 1000쪽이 넘어가는 책들도 있다.[* Bjarne Stroustrup이 직접 쓴 TC++PL이 1,300쪽, C++ Primer Plus가 1,700쪽이다. 그런데 TC++PL이나 Primer Plus나 둘 다 초보자에게 권할 만한 책은 아니다. TC++PL의 서문에는 아예 'C++를 시작하는 입문자에겐 이 책을 권장하지 않는다'는 말이 적혀 있다.] 물론 반드시 1000쪽짜리 책으로 공부해야 한다는 건 아니지만 C++ 교재들은 대체로 다른 언어 교재에 비해 두꺼운 편이다.\n\nC++는 자유도가 높은 언어인만큼 기능도 많고 다른 언어에 비해 구조나 설계에 제한이 적지만, 실수하기 쉽고 설계가 어렵다는 단점이 있다. 다른 언어도 마찬가지이지만 특히 C++는 교재를 꼼꼼히 공부한다고 해도 한참 부족하다. Boost와 같이 잘 설계된 라이브러리나 여러 소프트웨어의 소스 코드를 참고하고, 직접 소프트웨어를 설계하고 제작하여 실무 경험을 쌓는 것이 실력을 향상시키는데 있어 매우 중요하다.\n\nC++11 이후 점차 추가되어가는 표준 라이브러리 기능들을 사용한 코드를 보면 당최 C와 기반이 같은 언어라고는 생각이 들지 않을 정도로 차이가 크다. 이는 3년마다 타 언어의 장점을 흡수하고 단점을 개선하면서 더더욱 심화될 수 있는데, 기존의 C++의 스타일과 많이 달라지고 있기 때문에 잘 알아둘 필요가 있다. C++98을 잘 알고 있다는 가정 하에, 모던 C++의 새로운 기능을 배우고 싶다면 이들을 자세히 구글링하여 찾고 부족한 내용은 [[https://en.cppreference.com/w/|C++ 표준 라이브러리를 정리한 사이트]]에서 알아보는 것이, 가장 최신의 C++ 기능들을 빠르게 익힐 수 있는 방법이다.\n\nC++에서 할 수 있는 것을 다 할 수 있으면서 좀 더 쉽게 다룰 수 있도록 C++을 리엔지니어링해서 만든 '''[[D언어]]'''도 있지만, 인지도가 적고 퍼포먼스를 위해 GC([[쓰레기 수집]])를 사용하지 않을 때 제한되는 사항 때문에 성장이 정체되어 있다.\n\n2010년에는 [[모질라 재단]]이 만든 '''[[Rust]]''' 언어가 발표되고 2015년에 정식판이 나왔는데, [[https://www.tiobe.com/tiobe-index/|TIOBE 검색 순위]]상으로는 D언어보다도 떨어지지만, 2017년 [[Stack Overflow]] 사이트의 설문조사에서 [[https://insights.stackoverflow.com/survey/2017?utm_medium=email&utm_campaign=dev-survey-2017&utm_content=em-features&utm_source=so-owned#technology-_-most-loved-dreaded-and-wanted-languages|가장 좋아하는 언어 1위를 달성했다.]] C언어와 같거나 빠른 속도를 목표로 하여 GC를 배제했고, 메모리 안정성을 최우선시하여 객체의 수명 관리를 컴파일 타임에 모두 결정할 수 있도록[* 단, unsafe scope에서 발생한 메모리 버그나, 스마트 포인터의 순환 참조 등으로 인한 메모리 누수는 여전히 발생할 수 있다. 언어적 차원에서 이러한 실수를 덜하도록 고려되었지만, 여전히 다른 언어와 마찬가지로 항상 안전하지는 않다는 점에 유의하자.] 설계되었기 때문에 C++의 실질적인 대안이 될 수 있는 비전 있는 언어로 평가받고 있다. 그러나 사용할 수 있는 안정적인 라이브러리가 많이 부족하고 기존 소프트웨어 인프라는 이미 다른 언어가 차지하고 있어서, 소프트웨어 시장 내 수요가 적으며 전문 인력을 구하기 어렵다. C++도 2011년 이후로 3년마다 새 표준이 나오며 개정되고 있기 때문에, C++를 대체하기까지는 오랜 시간이 걸릴 것으로 보인다.\n==== 애매한 위치 ====\n[[리눅스]] 진영의 주축인 [[리누스 토르발스]]가 메일링 리스트를 통해 언급한 2007년도 비판이 자주 인용된다. 리누스 토르발스에 의하면 '''C++는 어중간한 지점에 위치한 언어'''라고 한다. 프로토타이핑 용도나 단순한 GUI 프로그래밍 용도로 사용하기에는 C++가 일을 충분히 쉽게 하도록 도와주는 친절한 언어가 아니고, 반대로 단순하고 직접적인 구조의 프로그래밍을 장려하는 [[C언어]]처럼 날씬한 [[운영 체제]] 프로그래밍용 언어도 아니라는 것이다.[[https://en.wikiquote.org/wiki/Linus_Torvalds#2007|#]] 다만 리누스 토르발스가 OS 개발자인 만큼 C를 선호할 수밖에 없다는 점과 해당 발언이 모던 C++ 이전의 비판임을 참고해서 이해해야 한다.\n\n하지만, 아무리 C++이 예전과는 다르게 3년마다 표준을 내놓으면서 발전한다 해도 점유율은 생산성이 높은 다른 언어나 도구에 밀려 꾸준히 떨어지고 있다. 오늘날 소프트웨어 시장이 데스크톱 애플리케이션 중심에서 웹 애플리케이션 중심으로 변화한 것도 점유율 하락에 영향을 미쳤다. 다만 [[Tensorflow]]나 게임, 드라이버, 임베디드가 C++로 개발되고 있는 것과 마찬가지로 성능이나 자원 절약이 최우선시되는 경우 C/C++가 유일한 선택지이기 때문에 많은 프로젝트에서 여전히 사용하고 있다.\n\n==== 성능 저하 요소 ====\nC++의 고성능에 대한 철학은 흔히 \"don't pay for what you don't use\", 즉 성능에 군더더기 없는 기능으로 대표된다. 하지만 두 가지 언어 요소가 이를 정면으로 어기는 기능으로 여겨지는데, 하나는 RTTI(Run-Time Type Information)이고, 다른 하나가 바로 예외(Exception) 이다.\n\n===== RTTI =====\nRTTI(Run-Time Type Information)는 컴파일 타임이 아니라 런타임에 객체의 타입이 결정되는 C++의 매커니즘이다. 프로그램이 실행될 때, 객체에 대한 정보를 저장하고 확인해야 하기 때문에 오버헤드가 발생한다. 다음 문법이 대표적인 예이다.\n\n - {{{dynamic_cast}}}\n - {{{virtual}}}\n\n{{{dynamic_cast}}}의 경우 상속 트리 전체를 휘젓고 다녀야 한다는 점 역시 큰 성능 문제로 꼽힌다. 하지만 이에 의존하는 언어의 기능이 거의 없기 때문에 대부분의 상황에서 성능 패널티를 피할 수 있다. 메이저 컴파일러에서 아예 기능을 제외하는 옵션을 제공하는 건 덤이다.\n\n{{{virtual}}}의 경우 50% 정도의 성능 하락이 있을 수 있지만, 현대 컴퓨터에서는 분기 예측을 잘 활용하여 평균 5~10% 정도의 성능 하락을 보여준다. 그리고 이러한 성능 하락은 어디까지나 함수 호출 비용으로만 계산한 것이기 때문에 특수한 상황이 아니라면 고민하지 않아도 된다. 많은 소프트웨어가 이 문법을 자주 사용한다.\n===== 예외 =====\n예외도 마찬가지로, 설계상 예외 핸들러를 찾기 위해 (RTTI와 동일한 맥락으로) 던져지는 예외의 타입별로 타입 캐스팅을 해야 하기 때문에 런타임 타입 정보가 필요하다.\n\n따라서 예외를 던질 때마다 적지 않은 성능 패널티가 부과된다. 심지어 예전에는 {{{try}}} 블럭을 설치하는 것과, 소멸자가 있는 오브젝트를 정의하는 것만으로도 프로그램 성능이 크게 하락했었다. 최신 컴파일러는 zero-cost exception[* 예외를 던지지 않는 실행경로에서는 아무 것도 하지 않아도 되도록 만드는 기법. 요약하면 컴파일러가 전역 에러 핸들러 테이블을 미리 만들어두어, 예외를 던지면 런타임에 해당 테이블을 참조하여 처리하는 방법이다.]을 사용하기 때문에 성능 하락이 거의 없다. 현대 컴파일러에서 {{{if}}}문 처리는 분기 예측에 따라 1~20 cpu cycle를 소모하고, '''예외처리는 대략 5000 cpu cycle를 소모한다'''[[http://ithare.com/infographics-operation-costs-in-cpu-clock-cycles/|#]]는 점을 고려하여, '''불필요한 예외는 사용하지 말아야''' 하며 성능이 중요한 부분에서만 예외 처리를 사용하지 않는 것을 추천한다.[* 처리하기 전에 앞서 확인하는 과정을 통해 피할 수 있는 예외는 당연히 피하는 것이 좋다. 예를 들면, {{{std::optional}}}에 유효한 객체를 가지고 있지 않을 때 객체에 접근하여 발생하는 {{{std::bad_optional_access}}} 예외는 접근하기 전에 미리 확인하여 피할 수 있다. 그러나 컨테이너 라이브러리 등을 사용하는 과정에서 {{{std::bad_alloc}}}과 같이 메모리 할당의 실패로 발생하는 예외는 남은 메모리 크기를 확인하더라도 피하지 못할 수 있다. 이 경우, 예외를 처리하지 않으면 프로그램은 종료될 뿐이다.][[https://docs.microsoft.com/ko-kr/cpp/cpp/errors-and-exception-handling-modern-cpp|#]]\n\nRTTI와 달리 C++의 표준 라이브러리를 사용하고 에러 처리를 동반하는 한 '''예외는 현실적으로 피할 수 없다.''' C++에서 객체의 생성이나 복사를 실패시킬 수 있는 문법적 기능은 예외가 유일하며[* two-phase construction 등 회피 꼼수가 있으나 어디까지나 꼼수다. C++ 특성상 예외를 완전히 피하면서 깔끔한 코드를 설계하는 것은 매우 어렵다.] 표준 라이브러리는 이를 적극적으로 활용하기 때문이다.[* 메이저 컴파일러들 중 일부는 RTTI와 마찬가지로 예외 처리를 끄는 기능을 제공하긴 한다. 하지만 이 경우 표준 라이브러리를 사용하는 중 거기서 예외를 던지는 순간 정의되지 않은 동작(undefined behavior)으로 돌입한다. 이 순간에는, 컴파일러나 런타임 라이브러리에 따라 다르긴 하지만, 대부분의 경우 프로그램이 종료된다.]\n\n에러 처리 수단은 수많은 프로그래밍 언어의 핵심 매커니즘이다. 하지만 이런 상당한 단점이 있게 되자, 대규모 프로젝트에서는 성능 상의 이유로 예외의 사용을 금지하게 되고[* P0709에 따르면 무려 52%의 프로그래머가 프로젝트 내에서 예외가 금지되었다고 답하였다.], 오히려 C에서 흔히 쓰는 에러코드 등의 매커니즘으로 회귀하게 되었다. 심지어 에러 처리를 일관적으로 예외로 하던 표준마저도 어느 정도 스탠스를 바꾸어, C++17의 {{{filesystem}}} 라이브러리의 경우 예외 처리와 에러코드용 인터페이스를 혼용해서 제공해버릴 정도로 C++의 예외 처리는 처리 비용이 상당하다.\n\n이렇게 성능 상의 문제로 예외 처리를 기피하는 상황이 발생하자, 아예 에러코드 방식을 확장시킨 {{{Boost.Outcome}}} 혹은 {{{std::expected}}}[* 이러한 개념을 먼저 도입한 언어의 예로 [[Rust]]와 [[Kotlin]]의 {{{Result}}}를 들 수 있다. Rust는 예외 대신 {{{Result}}} 객체와 열거형 에러를 사용하며, 다른 열거형으로의 변환에 대한 구현이 있는 경우 자동 변환을 지원한다.] 등으로 발전하려고 하고 있다. 타입 캐스팅을 포기하고 에러코드와 예외의 장점을 섞은 표준안이 제안되고 있으므로 [[http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p0709r4.pdf|#P0709]] 언젠간 개선되리라는 희망을 가질 수는 있겠지만, 아직도 많은 논의가 계속되고 있기 때문에[[https://www.reddit.com/r/cpp/comments/c75ipk/why_stdexpected_is_not_in_the_standard_yet_is_it/|#]] 당분간은 적용이 요원하다.\n== 역사 ==\n=== 클래식 C++ ===\n==== C with Classes (1979년) ====\n[[1979년]]에 비아르네 스트로우스트루프가 속도가 느리지만 객체 지향적인 언어인 Simula의 컨셉을 [[C언어]]에 접목시키면서 C with Classes라는 이름으로 만들었다.\n\n==== C++ (1983년) ====\n[[1983년]]에 가상 함수, 연산자 오버로딩, [[참조]], const, new/delete 연산자 등을 포함한 새로운 기능들이 추가되면서 언어 이름도 C with Classes에서 C++로 변경되었다. 이 시점에서 이미 클래식 C++의 틀은 완전히 잡혔다고 할 수 있으며, 이때까지는 거의 스트로우스트루프가 언어 개발을 전담하다시피 했다.\n\n1985년에 본인이 쓴 책인 [[http://www.stroustrup.com/4th.html|The C++ Programming Language]]를 통해 C++라는 언어를 정의하여 레퍼런스 컴파일러를 배포하는 식으로 개발되었다. 한편, 컴파일러 쪽에서는 백엔드는 여전히 C 컴파일러이지만 프론트엔드만 Cfront라는 이름으로 새로 개발되었다.\n\n==== C++ 2.0 (1989년) ====\n[[1989년]]에 다중 상속, 추상 클래스, static 멤버 함수, const 멤버 함수 및 protected 멤버 등의 새로운 기능들이 추가된 C++ 2.0이 발표되었으며, 컴파일러의 프론트엔드도 Cfront 2.0으로 업그레이드되었다.\n\n1990년에 C++ 2.0에 추가된 기능 외에 템플릿, 예외, 네임스페이스, new casts 및 bool 타입 등의 새로운 기능들이 추가된 '주석이 달린 C++ 레퍼런스 메뉴얼'이 발표되었고 1991년에 컴파일러 프론트엔드가 Cfront 3.0으로 업그레이드되었으며, The C++ Programming Language의 첫 번째 개정판이 발행되었다.\n\n==== C++98 (1998년) ====\n[[1998년]]에 최종 승인된 C++의 첫 공식 표준안으로, C++ 2.0 이후 C++가 안정적으로 정착하고 수요가 폭증함에 따라 여러 회사에서 상업용으로 컴파일러를 만들었고, 이에 따라 코드가 컴파일러에 따라 중구난방이 되는 것을 막기 위해 표준화의 필요성이 제기된다. 그래서 1990년에 [[ANSI]]에서 C++ 표준화를 위한 위원회가 설립되었으나 1991년에 [[ISO]]로 넘기면서 스트로우스트루프를 비롯한 프로그래밍 언어학자 및 컴파일러 제조사들을 모아 표준화 작업을 하기 시작한다.[* C++뿐 아니라 C, 파스칼 등 클래식 언어들이 전부 [[ISO]]에서 표준화되고 있다. 아예 이런 언어를 표준화하는 전문 태스크 팀 [[https://en.wikipedia.org/wiki/ISO/IEC_JTC_1/SC_22|JTC1/SC22]]라는 게 있으며, 이중 C++는 21번째 그룹에 속한다.] 그렇게 C++의 표준안이 ISO/IEC 14882:1998라는 공식 명칭으로 처음 제정되었으며, 이를 줄여 C++98이라 부른다.\n\n==== C++03 (2003년) ====\n[[2003년]]에 C++98 문서의 애매모호했던 부분들을 보완한 C++03이 ISO/IEC 14882:2003라는 정식 명칭으로 제정되었는데, 이는 그냥 표준화 문서상 불명확했던 것을 교정한 버전이다. 예를 들어 {{{std::vector}}}가 배열처럼 연속된 메모리를 차지하도록 표준에 명시했다. 사실 당시 컴파일러들 대다수가 이미 C++03 제정 이전부터 이러한 부분들을 잘 구현한지라, 실제 프로그래머 입장에서 변한 건 없다.\n\n=== 모던 C++ ===\n각종 주요 컴파일러들과 모던 C++의 호환성은 [[http://en.cppreference.com/w/cpp/compiler_support|여기서]] 볼 수 있다.\n\n==== C++TR1 (2007년) ====\n[[2005년]] 6월 24일에 표준 라이브러리를 확장하는 것을 골자로 하는 C++ 테크니컬 리포트의 초안이 작성되어 [[2007년]] 11월에 제정되었다.\n\n첫 번째 테크니컬 리포트라고 해서 C++TR1으로 알려져 있는데 혹자는 이를 표준안과 동급으로 간주하고 C++07/TR1이라 부르기도 한다. 정식 명칭은 ISO/IEC TR 19768:2007이며, C++ 표준화 이후 사실상 언어에 변화를 가한 첫 번째 사양이지만 엄밀하게 표준안은 아니라서 컴파일러 제작사가 원하면 넣고 아니면 마는 수준의 선택적인 확장안이었다. 그래서인지 전부 {{{std}}} 네임스페이스에 들어가 있지 않고 대신 {{{std::tr1}}} 네임스페이스로 분리되어 들어간다. 이후 C++TR1의 기능들은 대부분 C++11 표준 사양으로 흡수된다.\n\nC++TR1 초안이 발표되기 2달 전인 2005년 4월 29일에 C++TR2의 초안에 대한 작업을 시작했었다. 여기에는 유니코드, XML/HTML, 네트워킹, 파일 시스템 등의 기능이 포함될 예정이었으나, 이는 무산되었다. 대신, 각각의 라이브러리와 기능들을 \"Technical Specifications\"이라는 별도의 비표준 기술 사양으로 별도로 제정하기 시작했다. 여기에는 파일 시스템, 병렬 컴퓨팅, 트랜잭셔널 메모리, 컨셉트, Range, 코루틴, 네트워킹, 모듈, 리플렉션 그리고 심지어 그래픽까지 있지만, 이러한 것들이 추후 표준에 포함될 지 또는 얼마나 수정될 지는 미정이다. C++TR2의 일부 사양이 C++11에 포함되었으며, C++17, C++20에 해당하는 기능들까지 포함되어 있는 등 실험적인 성격의 사양임을 짐작할 수 있다.\n\n이러한 시범 사양은 {{{std::experimental}}}이라는 네임스페이스에 포함되어, [[Visual Studio|MSVC]]나 [[Clang]]에서 일부 지원한다. 시범적인 사양은 [[https://en.cppreference.com/w/cpp/experimental|이 사이트]]에서 확인할 수 있다.\n\n==== C++11 (2011년) ====\n새로운 기능들이 많이 포함되었던 C++TR1이 정식 표준으로 채택되지 못 해서 대부분의 프로그래머들에게 있어서 C++은 C++98 이후 13년 간 정체된 언어나 다름 없었다.\n\n[[2011년]] 8월 12일에 최신 컴퓨팅 환경을 지원하기 위해 급격한 변화의 첫 단추를 끊은 새로운 표준안인 C++11이 ISO/IEC 14882:2011라는 정식 명칭으로 최종 승인되었다. 최종 승인되기 전까지 표준안 개발 당시엔 C++'''0x'''라 불리었는데, [[2000년대]] 안에는 표준화가 될 것이라는 의미였다. 하지만 결국 2000년대가 끝나고 2011년 8월에서야 정식 C++ 표준이 되어서 11이 붙었다. [[http://herbsutter.com/2011/08/12/we-have-an-international-standard-c0x-is-unanimously-approved/|#]] 여담이지만 추가된 많은 기능 중 상당수 항목들이 boost 라이브러리를 다수 참조[* 아예 boost 라이브러리 개발진 중 다수가 C++ 표준화 위원이기도 하다. 차세대 C++에 들어갈 요소를 표준화 위원들이 미리 개발해서 시험해본 것이라 봐도 무방하다.]했다. C++11에서 r-value/move[* 객체의 복사에서 원본이 불필요한 경우 이를 활용하면 실행 시간 감소의 효과가 있다. 복사 생성자를 통해 객체를 복사하고 원본의 메모리를 삭제하는 대신, 얕은 복사처럼 기존의 포인터만 가져오고 원본 역시 포인터만을 소멸시켜 객체 자체는 그대로 사용한다. 이동 생성자와 이동 대입 연산자를 통해 이러한 기능을 구현한다.], {{{constexpr}}}, {{{std::initializer_list}}}, Range-based for loop[* 표준 라이브러리의 iterator 대신 이를 대신 사용함으로써 for문을 간략하게 작성할 수 있다.], [[람다식#s-5.2.3|lambda expression]], 스마트 포인터[* 기존 표준에서 유일한 스마트 포인터였던 {{{std::auto_ptr}}}은 명시적이지 않은 소유권 이동, 동적 배열의 삭제 불가 등 실무에서 절대 사용하면 안되는 쓰레기였지만, {{{std::shared_ptr}}}와 같은 새로운 스마트 포인터가 추가되면서 메모리 관리가 보다 안전해지고 편해졌다. 스마트 포인터를 잘 활용한다면 메모리 관리에 대한 수고를 덜 수 있다. 실제로 Chromium과 같은 대규모 프로젝트에서 심심치 않게 볼 수 있다.], 정규표현식[* 다만, 속도가 Python보다도 1.5배나 느리다. 컴파일러들의 구현이 좋지 않거나 운영체제의 메모리 할당이 너무 잦기 때문으로 보인다. 자주 사용한다면 별도의 라이브러리를 사용할 것을 추천한다.], 멀티쓰레드 등등 중요한 신 개념과 편의 기능들이 많이 추가되었으므로 반드시 확인할 필요가 있다. C++11에 추가된 내용만 적절히 활용해도 C++ 코드의 작성과 관리가 보다 명확하고 더 쉬워진다.\n\nC++ 표준 위원회는 C++98에서 C++11까지 업데이트가 나오는 데 시간이 매우 오래 걸린 것이 업데이트가 잘 완성된 후에 발표하려고 했던 접근 방식 때문이었다고 자평한 뒤, 이러한 완벽주의를 버리고 3년에 한 번씩 그때까지 정리된 업데이트만 발표하는 형식(기차 모델)으로 규칙적인 업데이트를 하는 것이 훨씬 생산적인 접근방식이라고 결정하였다.\n\n==== C++14 (2014년) ====\n[[2014년]] 8월에 ISO/IEC 14882:2014라는 정식 명칭으로 C++14이 제정되었다. 표준안 작성 당시 C++0x라 불리었던 C++11처럼 C++14도 C++'''1y'''라는 코드네임으로 불렸으며, 주로 C++11에 추가된 요소들을 다듬고 확장하는 데 치중한 비교적 마이너 표준안이다.\n\n==== C++17 (2017년) ====\n[[2017년]] 12월에 C++'''1z'''로 알려졌던 C++17 표준이 ISO/IEC 14882:2017이라는 정식 명칭으로 최종 승인되었다.\n\nC++11의 추가 요소들을 다듬고 향상시키는데 주력했던 C++14에 비해, C++17은 표준 라이브러리의 새로운 기능에 비교적 주력한다. 초안 단계에서부터 논란이 많은 표준안이기도 하다. C++11/14의 실정에 맞추어 옛날 기능을 삭제하자는 안이 많기 때문인데[* C++11 제정 당시에도 {{{std::auto_ptr}}} 등 많은 옛날 요소들이 deprecated로 명시되어 사용이 자제될 것을 권장받았으나, 이는 어디까지나 권고라 사용자가 맘 놓고 쓰려면 쓸 수 있었다. 이전 버전의 기능을 아예 죽여버린 사례는, C++98 시절에 실상 누구도 안 썼고 지금은 아예 용도가 바뀌어버린 {{{auto}}} 등 극소수만이 해당한다.], deprecated 판정을 받은 {{{std::auto_ptr}}}이나 삼중자(trigraph)[* C/C++의 특수기호는 미국의 부호체계인 [[ASCII]]를 기반으로 하고 있기 때문에 해당 영역에 다른 문자를 넣어 사용하던 유럽국가들의 코드페이지에서는 이상하게 표현되는 일이 있었다. 그래서 잘 사용하지 않는 문자의 조합으로 특수문자를 표기하는 방법. 문자 2개의 조합이면 digraph, 3개면 trigraph. 유니코드가 대세가 된 지금은 사실 필요 없고, 옛날 소스라고 해도 간단한 일괄 변환작업으로 새 표준에 맞출 수 있기도 하다. 다만 표준에서 삭제처리를 할 경우 해당 문법이 '''다른 기능으로 대체될 수 있기 때문에''' 일괄변환이 언제나 될 것이라는 보증이 안 되고, 후술하는 IBM 등 장기간의 낡은 코드와 관련된 이해관계자들 입장에서 떨떠름한 것은 사실이다.] 등이 삭제되었다. 이는 옛 코드에 대한 호환성을 포기하는 것이기 때문에, 오래된 코드들이 최신 컴파일러에서 컴파일되지 않을 가능성이 크다. 이 때문에 IBM에서 문자체계의 문제를 내세워 삼중자를 제거하지 말라고 회사 차원에서 표준화 위원회에 진정서를 제출했었다. [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4210.pdf|#]]\n\nC++17에는 파일 시스템, [[STL]] 병렬 알고리즘 처리[* 다만 이를 제대로 지원하는 컴파일러는 그다지 많지 않아서 호환성 문제가 있을 수 있다. [[Visual Studio]]의 경우 2017 이상, [[GCC]]의 libstdc++의 경우 9 이상에서 지원한다.] 등이 추가되었다. 그외의 새로운 기능들은 [[https://stackoverflow.com/questions/38060436/what-are-the-new-features-in-c17|이곳에]] 잘 정리되어 있다. 예를 들면 C++17에 추가된 structured binding을 잘 활용하면 두 개 이상의 값을 반환받을때, 값들을 선언과 동시에 초기화하는 기능을 이용할 수 있다.\n\n==== C++20 (2020년) ====\n[[2020년]]에 최종 승인된 C++20은 C++11, C++14, C++17에 이은 주요 버전이다. 비동기 프로그래밍을 지원하기 위한 코루틴[* 언어 차원에서 지원하기 때문에, 비동기 프로그래밍을 위해 별도의 라이브러리가 필요하지 않게 된다.], 컴파일 속도 향상을 위한 소스 파일 모듈화[* 소스 파일이 각각의 헤더 파일을 일일이 포함하는 대신, 미리 컴파일된 모듈을 사용함으로써 컴파일 속도가 크게 향상된다. 별도의 시범 사양으로도 공개되어 있기 때문에, [[Visual Studio]]의 C++ 컴파일러와 [[Clang]] 컴파일러에서 이미 시범적으로 지원하고 있다.], 템플릿 매개변수에 조건을 추가하기 위한 컨셉트[* 현존하는 템플릿 트릭의 대다수를 대체할 수 있으므로 코드가 간결해지고 가독성이 증가한다.] 등 [[https://ko.wikipedia.org/wiki/C%2B%2B20|다양한 기능들이 추가될 예정이다.]] 그 외에 추후 표준에[* 3년 주기를 따를 경우 C++23이 된다.] 추가될 수 있는 리플렉션과 네트워크 라이브러리, 2D GUI 라이브러리, 트랜잭셔널 메모리에 대한 [[https://en.cppreference.com/w/cpp/experimental|시범 사양도 별도로 공개되어 있다.]]\n\n더 놀라운 점은 C++20에 추가된 기능들과 C++20에 다 반영되지 못한 대신 다음 C++ 표준에 포함될 예정인 기능들이 대부분 C++TR2 제안서에 이미 언급되어 있던 사양이라는 특징이 있다. 표준화로서 최소 15년만에 빛을 발하게 된 셈.\n\n== 방언 및 확장 ==\n=== [[.NET#Framework|C++/CLI]] ===\n2005년 비주얼 스튜디오 2005에 도입된 [[.NET#Framework|.NET Framework]]의 CLR에 맞물려 동작하는 C++. 보통 프레임워크 정도로 제공되는 다른 라이브러리와 달리 .NET의 메모리 구조에 맞추어 언어 자체가 다르다.\n\n2002년에 비주얼 스튜디오 .NET 2002에 도입되었던 Managed Extensions for C++[* 줄여서 Managed C++라고도 불렀다.]는 정말 못 써먹을 언어였기 때문에 Managed C++을 대체하기 위한 언어로 나왔으며, 적어도 스펙상으로는 [[게임]]을 만들기에도[* 게임은 일반적으로 생산성이 매우 중요한 거대 프로젝트이면서 하드웨어의 성능을 극한까지 끌어내야 하는, 속도와 효율에 매우 민감한 특수한 소프트웨어 분야이기 때문에 C++가 많이 사용된다. 괜히 이런 이야기에 게임에 대한 언급이 잘 나오는 게 아니다.][* 초기의 Managed C++은 언어의 포지션도 상당히 애매했다. 간단히 말하자면 닷넷 프레임워크와 레거시 운영체제 프레임워크를 동시에 지원하고자 했으나 결과는 이도저도 아니었다. 차라리 닷넷 프레임워크가 COM을 지원하니 그런 걸 쓰는 게 낫다.] 부족함이 없는 고속의 언어임에도 생산성은 C++에 비해서 높다고 한다. 특히 [[C\\#]]과 C++를 이어주는 래퍼 등의 모듈을 만들기에는 아주 제격이며, C/C++로 만들어진 프로젝트를 시간적 여유를 두고 닷넷 기반으로 바꾸는 용도로도 많이 쓰이고 있다. 필요에 따라 단계적으로 모듈을 바꿔치기 하다보면 어느새 순수 닷넷 애플리케이션 완성. 그러나 지원 및 이식성이 떨어져서 업계 표준으로 쓰기에는 무리다.\n\nC++/CLI 코드 내에서는 관리와 비관리 클래스를 혼용할 수 있으므로 래핑 없이 모든 모듈을 C++/CLI로 작성해도 되지만, C++/CLI 내의 C++ 클래스는 순수 네이티브 라이브러리에서 만들어진 C++ 클래스에 비해 성능이 다소 떨어진다. 따라서 성능이 중요한 모듈은 별도의 네이티브 코드로 작성하고, C++/CLI는 이 모듈의 래핑을 담당하는 모듈만을 작성하는 것이 좋다.\n\n여담이지만 .NET 출시 당시 [[마이크로소프트]]가 Managed 언어를 강력하게 밀어줘서([[C\\#]] 등) 기존에 쓰이던 Win32 API C++나 [[MFC]]는 찬밥 신세라는 인상을 줬다. 특히 닷넷 기술이 막 도입되던 [[비주얼 스튜디오]] 2005 당시 C++와 C#을 비교해 보면 대놓고 C++를 죽이려 한다는 느낌이 팍팍 들었을 정도. (하지만 MS가 자사의 핵심 코드를 .NET으로 바꾸거나 핵심 플랫폼 기능들을 열어주거나 한 케이스가 거의 없다.) VS 2008부터는 지원이 다시 강화되는 추세이며, C++11, 14, 17 지원 및 C++ AMP의 도입 등 여러가지 확장을 하고 있다. 물론 이것도 예전에 비해 나아졌다 수준이고, 인텔리센스나 코드 리팩토링 등의 기능을 보면 여전히 C#에 비해 지원이 미흡하다. 특히 [[언리얼 엔진]]으로 비주얼 스튜디오에서 C++ 코딩을 하다 보면 그 끔찍하게 느린 인텔리센스 속도에 경악하게 된다.\n\n=== [[CUDA]] ===\n2007년 6월에 발표된 [[NVIDIA]]의 [[GPU]]에서 동작하는 C++ 기반 [[GPGPU]] 언어.\n\n=== [[OpenCL]] ===\n2009년 8월에 발표된 개방형 [[GPGPU]] 언어. 원래는 [[C(프로그래밍 언어)|C]] 기반이었으나 2015년 11월 16일에 발표된 OpenCL 2.1부터 C++14를 기반으로 문법이 확장되었다.\n\n=== C++/CX ===\n2012년에 [[WinRT]] 및 XAML을 지원하기 위해 마이크로소프트에서 고안한 확장 언어. 라이브러리는 Windows Runtime C++ Template Library(WRL)을 사용했으나 2015년 6월 23일에 발표된 C++/WinRT로 대체되었다.\n\n== [[/문법|문법]] ==\n[include(틀:상세 내용, 문서명=C++/문법)]\n\n== 도서 ==\nC++는 초기에 배울 내용이 무척 많고 최종 목표로 하는 어플리케이션의 종류에 따라서[* 시스템, 실시간 임베디드, 게임, 파이낸스, 그래픽, 머신러닝, 영상처리, 수치 시뮬레이션...] 중상급 레벨에서 가는 길이 크게 갈리기 때문에, 어디에서 시작할 것인가가 꽤나 학습 방향에 중요하게 작용해서 입문 및 초급자용 도서 추천이 매우 곤란하다. 거기에 몇 년도 C++ 버전을 기준으로 썼는지도 고려해야 한다. 아래의 도서들은 한국어 번역본이 존재하는 도서를 우선시하였다.[* 다만 처음부터 번역서를 보는 것보다는 차라리 한국인 저자가 쓴 책을 먼저 보고, 영어실력을 좀 쌓은 이후에 아예 원서로 넘어가는 식으로 공부하는 것을 추천한다. 번역서들은 번역이 매끄럽지 않고 이해하기 어려운 경우가 제법 있기 때문이다.]\n\n||<|5> 입문 & 초급 || '''입문용 서적으로는''' [[https://www.quora.com/What-are-the-best-books-for-learning-C-that-you-will-suggest-to-a-beginner|외국의 입문서]]라고 하면 Teach Yourself 시리즈나, Primer 시리즈 등이 가장 처음 볼 책으로 추천되곤 하지만 초급 서적임에도 불구하고 둘 다 매우 두꺼운 편이며, 예제나 서술 방식에 호불호가 크게 갈리는 책이다. ||\n|| C++ 창시자 본인이 학부생 수업 교재로 사용할 목적으로 쓴 Programming: Principles and Practice using C++는 보통 컴퓨터 관련 학부 2학년에 존재하는 '''프로그래밍 방법론''' 등의 이름을 가진 특정 언어와는 무관한 수업의 교재이지만, [[https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list|C++ 입문서]]로도 꽤 유용하다. ||\n|| 오래된([[2005년]]) 책이지만 Effctive C++(3판)을 보는 것도 좋다. 번역이 매끄러워 읽기 좋고 이해하기 쉽다. ||\n|| 인터넷으로 배우고 싶다면 [[https://modoocode.com|모두의 코드]]를 추천한다. ||\n|| [[https://hackr.io/blog/10-best-c-cpp-books|C 초급용 추천서적 5종, C++ 초급용 추천서적 5종]] ||\n||<|2> 중급 || 일단 초급용 서적을 한 권 독파하고 나면, Effective Modern C++, C++ Template: The Complete Guide, C++ Concurrency in Action 정도의 책을 권하는 사람이 많다. 특히 스콧 마이어스의 Effective Modern C++는 거의 필독서에 가깝다.[* 하지만 한국어판은 번역 오류가 많아 이해가 어려울 수도 있다.] ||\n|| C언어의 창시자가 쓴 The C Programming Language가 초급자들부터 봐야 하는 책으로 유명한 것에 비하여, 비아르네 스트로우스트루프의 The C++ Programming Language는 절대 초급용 서적이 아닌, 중급 이후의 레퍼런스 서적이다. ||\n|| 이후 || 이 단계까지 성공적으로 도달하였으면, 최종 목표에 따라서 책을 보아야 하는 단계이므로 더 이상 일반적인 추천이 가능하지 않다. ~~그리고 여기까지가 튜토리얼이다~~ ||\n\n사족으로, \"Visual C++\"이라고 굳이 제목에 Visual을 넣는 책들은 조금 오래된 서적들이니 주의할 것. \"C/C++\"이라고 C언어와 C++을 혼용해서 서술하거나, 명색이 C++ 참고서라면서 정작 내용은 C언어에 대한 것만으로 절반 가까이 채운 책들도 있는데, 이런 종류 역시 별로 추천하지 않는다.\n== 관련 문서 ==\n * [[인라인 함수]]\n * [[표준 템플릿 라이브러리|STL]]\n * [[Boost]]\n * [[템플릿]]\n * [[컴퓨터공학과]][* 대부분의 컴공과에서 배운다. 많은 컴공과에서 첫 언어로 C를 가르치는 관계로, 학생들에게 익숙한 C의 문법을 가지고 객체지향 프로그래밍의 개념도 다룰 수 있다는 장점이 있기 때문이다. Java나 Python을 처음으로 배우는 학교의 경우에도 언젠가 한번쯤은 C나 C++를 건드릴 일이 생기게 된다.]\n * [[객체 지향 프로그래밍]]\n== 외부 링크 ==\n * [[http://en.cppreference.com/w/|레퍼런스 위키 사이트]]\n * [[http://www.stroustrup.com/C++11FAQ.html|비아르네 스트로우스트루프의 C++11 FAQ]]\n * [[https://classpert.com/cplusplus-programming|Classpert C++ 과정]]\n * [[http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines|가장 최근에 나온 C++을 기준으로 계속 업데이트되는 가이드라인]]\n\n[[분류:프로그래밍 언어]][[분류:1983년 출시]]", "contributors": ["capella87", "203.241.183.12", "221.154.230.206", "paranscreen", "221.139.237.4", "202.168.154.152", "starb0y", "r:yourmama397", "180.66.104.170", "163.180.116.163", "122.42.240.251", "59.12.62.106", "lusiyan", "cjm0112", "183.97.124.13", "14.38.150.87", "116.125.107.67", "rafina227", "dinsslug", "119.149.41.53", "175.123.58.63", "121.127.84.205", "222.112.181.233", "regentag", "119.202.82.179", "115.137.92.194", "aquarius218", "kweonsunho", "iz7h", "fred6758", "175.198.123.135", "211.109.176.117", "125.142.252.250", "lemon1335", "pknowledge", "14.52.177.211", "belzevuite", "justamathematician", "175.214.109.214", "125.142.106.50", "opticaltopography", "112.156.240.224", "175.200.79.98", "blackj0221", "moonseo1013", "58.124.101.7", "14.42.39.82", "210.178.101.185", "kippie408", "qurate5031", "uhmgoon", "rudibiaz", "119.70.186.150", "14.50.223.96", "58.122.73.204", "175.211.54.235", "110.11.199.22", "59.7.246.12", "khb", "dori99", "lenir", "24.76.62.68", "cnux9", "paxbun", "jangho", "isaac_newton", "115.145.234.185", "61.80.158.164", "miroo4517", "219.250.138.110", "119.198.112.92", "61.82.99.161", "115.90.242.117", "168.115.119.84", "121.138.151.1", "kerrigan", "39.119.42.58", "58.120.205.181", "210.119.101.186", "r:perfectsonic", "125.141.38.153", "220.88.241.101", "221.158.37.249", "61.255.175.42", "eldkfwkd321", "1.251.19.157", "125.184.97.35", "175.204.241.236", "e080hsm", "abcd", "jkayys1773", "175.194.99.242", "60.253.6.80", "gusdnlee0102", "188.138.9.180", "119.69.168.11", "125.138.119.178", "218.238.129.87", "r:bokudayoboku", "61.75.27.201", "cosgenio", "39.120.235.97", "quel", "rladbqls1", "93.133.192.142", "203.47.40.194", "democraz", "senior9324", "nuna8814", "sincity", "metan", "sequentialaccess", "112.170.88.241", "118.46.221.3", "comp", "119.196.149.218", "211.219.104.85", "editor123", "220.124.112.151", "hellheaven", "211.207.47.185", "1.229.151.115", "114.204.104.109", "118.45.213.172", "cccccccc", "yul", "59.10.206.166", "222.120.77.100", "106.245.188.14", "gyoseoklee", "115.139.187.10", "nancykwon", "114.201.40.67", "222.101.91.193", "eternal_", "hwany0813", "61.43.92.36", "183.96.150.196", "14.51.222.112", "121.171.213.90", "ray_k1", "175.124.86.203", "222.107.209.198", "rozkhara", "jibril_lee", "everything", "61.73.111.109", "211.247.73.132", "1.241.48.232", "73.170.106.82", "211.247.111.108", "johntheripper", "mechartist", "118.32.149.61", "77.4.219.45", "sohnryang", "220.88.49.218", "clur", "118.38.155.124", "pip", "115.40.65.84", "carlos", "jhseo1107", "211.224.44.228", "mygumi", "hellojo011", "121.169.34.38", "charm", "buster", "143.248.137.153", "112.161.127.243", "221.151.251.185", "220.70.71.42", "markjjang1122", "222.98.105.56", "qpwoeiruty07", "makerj", "221.146.38.157", "211.228.145.92", "femi_jy_82", "atdt01410", "117.110.33.215", "121.145.134.26", "211.177.89.198", "accessable", "173.70.53.126", "59.17.206.241", "222.112.33.75", "121.144.71.135", "igorrocha", "121.161.89.25", "222.100.64.108", "106.243.28.82", "horai3420", "kym630174", "203.236.26.251", "enimsky", "119.202.82.14", "imaginedragoons", "61.72.95.133", "kiwitree2", "218.147.161.16", "namubot", "175.193.139.40", "220.122.23.160", "118.217.32.43", "203.252.159.230", "121.174.19.107", "121.127.84.209", "219.250.237.215", "lslgons", "a3963409", "jamaha12", "165.243.5.55", "gregendy15", "kiwitree", "211.114.184.160", "219.249.164.186", "dotting103", "lun4r", "sungkim17", "121.170.21.241", "61.111.10.20", "dfgtyrui", "121.170.184.44", "39.125.34.156", "undyne", "parisvienna", "sizzflair97", "121.138.57.211", "sugdktld", "58.227.219.97", "dalstroy", "182.230.250.227", "skygarden", "211.247.111.100", "210.222.42.158", "14.50.223.22", "konan8205", "121.165.234.77", "221.145.207.49", "perfectsonic", "enfortune", "papilio", "snowflake", "211.44.63.37", "103.229.16.4", "49.163.93.241", "kazuality", "117.111.1.236", "117.17.158.70", "119.194.235.128", "183.106.120.73", "43.241.44.33", "121.175.130.140", "1.231.83.102", "1.237.180.2", "124.80.52.157", "61.34.183.7", "purewell", "77.4.39.50"]} 2 | -------------------------------------------------------------------------------- /test_data/test4.gold.txt: -------------------------------------------------------------------------------- 1 | Python - 개요 2 | 위의 문법은 파이썬 3 기준이다. 3 | 파이썬 2에서는 print "Hello, world!"만 해도 충분하다. 4 | 1991년에 발표된, MATLAB과 유사한 인터프리터 방식의 프로그래밍 언어. 5 | 공식 홈페이지 공식 깃헙 저장소 6 | 최신 버전은 2020년 12월 07일에 나온 3.9.1 버전이며 0.1버전마다 for문 등의 루프에서 연산 효율이 약 2배 빨라지는 개선이 존재하므로, 최신 버전이 3개월 이상 지나 안정화가 된 후에는 귀찮더라도 버전을 반드시 업데이트 하기를 추천한다. 7 | 온라인 상으로 코드를 실행시켜 보고 싶다면 여기로. 8 | 창시자는 귀도 반 로섬(Guido van Rossum). 1989년 크리스마스 주에, 연구실이 닫혀있어서 심심한 김에 만든 프로그래밍 언어이다. 9 | 농담이 아니고 반 로섬을 유럽에서는 애덤 스미스에 비교할 정도다. 10 | 프로그래밍 계의 경제학자라나... 11 | 심심해서 만들었다는 것은 파이썬 서문과 마이크로소프트웨어와 한 인터뷰를 보면 알겠지만 사실이다. 12 | 기술자들은 대부분 심심할 때, 혹은 실수로 걸작을 만든다. 13 | 2000년에는 Python 2, 2008년에는 Python 3가 나왔다. 14 | 이름은 귀도가 즐겨 보던 영국의 6인조 코미디 그룹 몬티 파이선에서 따왔다고 한다. 15 | 지금 CPython의 공식 GitHub 저장소를 보면 협업보조용 봇 이름들이 the-knights-who-say-ni(니라고 말하는 기사)나 bedevere(베디비어) 같이 죄다 몬티 파이선과 성배의 배역들이다. 16 | 많은 파이썬 교재들에서 변수 이름을 spam, eggs로 짓는 등 드립을 친다. 17 | 직접적 관계는 없지만 42도 필수요소. 또한 시작 프로그램 중 하나의 이름이 아이들(Idle)인데, 탄생배경을 생각해 본다면 몬티 파이선의 멤버 에릭 아이들(Eric Idle)의 이름에서 유래하였을 가능성이 높다. 18 | 물론 사전적 의미를 생각 안 하는 건 아니라서 심볼마크가 뱀 모양이다. 19 | 문법이 매우 쉬워서 초보자들이 처음 프로그래밍을 배울 때 추천되는 언어이다. 20 | 오죽하면 Python의 별명이 '실행할 수 있는 의사 코드(Executable pseudocode)'일 정도. 실제로도 미국 공과 대학교에서 컴퓨터 프로그래밍 입문 수업으로 Python을 많이 사용하기도 한다. 21 | 학습용으로 좋은 언어인 동시에 실사용률과 생산성도 높은 강력한 언어인 셈. 즉 접근성과 응용력이 좋다는 게 굉장히 중요하다. 22 | Python의 이런 두 마리 토끼는 교육용 프로그래밍 언어인 BASIC이 망했어요 루트를 타게 된 결정적인 이유이다. 23 | Python은 BASIC과 달리 학교에서 배우고 끝나는 게 아니라 현업에서도 자주 쓰이는 언어이기 때문이다. 24 | 농담이 아니고 파이썬이 교육용 언어로 자리잡으면서 베이직은 마이크로소프트에 의해 산소호흡기를 달고 연명만 하는 신세가 됐다. 25 | MS가 없으면 BASIC은... 26 | 2010년 후반대에 이르러서는 풍부한 머신러닝 라이브러리와 프레임웍으로 머신러닝, 딥러닝등 인공지능 개발을 위한 언어로서 각광을 받고 있다. 27 | 사이킷-런(Scikit-learn), 텐서플로우(TensorFlow), CNTK, 아파치 스파크 MLlib(Apache Spark MLlib), 파이토치(PyTorch)등 성능도 뛰어나며 많이 사용되는 머신러닝, 딥러닝 프레임웍들이 파이썬으로 접근이 가능하다. 28 | 파이선은 많은 블록코딩에 사용된다. 29 | 원문보기: # 30 | 31 | Python - 특징 - 디자인 철학 32 | Perl의 '하나 이상의 해결법이 존재한다' 에 대비되는 '가장 아름다운 하나의 답이 존재한다' 를 기본으로 하고 있다. 33 | 이것은 남이 작성한 코드를 내가 읽고 이해해야 하는 경우 아주 절실히 느낄 수 있다. 34 | 이 점은 Tim Peters가 작성한 파이썬 기본 철학(The Zen of Python)에서 더 자세히 나열되어 있는데, 20가지 항목이라고 표현하고 있지만 실은 19가지 항목만 있는 등 '규칙'보다는 농담도 섞인 '조언'에 가까운 문항들이다. 35 | # 콘솔에서 "import this"를 입력하면 이스터 에그로써 파이썬을 통해 볼 수 있다. 36 | dir(this)를 하면 ROT13으로 인코딩된 this.s를 확인할 수 있다. 37 | this.d로 dictionary( {} )를 사용해 해독하면 원문이 나온다. 38 | 파이썬의 이런 철학은 이후 다른 프로그래밍 언어들에도 수출되어, 2010년대 들어서는 기존 언어들도 파이썬처럼 최대한 문법 구조를 단순화시키고 통일하려는 문법 대통일 운동이 일어나기 시작했다. 39 | 이는 프로그래머들이 프로그램을 돌려보기 좋게 한다는 매우 좋은 영향이 있으니까... 40 | 따라서 다른 언어들의 코딩 스타일은 각자의 취향에 맞게 발산 진화하는 반면, 파이썬은 위의 철학들을 만족 시키는 하나의 스타일로 수렴 진화하는 성향이 있다. 41 | 실제로 C 계열의 언어에서 중괄호의 위치에 대한 논쟁은 거의 종교적 논쟁에 가깝다. 42 | 현재 한국에서 가장 많이 쓰이는 방식은 C언어의 창시자 Kernighan과 Ritchie의 K&R 스타일이다. 43 | 그러나 Eric Allman의 방식을 고수하는 사람들도 제법 많다. 44 | 이외에도 중괄호 위치를 정하는 다른 방법들이 있으며 자세한 내용은 http://gyumee.egloos.com/1306012에서 확인 가능하다. 45 | 이런 성향은 다른 언어에는 없는 파이썬스러움(pythonic)이라는 독특한 개념을 낳게 되었는데, 복잡하지 않으면서 의미가 명확하고, 코드의 축약보다 뚜렷하게 보이는 흐름을 중시하는 파이썬의 철학을 지칭하는 개념이다. 46 | 이런 철학 때문에 문법이 굉장히 엄격한 편이다. 47 | 예를 들자면, 다른 언어에서는 해도 되고 안 해도 되는 들여쓰기가 이 언어에서는 의무로, 들여쓰기 자체로 하나의 코드 블럭이 된다. 48 | 코드 블럭을 명시적으로 표시하지 않아도 돼서 비주얼 적으로는 굉장히 깔끔한 반면 자유도를 제약한다는 평도 있다. 49 | 코드에서 중괄호는 모아놓고 보면 굉장히 지저분할 뿐더러, 당장 입력해야 하는 괄호가 2개나 되고, 괄호 하나라도 잘못 넣으면 블럭이 다 꼬여버리는 귀찮은 존재이지만(begin과 end 혹은 end.으로 구분해야 하는 파스칼에서 보면 중괄호만 해도 엄청나게 간결해 보이지만), 대신 블럭들을 이리저리 만질때는 매우 편리한 존재이다. 50 | 특히 C 코드를 종이에 출력해보면 중괄호 있고 없고의 가독성 차이가 의외로 크다. 51 | 파이썬에서는 이 중괄호를 들여쓰기로 대체하는데, 이게 블럭의 시작과 끝 지점을 찾는 부분에서 꽤 불편하다. 52 | 대신 괄호를 2개나 일일이 다 넣고, 잘못 넣지 않게 점검도 해 줘야하는 수고가 없다는 엄청난 장점이 있다. 53 | 이 들여쓰기 의무 규칙 때문에 소스 코드 들여쓰기에 탭(Tab) 문자를 사용하지 않을 것을 매우 강력히 요구한다. 54 | (들여쓰기에 최적화된 python을 쓰기싫으면 세미콜론과 중괄호, int/char 등을 수시로 많이 사용하게 될 것이다.) 탭 문자는 사용자나 시스템의 설정에 따라 서로 다른 폭의 공백이 생긴다. 55 | 문제는 파이썬 인터프리터가 탭 문자 하나를 공백 1문자로 처리한다는 것이다. 56 | 탭 문자로 들여쓰기를 처리하면 자신과 다른 탭 설정을 가진 에디터에서 코드를 열어 볼 경우 코드 들여쓰기가 높은 확률로 망가져 버리고, 그걸 교정해보겠다고 들여쓰기에 공백 문자를 혼용하는 순간 해당 소스 코드는 사람이 고칠 수 없는 형태로(시각적으로는 블록이 맞지만 파이썬 인터프리터는 다른 블록으로 인식) 망가져 버린다. 57 | PEP-8에 명시된 공식 코딩 가이드에서는 스페이스 바로 공백 4문자를 넣기를 권장하고 있다. 58 | 물론 이렇게 스페이스 바를 네 번이나 치는 귀찮은 행위를 프로그래머들이 가만 놔둘 리가 없다. 59 | PyCharm, VSCode 등 Python 개발자들이 애용하는 최신 에디터는 Tab을 누르면 공백 4개로 자동 변환하여 입력되는 기능이 지원되므로 이들 에디터를 이용하면 공백 4개를 번거롭게 칠 필요가 없어진다. 60 | 웃긴건 Python 2는 Tab 키를 권장한다. 61 | 탭 키를 사용하지 말 것을 요구하는 건 Python 3에서 해당하는 이야기. 물론 Python 2에서도 "Tab 키를 쓸 경우에는 잊어버리지 말 것"을 이야기하긴 하나, 그렇다면 처음부터 Tab 키를 막았어야 말이 된다. 62 | PyCharm 등의 주요 에디터에는 탭 키를 썼는지 스페이스 바를 썼는지 시각적으로 구분하여 보여주는 기능이 있으므로 참고하자. 63 | 참고로 위의 예시인 팩토리얼 함수는 (람다식과 ternary operator를 이용해) 다음과 같이 간결히 나타낼 수 있다. 64 | --사실 이 코드는 PEP-8 위반이다. 65 | -- 66 | C와 Java에서 쓰이는 ternary operator ?:에 비해 훨씬 직관적으로 읽혀, '실행할 수 있는 의사코드'라는 별명을 여기서도 느낄 수 있다. 67 | 물론 쳐야 할 문자 숫자가 몇 배로 늘어나기 때문에 싫어하는 사람은 엄청나게 극혐한다. 68 | 69 | Python - 특징 - 순수 객체지향 70 | 파이썬에는 원시 타입(Primitive Type)이 존재하지 않으며, 모든 것이 객체로 취급된다. 71 | 나아가 클래스, 함수 역시 객체로 취급할 수 있다. 72 | 상수 역시 상수가 저장된 객체라고 본다. 73 | 다음과 같은 상수 할당문이 있을 때, 74 | 이는 변수 x 자체에 10이 할당된 것이 아니라 x가 10이 저장된 상수 객체를 가리키는 것을 의미한다. 75 | 내부적으로는 C의 포인터 연산과 같은 동작이 행해지는 것이다. 76 | 이렇게 x에 대입되는 값을 변경할 경우, 77 | x가 가리키는 대상이 10이 저장된 상수 객체에서 20이 저장된 상수 객체로 바뀐 것이다. 78 | x 자체의 값이 10에서 20으로 바뀐 게 아니다. 79 | 파이썬 버전 3의 표준 타입 계층 구조에서 주요 자료형은 그림과 같다. 80 | 이 중에서도 크게 불변 객체(Immutable Object)와 가변 객체(Mutable Object)로 나눌 수 있다. 81 | 불변 객체에는 상수(숫자), 문자열, 바이트, 그리고 튜플이 있다. 82 | 이 네 가지를 제외한 나머지 객체는 모두 가변 객체이며, 값을 수정할 수 있다. 83 | 불변 객체의 값을 수정할 때는 바뀐 값이 저장된 새로운 객체를 생성하고 참조 대상을 새 객체를 옮기는 식으로 동작한다. 84 | 이와 같은 특징 때문에 파이썬은 순수 객체지향 언어라고 할 수 있고, 이와 같은 순수 객체지향 언어의 또다른 예로는 Ruby가 있다. 85 | 함수의 매개변수로 불변 객체를 넘겼냐 가변 객체를 넘겼냐에 따라서 함수 바깥에 있는 인자의 값도 수정할 수 있는지 없는지가 달라진다. 86 | 불변객체를 넘겼으면 값의 복사만 일어나고 함수 바깥에는 영향을 주지 못하므로 '값에 의한 호출(Call by Value)'이 될 것이며, 가변 객체를 넘겼으면 함수 바깥에까지 영향을 줄 수 있으므로 '참조에 의한 호출(Call by Reference)'이 될 것이다. 87 | 파이썬 공식 문서에서는 파이썬의 인자 전달 방식을 '할당에 의한 호출(Call by Assignment)', 또는 '객체 참조에 의한 호출(Call by Object Reference)'이라고 명시하고 있다. 88 | 89 | Python - 특징 - 반복 가능한 객체 90 | 파이썬의 가장 큰 특징 중 하나. 91 | 파이썬은 반복 가능한 객체(iterable)라는 강력한 기능을 제공한다. 92 | 이 객체는 집합, 문자열, 리스트, 튜플, 딕셔너리, 그리고 함수까지도 반복이 가능하며, 이것을 for 구문에서 사용할 수 있게 해준다. 93 | 리스트와 튜플 등은 좀 편해지는 정도라 할 수 있지만, 함수의 값을 반복할 수 있다는 것은 큰 장점이다. 94 | 그 예로 n의 배수를 구하는 f(n) 함수가 있을 때, 95 | 와 같은 함수를 만드는 것도 가능하다. 96 | 함수를 호출하고 나서도 함수가 완전히 끝나기 전까지는 지역 변수가 남아있으며, 함수가 끝나야 지역변수가 삭제된다. 97 | 따라서 함수를 호출할 때마다 x의 값이 증가한다. 98 | 이렇게 만들어진 반복 가능한 객체는 __next__ 함수나 next(객체) 함수, 또는 for ... in 객체 와 같은 문법들을 이용하여 순서대로 값을 호출할 수 있다. 99 | 특히 제너레이터의 경우, 미리 만들어놓는게 아니라, 호출 될 때 반환값을 새로 만들어 반환하는 방식이기 때문에 메모리 관리 면에서도 이점이 있다. 100 | 101 | Python - 장점 - 높은 생산성 102 | 파이썬의 아이덴티티. 그 무엇과도 바꿀 수 없는 파이썬만의 특징이다. 103 | 전 세계의 모든 프로그래밍 언어 중에서 파이썬 정도의 낮은 난이도를 가지면서, __범용성을 갖추고, 파이썬 수준의 프로그램 개발 속도를 따라잡는 언어가 없다__. 파이썬으로 만든 프로그램을 같은 객체지향 프로그래밍 언어인 Java나 C++로 만든다고 하는 순간 숨이 턱 막힐 정도. 이런 언어를 사용하려면 설계부터 난감해진다. 104 | 인터프리터 언어이면서 우수한 자료형과 다양한 모듈 등을 제공해 개발기간이 단축되는 것이 특징. 'C언어로 2년동안 완성하지 못한 프로젝트를 파이썬으로 한달만에 해냈다'는 극적인 경험담이 있을 정도다. 105 | 당장 파이썬의 집합 자료형 같은 경우 C언어로 구현하려고 하면 머리가 아파온다. 106 | C언어와의 접착성도 좋기 때문에, 일단 Python으로 빨리 구현하고, 남은 시간에 속도에 병목이 되는 부분을 C++로 전환하는 전략을 내세우고 있다. 107 | 버전이 올라가면서 Python 자체도 그리 느리지 않게 되었다. 108 | 심지어 어셈블리어 같은 저수준 언어(Low level)도 Python에서 호출 할수있다. 109 | Python은 어지간한 다른 프로그래밍 언어들을 지원하는 호환성, 응용할 곳이 무궁무진하다. 110 | 참고로 저 만화는 파이썬 내에 이스터 에그로 삽입되기도 했다. 111 | import antigravity로 antigravity 모듈을 불러오면 나온다. 112 | 영상 113 | 114 | Python - 장점 - 문법 통일에 따른 빠른 피드백 115 | 디자인 철학 자체가 가장 완벽한 하나의 아름다운 해답을 찾는 파이썬 특유의 철학을 찾다 보니, 문법 자체가 딱 떨어지게 표현된다. 116 | 이 때문에 다른 사람이 제안하고 만든 프로그램을 수많은 사람들이 보고 쉽게 접근할 수 있다. 117 | Perl 같은 경우는 Write Once, Read Never라고 불릴 정도로 피드백과는 담을 쌓았는데, 파이썬은 문법이 통일되어 있다 보니 Write Once, Read Infinity가 되어버렸다. 118 | 그래서 프로그램 하나 만들면 다른 프로그래머들에 의해 엄청난 양의 피드백이 들어오게 되었고, 이는 곧 생산성 향상으로도 이어졌다. 119 | 괜히 파이썬이 시간이 갈수록 점유율이 상승하는 언어가 아닌 것이다. 120 | 121 | Python - 장점 - 과학/공학 친화 122 | Python은 과학과 공학 분야에서 필요한 여러 기능을 기본적으로 제공한다. 123 | 우선 언어 자체적으로 64비트를 넘어가는 매우 큰 정수를 지원한다. 124 | 또한 허수를 기본적으로 지원하며, 표준 라이브러리의 decimal, fractions 모듈을 사용해 소숫점과 유리수를 정밀하게 다룰 수 있다. 125 | 따라서 이러한 기능을 다루는 암호학과 통계 분야에서 쓰기에 알맞다. 126 | Python 생태계 또한 공학 및 과학 분야를 빵빵하게 지원한다. 127 | 복잡한 수치와 큰 데이터를 다루는 연산에 알맞은 NumPy, SciPy, pandas, 데이터를 그래프로 시각화하는 Matplotlib, 코드와 데이터를 함께 다룰 수 있는 Jupyter Notebook 등의 강력한 패키지와 도구를 사용할 수 있다. 128 | Python 개발자들도 이러한 사실을 잘 알고 있기 때문에 언어 차원에서 관련 패키지를 위한 기능을 제공한다. 129 | 가령 Ellipsis 상수는 사실상 NumPy 전용의 슬라이스 객체로 제공한다. 130 | 또한 3.5부터는 행렬곱을 위한 @ 연산자가 추가되었다. 131 | 132 | Python - 장점 - 만능 언어 133 | PyPI#라는 패키지 저장소가 2012년 구축되었다. 134 | 2018년 10월 기준 155,800 여개의 패키지를 제공한다. 135 | 여기에 등록된 패키지들은 pip#를 통해 간단하게 내려받을 수 있다. 136 | 다만, PyPI가 최초, 최대의 패키지 저장소는 아니다. 137 | Python으로 직접 만들었거나 또는 다른 프로그램의 Wrapper가 꼭 존재한다. 138 | 사실상 못하는 것이 없다. 139 | 웹 사이트 서버를 구현하려고 하면 Python Web Framework를 쳐보자(Django, Flask, Bottle 등). 기계학습 알고리즘을 쓰고 싶다면 python machine learning이라 검색하자(scikit-learn). 얼굴인식을 코드 몇 줄로 할 수도 있다(OpenCV). 기본적으로 설치되는 모듈인 tkinter 모듈을 이용하면 간단한 GUI 프로그래밍을 할 수 있다. 140 | 게임도 만들 수 있다(Pygame). 비주얼 노벨도 만들 수 있다(Ren'Py). 141 | Python 가지고 스프레드시트나 데이터베이스까지 만드는 괴수들도 있다. 142 | Python으로 SQL을 구현하는 건 불가능하다는 소리가 있었지만 우리의 Nerd들은 해내고 말았다. 143 | 2013년 Python으로 관리하는 DB 개념이 잡힌 이후 수많은 피드백 끝에 2015년 도전 성공. 심지어 2017년 프랑스의 중견기업에서 Python DB 프로젝트를 보더니 정말로 회사의 DB를 파이썬으로 관리하는 사업을 벌려서 DB화되지 못하고 저장되던 회사 내부의 파일형 자료들과 기존의 DB에 저장된 자료를 접합시키는 사업까지 했다 한다. 144 | 물론 그렇다고 Python만 쓰는 것이 답은 아니다. 145 | 실행 속도(정확히는 CPython의 실행 속도)가 상대적으로 느린 편이라, 빠른 속도가 필요한 프로그램 작성에는 한계가 있다. 146 | 일반적으로 기계어로 컴파일하여 사용하는 C, C++보다는 당연히 느리고, Lua, JavaScript, LISP 계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교해 봐도 속도가 빠른 편은 아니다. 147 | Python처럼 가상 머신 위에서 실행되는 Java, JavaScript 등의 언어들의 경우, 속도 문제를 극복하기 위해서 JIT 컴파일러를 도입했다. 148 | Python의 사실상의 표준 구현체인 CPython은 JIT 컴파일을 도입하지 않았고, JIT 컴파일을 도입한 별도의 구현체인 PyPy가 등장했다. 149 | 통계 분야 등 특정 분야에서는 R과 같이 그 분야에 특화된 언어를 사용하는 것이 더 편리할 수도 있다. 150 | 그리고 동적 타입 언어(dynamically typed language)라는 점이 큰 프로젝트에서는 단점으로 작용하여 자료구조 설계나 디버깅이 어렵다는 지적도 있다. 151 | 다만 "정적 타입 vs. 동적 타입" 논쟁은 서로의 장단점이 있으며 일종의 종교 논쟁으로 취급 받는다. 152 | 일례로 OCaml 같은 강력한 타입 인터페이스(Hindley-Milner, System F 등)를 가진 경우, 모든 타입 에러(!)를 컴파일 타임에 잡아낼 수 있는 반면에, 모든 버그가 타입 에러는 아니기 때문에 여전히 테스트 및 디버깅 과정은 필요하며, 타입 시스템으로 인한 부담 때문에 빠른 구현에는 부담이 될 수 있다. 153 | 반면에 동적 언어는 빠른 구현의 이점이 있지만 타입 에러가 많이 나는 특징이 있다. 154 | 한 마디로, 컴파일 언어의 경우에는 컴파일 시간에 잡아낼 수 있는 오류를 범하게 된다는 소리. Python으로 parser를 많이 작성해봤다면, 십중팔구 읽은 숫자를 string으로 저장했다가 나중에 연산을 했더니 연산이 불가능하다면서 에러가 나거나 이상한 결과가 나온 경험이 있을 것이다. 155 | 그러나 이는 커버리지가 높은 테스트 세트로 어느 정도 커버할 수 있으며 최근의 추세와 부합하는 방식이기도 하다. 156 | 또한 Python 3.5부터는 Type Hints를 이용해서 변수가 가질 수 있는 타입을 지정할 수 있게 되었다. 157 | 성능 향상에 도움은 안되지만 가능한 오류를 쉽게 찾아낼 수 있으며 PyCharm과 같은 IDE 프로그램을 이용하면 도움을 받을 수 있다. 158 | 빠른 아이디어 구현이 생명인 연구소에서 각광을 받고 있고, 한국 밖에서는 당당한 주류 언어로 대우받고 있다. 159 | 인스타그램, 유튜브, reddit 등이 Python을 주로 쓰고 있다고 알려져 있으며, 외국의 구인 사이트에도 Python을 할 줄 아는 사람에 대한 수요가 많다. 160 | 컴퓨터 관련이 아닌 이공계 전반에서 많이 쓰이는 MATLAB은 오픈소스가 아니라는 점이 최근 추세와 맞지 않아 입지가 좁아지고 있다. 161 | CG 업계에서도 사실상 표준으로 사용되는 스크립트 언어이다. 162 | MEL, MAXScript 등 툴별로 자체 스크립트 언어들이 난립하고 있었는데, 현재는 Python 스크립팅을 주력으로 밀고 있다. 163 | 요즘은 가히 춘추전국시대라고 할 수 있을 만큼 새로운 언어와 프레임워크가 계속 등장하고 있으며, 아예 폴리글롯(Polyglot) 프로그래밍이라는 용어가 등장하는 시대다. 164 | 당장 구글만 해도 C++, Java, Python을 골고루 섞어서 쓴다고 알려져 있으며, 게임도 메인은 C++로 작성되었지만 스크립팅은 Python이나 Lua로 된 경우(시드 마이어의 문명, WOW 등)를 매우 쉽게 찾아볼 수 있다. 165 | 따라서 필요하다면 프로그래밍 언어를 가리지 않고 매우 능숙할 수 있게 사용할 수 있도록 공부해야 하며, 알고리즘, 디자인 패턴, 테스트 기법, 동시성 프로그래밍(멀티스레드, 멀티프로세스) 등의 필요한 지식을 훤하게 꿰고 있어야 제대로 된 프로그래머/개발자가 될 수 있다. 166 | Python으로 할 수 있는 것들을 모아 놓은 곳도 있다! 167 | Awesome Python 168 | 169 | Python - 장점 - 교육 170 | 파이썬은 위의 특징 때문에 교육용 프로그래밍 언어로 각광받고 있다. 171 | 한국, 미국의 여러 대학교 프로그래밍 교육들은 개론 수업 언어를 C, C++나 Java에서 Python으로 옮겨가는 추세다. 172 | 주의할 점은 Python이 배우기 쉽다는 건 프로그래머 입장에서 나온 말이라는 것이다. 173 | 그마저도 다른 언어에 비해 비교적으로 쉽다는 뜻이지, 깊게 파고 들어가거나 특유의 '파이썬스러움(pythonic)'한 코딩을 하려면 생각보다 신경쓸 것도 많고 동적 언어에 익숙해져 있어야 한다. 174 | 더욱이 컴파일러 없이 프로그래밍 하는 것은 깡초보에게 권장할 만한 것이 아닌게, 정적 언어에 대한 개념도 없이 동적 언어를 잡았다가는 오히려 더 헷갈릴 수 있다. 175 | 왜 마이크로소프트가 TypeScript를 만들었는지 잠시 생각해 보기 바란다. 176 | 더욱이 파이썬은 편집증이 의심될 정도로 객체 위주로 돌아가긴 하지만, 언어의 패러다임을 보면 절차지향, 객체지향, 함수형 모두 사용할 수 있는 언어다. 177 | 극단적으로 OOP를 지향하는 Java나 C#보다 더 신경써야 할 것이 많다는 이야기. 하여튼 프로그래밍 자체를 마냥 쉬운 것으로 생각하다면 큰 코 다친다. 178 | 프로그래밍을 쉽게 할 수 있는 것과 좋게 하는 것에는 큰 차이가 있으며, '좋은' 프로그래밍을 하는 것은 프로그래머의 역량에 크게 좌우된다. 179 | 180 | Python - 문제점 181 | 파이썬은 시스템을 건드리거나 반복연산이 많은 것은 하기 어렵지만 python num 처럼 따로 모듈을 지원하기 때문에 크게 걱정할 필요는 없다(그래도 python num을 사용해도 느린건 느리다;;). 182 | 이 단점은 반복 연산이 있는 C를 사용하여 작성하면 사라진다. 183 | 184 | Python - 문제점 - 멀티스레딩 불가 문제 185 | 파이썬은 멀티스레딩을 지원하기 위하여 GIL(Global Interpreter Lock), 즉 전역 인터프리터 락을 도입하여 사용하게 되었다. 186 | 따라서, python 스레드 10개를 만들어도 실제 Pthread/윈도우 스레드가 10개가 만들어지긴 하는데, GIL때문에 개중 동시에 하나밖에 안돌아가는 기이한 구조를 갖고 있다. 187 | 물론, 내부적으로 IO작업이 있을 시 바로 다른 스레드로 문맥 교환을 해주고, 바이트 코트를 100번 실행한 다음에는 인터프리터 차원에서 다른 스레드로 교체 해주므로 동시 작업 비슷한 효과가 난다. 188 | 이것은 구현이 매우 쉬워지고 빠른 개발을 할 수 있다는 장점이 있으나, 다중 코어 CPU가 보편화된 2006년 이후에는 다중 코어를 제대로 활용하지 못하는 구조적인 문제 때문에 성능에서 밀린다는 평가를 받게 되었다. 189 | 만일 특정 프로그램에 순진하게 CPU 코어를 2개 이상 동원하려고 할 경우, 뮤텍스(MutEx), 즉 한 스레드에 여러 개의 CPU가 연산을 행하여 내부 정보를 오염 시키는 것을 방지하는 역할을 맡는 GIL이 병목 현상을 일으켜 코어 하나를 쓸 때보다 오히려 성능이 크게 저하된다는 것. 190 | 구글 내부에서 이미 가루가 되도록 까인 부분이다. 191 | 더불어, 예전의 Python에는 CPU-bound한 스레드가 I/O-bound한 스레드와 함께 돌아갈 때, I/O-bound한 스레드가 실행되어야 할 상황에서도 context switch가 제대로 이루어지지 않는 문제가 있었다. 192 | 이 때문에 CPU-bound 스레드가 GIL을 지나치게 오래 점유하게 되면서 I/O 반응 속도가 느려지고, 다른 스레드는 GIL을 획득하려고 계속 시도하느라 CPU 시간을 낭비하게 되었다. 193 | 이에 대해 파이썬 전문가인 David Beazley가 2009년에 Mindblowing Python GIL이라는 강연에서 지적하였다. 194 | 이후 Antoine Pitrou라는 개발자가 GIL을 뜯어고쳐 해당 문제를 해결하였고, Python 3.2부터는 새로운 GIL이 적용되어서 성능이 어느 정도 개선되었다. 195 | 이런 문제점 때문에 파이썬에서 병렬 처리가 필요할 때는 다중 스레드가 아닌 다중 프로세스로 GIL을 우회하는 방식을 사용한다. 196 | 2008년 이후에 multiprocessing이라는 모듈을 제공하는데 이 모듈은 자식 프로세스를 만드는 방향으로 다중 코어 사용 시 성능의 향상을 꾀하고 있다. 197 | 단, CPU 부하가 큰 작업을 돌리는 것이 아니면 GIL을 체감하기는 생각보다 쉽지 않다. 198 | 다중 스레딩으로 CPU의 여러 코어를 최대한 이용하고 싶은 경우에는 GIL가 굉장히 아쉬운 이슈지만, CPU를 별로 쓰지 않거나 I/O가 주가 되는 작업은 유의미한 성능 차이가 없다. 199 | 게다가 어설프게 코어 몇개 깔짝깔짝 이용해서 계산하는 것보다는 그냥 C언어로 모듈을 짜서 붙이는 게 더 빠르다. 200 | 즉, python에서 CPU를 많이 먹는 부분은 C 모듈을 짜서 붙이거나, 이미 C 모듈로 짜여있는 라이브러리를 사용하거나(Numpy, Scipy 등), 필요하다면 multiprocessing 모듈을 이용하여 멀티코어를 활용하는 편. 그 이상의 CPU-heavy한 작업은 처음부터 C, C++로 짜는 게 맞다. 201 | 자세히 알고 싶다면 다음 링크들을 참조.(너무 오래된 링크들이라 차라리 인터넷 검색해서 최근 글들을 보기 바란다.) 202 | 파이썬 GIL 깊숙히! (上) (2006년도) 203 | 파이썬 GIL 깊숙히! (上) 에 대한 몇 가지 변명 (2007년도) 204 | “파이썬은 멀티코어 줘도 쓰잘데기가 없나요?”에 대한 파이썬 2.6의 대답 (2008년도) 205 | Understanding the Python GIL (유튜브) (2010년도) 206 | Python에서의 동시성/병렬성 (2014년도) 207 | 하지만 대규모 연산의 멀티코어의 성능 향상을 보기 위한 것 말고도, I/O가 주가 되는 작업(즉, 여러 개의 I/O 이벤트를 기다리는 것)을 위해서 멀티스레드를 사용하는 경우가 많고, 이런 경우에도 복잡한 동기화를 해야 하는 멀티쓰레딩을 사용하는 건 낭비이다. 208 | 왜냐하면 디버깅도 힘들 뿐만 아니라, 실제로는 I/O를 위해 기다리는 시간이 실제 I/O가 발생했을 때 필요한 처리 작업을 수행하는 시간보다 월등히 긴 경우가 많아 여러 개의 스레드를 관리하기 위한 자원만 낭비하는 꼴이기 때문이다. 209 | 따라서 Go나 Erlang 같은 최근의 프로그래밍 언어들은 코루틴이란 개념을 도입해 이러한 "event multiplexing"을 싱글스레드로도 구현할 수 있게 하고 있다. 210 | 특히 멀티쓰레딩할 때 필요한 각종 동기화 문제 없이 마치 싱글 스레드 코드를 짜는 것과 거의 동일한 방식으로 코드를 작성할 수 있으면서도 그러한 코드들이 "동시에" 동작하는 것처럼 실행해주므로 프로그래머 입장에서 매우 편하다. 211 | 실제로는 각 이벤트에 필요한 처리를 하고 다음 이벤트가 발생하기 전까지 비는 시간에 다른 이벤트를 처리하는 코드를 실행시켜주는 방식으로, 시분할과 비슷하지만 문맥 전환이 프로그래머가 작성한 코드에서 명시적으로 다음 이벤트를 기다려야 할 필요가 있을 때 협력적으로 발생한다는 차이점이 있다. 212 | C같은 언어에서 이러한 코루틴 지원이 잘 안 되는 이유는, 언어적 차원에서 함수 중간에 실행을 멈추고 다른 함수를 실행할 수 있게 해줘야 하는데 스레드 별로 stack이 1개밖에 없는 구조에서는 구현이 어렵고 하나의 함수로 짜야 할 내용을 여러 개의 callback 함수로 쪼개면 코드가 지저분해진다는 단점이 크기 때문이다. 213 | 이런 callback형태를 사용하는 게 Node.js 개발 환경이다. 214 | 현재로써는 이런 콜백 방식이 유연하면서 퍼포먼스가 좋은 방식이지만 언어적으로 약간 더럽다. 215 | 위에서 기술한 Stackless Python에서 코루틴을 먼저 지원할 수 있었던 것도 이런 배경이 있다. 216 | 다행히 Python은 (stackless가 아니더라도) yield 키워드를 통해 함수 실행 흐름을 제어할 수 있다. 217 | Python 3.4 버전부터는 표준 라이브러리의 각종 파일 입출력, subprocess, socket 통신 등의 기능들을 모두 코루틴화 해주는 asyncio 패키지가 기본 탑재되었다. 218 | Python 3.5 부터는 C를 본딴 async 함수 선언자와 await 키워드가 포함되어 asyncio 라이브러리에 의존할 수밖에 없던 코루틴 기능을 다른 서드파티 라이브러리도 보다 쉽게 지원할 수 있도록 바뀌고, 코루틴 내부에서의 예외처리 과정이 개선되었다. 219 | 220 | Python - 문제점 - 멀티스레딩 불가 문제 - 멀티코어로 프로그램 돌리기 221 | 유닉스, 리눅스, macOS의 파이썬에서 멀티코어를 쓰려면 아래와 비슷한 방식으로 소스 코드를 적으면 된다. 222 | 윈도우즈는 포크(fork) 함수가 없어 아래 코드를 추가해야 한다. 223 | 224 | Python - 문제점 - 난잡한 패키지 관리 및 하위 호환 에러 225 | 최신 언어에 비해 패키지를 설치하거나 만들어 배포하는 방식이 복잡하다. 226 | 이는 역사가 오래된 언어이다 보니 패키지를 다루는 방식이 여러 차례 바뀌었기 때문이다. 227 | 228 | Python - 문제점 - 난잡한 패키지 관리 및 하위 호환 에러 - 패키지 설치 및 관리 229 | 오늘날 파이썬 라이브러리를 설치할 때는 주로 pip을 이용한다. 230 | 이 방식은 모든 패키지를 기본적으로 설치된 파이썬에 추가하기 때문에 몇 가지 문제가 생긴다. 231 | 우선 여러 프로젝트를 동시에 작업할 때 호환성 문제가 생길 수 있다. 232 | 가령 프로젝트 A는 라이브러리 X의 1.1 버전을 사용하는데, 다른 프로젝트 B는 호환성 문제 때문에 X의 1.0 버전을 사용해야 할 경우가 있다. 233 | 이 경우 라이브러리 X의 1.1 버전과 1.0 버전을 동시에 설치할 수 없기 때문에, 가상 환경이라는 것을 만들어 프로젝트 A와 B에서 사용하는 패키지를 분리해야 한다. 234 | 가상 환경은 virtualenv라는 도구를 이용해 만들 수 있으며, Python 3.3부터는 표준 라이브러리에 포함된 venv 모듈을 직접 호출하여 만들 수 있다. 235 | 위의 명령은 현재 디렉토리에 my-venv라는 가상 환경을 생성한다. 236 | 일반적으로는 가상 환경 이름도 venv로 한다. 237 | 또한 pip은 패키지 간의 호환성을 꼼꼼하게 따지지 않는다. 238 | 가령 위의 프로젝트 A와 B를 남들이 사용할 수 있게 라이브러리로 만들었다고 하자. 239 | 다른 컴퓨터에서 pip을 사용해 A를 설치하면 A가 필요한 X의 1.1 버전이 설치된다. 240 | 이후 B를 설치하면 X의 1.1 버전을 삭제하고 1.0 버전을 설치하기 때문에 A를 쓸 수 없게 된다. 241 | npm과 같은 현대적인 패키지 관리자들은 패키지 호환성을 꼼꼼하게 검사하기 때문에 이런 상황에서는 B를 설치하려 하면 거부하지만, pip은 그런 거 없다. 242 | 리눅스와 같이 자체적으로 파이썬을 탑재한 운영체제에서는 호환성 문제를 특히 신경써야 한다. 243 | 시스템에 내장된 핵심 도구들이 기본적으로 설치된 파이썬 라이브러리를 사용하기 때문이다. 244 | 만약 패키지를 설치하다가 호환성 문제가 생기면 최악의 경우 OS를 재설치해야 할 수 있다. 245 | 따라서 이런 OS에서는 시스템 내장 파이썬에 패키지를 설치하면 안 되며, 대신 #pip install --user로 사용자별 기본 환경에 설치하거나 별도의 가상 환경을 만들어야 한다. 246 | 혹여나 프로그램 간 접합 등을 이유로 파이썬의 라이브러리를 사용하다 해당 기능을 외부 모듈(.msi, .exe, .pkg등의 설치파일)을 이용해 서버에 내장하여 돌리려는 때에는 정말 지옥을 맛볼 수 있다. 247 | 파이썬의 라이브러리가 불러오는 코어와 서버에 설치되는 모듈이 불러오는 코어가 다르기 때문. (이런 경우는 상상하면 수명만 줄어들 뿐이다.) 이를 고치려면 에러의 콜스택을 따라가며 어디서 문제가 생겼을지 머리를 쥐어짜고 모듈 내의 코드를 뜯어 고치는 수밖에 없다. 248 | 사실 이 문제는 다른 언어에서도 있을 수 있는 일이다. 249 | 다만 파이썬의 경우 패키지 버전의 통일성 부족과 만나버리는데, 버전에 따라 천차만별로 다를 이 대처법들이 인터넷 온갖 구석을 다 뒤져도 나오지 않아 아스트랄한 난이도를 선사한다. 250 | (나오긴 하지만, 해결되지 않는 경우가 많다. 물론 직접 질문을 올려도 대부분 답은 안나온다.) 차라리 처음 발견되면 사용하는 라이브러리나 내부 구조를 바꿔서 피해갈 수 있지만, 이미 진행될대로 진행된 프로젝트인 경우 그저 행운이 함께하길 빌 뿐이다. 251 | 252 | Python - 문제점 - 난잡한 패키지 관리 및 하위 호환 에러 - 패키지 개발 및 배포 253 | 파이썬으로 만든 프로그램이나 라이브러리를 다른 사람들이 사용할 수 있게 만들려면 복잡한 과정을 거쳐야 한다. 254 | 파이썬의 라이브러리 개발 방식은 세월이 흐름에 따라 여러 차례 바뀌었다. 255 | 패키지 관리자라는 개념이 없어서 각자 프로그램의 소스 코드를 다운로드해 쓰던 시절에는 setup.py라는 설치 스크립트를 각자 만들어서 파이썬 프로그램과 함께 배포하는 것이 관행이었다. 256 | 이를 언어 차원에서 지원하기 위해 Python 1.6부터는 distutils라는 빌드 도구를 기본 탑재하였다. 257 | 그런데 distutils는 자신의 프로그램이 필요로 하는 다른 패키지를 설치하지 못한다는 치명적인 문제가 있어서, 이를 해결하기 위해 setuptools라는 도구가 등장하였다. 258 | 세월이 흘러 pip이라는 패키지 관리자와 PyPI라는 패키지 저장소가 등장하면서, setup.py를 만드는 기존의 방식의 단점이 부각되었다. 259 | setup.py를 실행하는 데 필요한 도구가 있는지 확인하고, 없으면 자동으로 설치하거나 사용자에게 알려주는 기능이 없다. 260 | setup.py는 파이썬 코드로 작성하기 때문에 패키지 이름이나 버전과 같은 메타데이터를 추출하는 것이 까다롭다. 261 | setup.py에는 아무 파이썬 코드나 넣을 수 있으므로 악의적인 코드를 심을 수 있다. 262 | setup.py는 setuptools를 직접 import하기 때문에 사용자가 다른 빌드 도구를 선택할 수 없다. 263 | 이 때문에 setup.py를 작성하는 대신 pyproject.toml이라는 설정파일을 사용하는 표준안인 PEP-518이 등장하였다. 264 | pip 10.0부터는 pyproject.toml을 지원한다. 265 | 다만 운영체제 중에는 최신 버전의 pip을 탑재하지 않은 경우도 많기 때문에 pip을 업데이트해야 한다. 266 | flit이나 Poetry 등의 개발 도구를 사용하면 setup.py를 작성하지 않고 패키지를 만들어 배포할 수 있다. 267 | 물론 예전 방식대로 distutils/setuptools를 사용하면서 setup.py과 pyproject.toml를 함께 사용하는 것도 가능하다. 268 | Python 으로 개발한 SW를 공개 배포하는 경우 소스 코드가 그대로 노출된다. 269 | 예를 들어 상용 프로그램이나, 보안을 유지해야 하는 경우 파이썬 코드를 숨겨야 한다. 270 | Py파일을 Bytecode로 컴파일하는 방법# 271 | PyInstaller를 사용해서 EXE 또는 ELF 형식의 실행 파일을 만드는 방법 사용법과 주의사항 272 | 가장 쉬운 방법은 byte code인 pyc파일로 변환하는 방법이다. 273 | 하지만, 이 방법은 조금만 노력하면 디컴파일이 쉽게 되기 때문에 코드를 숨길 수 없고 다만 코드 보기를 조금 어렵게 만드는 것으로 이해해야 한다. 274 | Pyc 파일보다 나은 방법은 PyInstaller를 사용하는 방법이다. 275 | PyInstaller는 Py파일을 종속성을 분석해서 필요한 shared lib를 하나에 폴더에 패키징하고, EXE나 ELF의 실행 파일을 생성하여 소스 코드를 숨길 수 있다. 276 | PyInstaller로 패키징하는 과정에서 --key 옵션을 사용하면 AES256 으로 Bytecode를 암호화한다. 277 | 278 | Python - 다양한 python 구현체 종류 279 | 보통 말하는 Python은 C로 구현되었으며, 다른 구현체와 구분하여 언급할 때는 CPython이라고 표기한다. 280 | #1 또는 #2에서 소스 코드를 열람해볼 수 있다. 281 | Stackless Python은 CPython에서 C 스택을 없앤 것이다. 282 | Cython은 파이썬 소스 코드를 C 언어 코드로 변환하여 컴파일한다. 283 | Pyston은 C++로 구현되었다. 284 | 파이썬 자체로 구현된 PyPy도 있다. 285 | Pyston과 PyPy는 JIT가 구현되어 있다. 286 | Java로 구현되어 Java Virtual Machine 위에서 돌아가는 Jython과 C\#으로 구현된 .NET Framework 위에서 동작하는 IronPython이 있다. 287 | Jython과 IronPython은 가상머신에서 동작하는 구현체이다. 288 | 시작부터 JVM 또는 .NET CLR 위에서 동작하는 Python 구현체를 도입하는 경우는 매우 드물다. 289 | 기존에 Java나 .NET Framework에서 개발되어 운영되던 프로그램이나 시스템이 존재하고, 이 환경 하에서 Python의 간결하고 편리한 기능과 높은 생산성을 도입하고자 할 때 사용된다. 290 | Jython과 IronPython은 둘 다 CPython에 비하면 실행 속도가 매우 느리며, Jython은 경우에 따라서 심각할 정도로 많이 느리다. 291 | 따라서 주요 기능을 수행하는 데에는 문제가 있지만, 보조 기능에서 사용하면 번거로운 작업들을 매우 손쉽게 Python 스크립트로 Java, .NET Framework의 자원을 그대로 끌어다 써서 할 수 있기 때문에 개발 공수와 편리함에서 큰 장점이 있다. 292 | JavaScript로 구현한 Brython과 Skulpt도 있다. 293 | Pythonpad에서 Brython 기반으로 코드를 실행해볼 수 있다. 294 | 한편 중국에서는 Chinese Python이라는, 중국어 문법으로 한자를 쳐서 돌아가는 언어를 독자 개발했다. 295 | 296 | Python - 다양한 python 구현체 종류 - Stackless Python 297 | 파이썬의 표준 구현인 CPython은 이름 그대로 C로 만들어져 있는데, 파이썬 프로그램의 함수 호출 스택(Call stack)을 구현할 때 그만 C의 호출 스택에 그대로 얹어가도록 구현되고 말았다. 298 | 때문에 파이썬에서 얼마나 메모리를 많이 쓸 수 있느냐에 관계없이 C 호출 스택을 꽉 채우는 순간 그대로 스택 오버플로우 에러가 뜨게 되어버렸고, 파이썬 프로그램의 호출 스택, 즉 프로그램의 실행 흐름을 CPython 스스로 제어할 수가 없게 되어 코루틴 등의 실행 흐름을 제어하는 언어 기능을 쓸 수 없게 되고 말았다. 299 | Christian Tismer라는 개발자는 이 문제를 타파하려면 "CPython 소스코드를 수정해서 C 스택을 쓰는 부분을 전부 들어내고 새로 호출 스택을 짤 수밖에 없다"고 생각했고, 그것을 실제로 실행에 옮긴 것이 Stackless Python이다. 300 | 이름의 Stackless는 그래서 사실 C 호출 스택이 없다는 의미. Stackless Python은 스택 오버플로우 에러가 덜 난다는 사소한 장점 외에도, 스스로 제어할 수 있는 자체적인 호출 스택을 갖고 있기 때문에 마이크로쓰레드나 코루틴 같은 기능들을 쓸 수 있게 됐고, 덕분에 쓰레드도 고자고 코루틴도 안되는 CPython에 비해 동시성 처리에서 훨씬 강력한 이득을 낼 수 있게 됐다. 301 | CPython도 3.4 버전 이후로 코루틴을 지원한다. 302 | 아래 멀티쓰레딩 섹션 참조. 303 | 다만, 앞서 말했듯이 CPython을 개조한 것이기 때문에, 파이썬의 버전이 올라갈 때마다 개조한 코드가 이상없이 동작하는지 항상 확인해야 하고, 이 기능이 운영체제나 하드웨어에도 영향을 받는 까닭에 심하면 각각의 운영체제나 CPU별로 개발을 따로 해야 하는 피곤한 작업을 Python이 망할 때까지 해야 하는 지겨운 길을 걷게 되는 것이었다. 304 | 그래서 실제로 한동안 Stackless Python의 개발이 잠시 중단된 일도 있었을 정도. 305 | 그런 와중에 PyPy 리드 개발자 Armin Rigo가 "C 호출 스택도 어차피 메모리에 있잖아? '''그러면 그걸 'memcpy()'로 통째로 복사하고 덮어 씌우면 호출 스택을 저장하고 복구하는 거 아냐?"라는 실로 마개조스러운 아이디어를 내놓는데, Christian Tismer가 여기에 매우 깊은 감명을 받고 Armin Rigo와 함께 구현한 결과 greenlet이라고 하는 import만 하면 코루틴을 쓸 수 있는 모듈'''을 만들어내기에 이른다. 306 | 같은 걸 구현하려고 언어 인터프리터 자체를 뜯어 고치는 수고에 비하면 놀랄 만큼의 노력 절약이 아닐 수 없다. 307 | 다만 이 짓을 제대로 구현한 Stackless Python에 비하면 아무래도 성능이 딸리기 때문에 정말 절실하게 성능이 필요한 EVE 온라인과 같은 경우엔 Stackless Python을 쓴다. 308 | 하지만... Armin Rigo와 Christian Tismer는 지금 둘 다 PyPy를 만들고 있고, PyPy는 자체 스택을 쓸 수 있는 Stackless 모드의 JIT 컴파일러를 만들어낼 수 있다. 309 | 310 | Python - 다양한 python 구현체 종류 - C 언어 확장, Cython 311 | 312 | Python의 속도를 높이고자 아예 C언어로 변환하여 컴파일하는 방법을 택한 패키지. 313 | 파이썬의 문법을 확장하여 정적 타입 선언 기능을 넣어, 기존의 C 코드를 쉽게 접착할 수 있도록 만들었다. 314 | Python C API를 이용하여 C 코드를 직접 접착하는 기존의 방식보다 훨씬 사용하기 쉽고, C언어로 변환되어 컴파일 된다는 점 때문에 ctypes로 덧씌우는 것 없이 네이티브 코드(*.so, *.dll)를 직접 사용할 수 있다. 315 | 이것을 사용하면 적게는 열 배 정도에서 많게는 천 배 이상까지 속도 향상을 경험할 수 있다. 316 | (물론, 파이썬과 C의 구현 차이를 잘 이해하고 컴파일이 제대로 동작할 수 있게하기 위한 코드 수정이 요구된다. 그냥 냅다 넣고 돌려버리면 제기능을 제대로 발휘하지 못하거나 심지어는 거의 발전이 없는 경우도 생길 수 있다. 프로파일링은 언제 어디서나 기본이다.) 317 | C를 모르는 상태에서 Cython을 사용하는 것이 아예 의미가 없는 것은 아니지만, C와 Python 둘 모두에 익숙할 때 Cython을 가장 효과적으로 쓸 수 있다. 318 | 고성능이 필요하면 일단 코드 수정이 불필요한 PyPy를 시도하고, 그걸로는 만족스럽지 않을 때 외부 라이브러리를 도입해 보고, 그걸로도 부족할 때 고려해보자. 319 | Cython의 대안으로는, SWIG, CFFI(C Foreign Function Interface), pybind(C++ 전용) 등의 도구들이 있다. 320 | 참고로, PyPy도 Cython에 크게 밀리지 않을 정도로 속도가 빠르고, PyPy를 사용하여 실행했을 때 속도 향상이 별로 없다면 Cython을 사용하여 C로 변환해도 상황이 비슷한 경우가 많다. 321 | Cython을 사용하여 속도 향상 효과를 얻고자 한다면, 파이썬 코드를 바로 실행할 수 있는 PyPy를 사용하여 속도를 미리 체크해보는 것이 유용한 방법이 될 수 있다. 322 | 323 | Python - 다양한 python 구현체 종류 - C++ 구현, Pyston (프로젝트 중단) 324 | Pyston은 LLVM 컴파일러를 사용한다. 325 | Pyston은 JIT(just-in-time) 컴파일러를 내장하여 반복되는 소스 코드를 빠르게 실행할 수 있다. 326 | 2014년 4월 프로젝트가 시작되었으며, Python 2.7 호환, x86 64비트 플랫폼을 목표로 개발 중에 있다. 327 | Dropbox Tech Blog - Introducing Pyston: an upcoming, JIT-based Python implementation (April 3, 2014) 328 | Pyston은 C++로 작성되어졌다. 329 | Technical overview · dropbox/pyston Wiki · GitHub (1 Sep 2016) 330 | 우분투에서만 테스트되고 있다. 331 | 그러다가 2017년 1월 31일부로 Dropbox에서 공식적으로 스폰싱을 종료했다. 332 | Pyston 0.6.1 released, and future plans (January 31, 2017) 메인테이너가 Dropbox 직원인데 더 이상 참여를 못하는 사실상 프로젝트 중단이다. 333 | 직후 프로젝트 리더였던 Kevin Modzelewski는 퇴사하였다. 334 | 성능은 상당히 훌륭한 편이었으나, CPython과의 호환성을 오랫동안 맞추지 못했고, 프로젝트가 시작됐을 때와 다르게 Dropbox의 코드가 Go랑 Python3로 많이 이전된 것이 원인으로 보인다(즉, 굳이 투자하면서 개발을 지속할 이유가 없는 상황). 또한 곧 Python2 버전이 공식적으로 지원이 중단될 예정이라서 완전하게 돌아가게 되는 시점(이조차 아무도 알 수 없었다)에서 이 프로젝트의 의미가 많이 퇴색될 수밖에 없었던 것. 335 | 336 | Python - 다양한 python 구현체 종류 - Python 구현, PyPy 337 | Python으로 Python을 만드는 프로젝트. JIT 컴파일을 사용하기 때문에 훨씬 빠르다. 338 | 339 | Python - 다양한 python 구현체 종류 - Java 구현, Jython 340 | Jython은 Java로 구현되어 JVM 위에서 실행된다. 341 | # CPython이 C언어와 결합성, 접착성이 좋은 것처럼 Jython은 Java와 결합성이 대단히 좋으며, 실제로 Java 진영의 메이저 업체인 Oracle, IBM 등에서도 자사 제품에 Jython을 내장하여 스크립팅 기능을 제공하고 있을 정도다. 342 | Jython은 JVM 위에서 실행되며, Python Module이 제공하는 API는 물론이고, JDK가 제공하는 모든 API를 그대로 사용할 수 있다. 343 | 오히려 pycrpyto와 같이 C언어로 구현된 CPython 모듈은 Jython에서 사용할 수 없다. 344 | 그러나 일단 Java Class라면, 설령 JNI로 되어있어서 C로 작성된 동적 모듈(*.dll, *.so 등)을 사용한다고 해도 Jython에서 사용하는데 아무런 제약이 없다. 345 | 또한 JVM 위에서 실행된다는 점 때문에 CPython의 GIL이 이식 되지 않았으며, CPython이 멀티스레드에서 보이는 단점이 Jython에는 존재하지 않는다. 346 | threading, threadsafety 등의 Python에서 제공하는 멀티스레드(락, 동기화 관련) 기능이 마음에 들지 않으면 java.util.concurrent에서 제공하는 Java API를 사용하면 된다! 347 | 348 | Python - 다양한 python 구현체 종류 - .NET Framework 구현, IronPython 349 | Microsoft .NET Framework의 가상머신인 CLR 상에서 구현되고 이 위에서 동작하는 Python이다. 350 | 정확히 말하면 이들 동적언어를 CLR 위에서 구현하기 위한 DLR이라는 프레임워크 기반이다. 351 | 제작자 Jim Hugunin#은 Jython의 제작자이며, NumPy의 전신인 Numeric 라이브러리의 제작자이기도 하다. 352 | 따라서 당연히 .NET Framework 환경에서 제작된 DLL과 결합성이 매우 좋다. 353 | Jython과 마찬가지로 병렬 프로그래밍 환경에서 GIL 때문에 고민할 필요가 없다. 354 | 자매품으로는 C\#로 작성된 모듈을 마치 파이썬 모듈처럼 임포트해서 쓸 수 있는 Python for .NET이 있으며 이 경우에는 CPython 위에서 돌아간다. 355 | 356 | Python - 다양한 python 구현체 종류 - JavaScript 구현, Brython 357 | JavaScript로 구현되었고, JavaScript를 대신하여 웹 브라우저에서 스크립트 형태로 Python을 실행할 것을 목적으로 하는 'Brython'이 있다. 358 | Python3를 구현했으며, 다음과 같이 script 태그의 type을 text/python으로 지정하여 실행할 수 있다. 359 | 360 | Python - 다양한 python 구현체 종류 - JavaScript 구현, Brython - 자바스크립트로 컴파일 transcrypt 361 | 타입스크립트와 비슷한 방식으로 파이썬 코드를 자바스크립트로 컴파일해서 일반적인 자바스크립트와 혼합하여 사용할 수 있게 해준다. 362 | (Ex. 파이썬 + jQuery) 363 | 364 | Python - 다양한 python 구현체 종류 - Micro Python 365 | 파이썬3의 기능을 임베디드 보드에 최적화 하여 구현한 프로그래밍 언어이다. 366 | Windows OS와 Windows Embeded OS와의 관계를 생각하면 이해하기 쉽다. 367 | 국내에서는 주로 마이크로비트보드에서 사용할 목적으로 많이 사용된다. 368 | 카시오 FX-9860 GIII에 탑제되어 있기도 하다. 369 | 370 | Python - 생태계 - 개발 환경 371 | 콘솔 372 | 윈도우 명령 프롬프트나 리눅스 Bash 같은 곳에서 실행하는 콘솔형 파이썬 인터프리터다. 373 | 여기서도 충분히 간단한 코딩을 할 수 있고, 콘솔 상에서도 pretty printer를 이용해 다양한 자료 구조를 ASCII Art로 출력해 주는 기능까지 이용해볼 수 있다. 374 | IDLE 375 | 파이썬 기본 탑재 콘솔로, 순수 파이썬으로 작성되었다. 376 | 콘솔과 같이 직접 명령을 입력하는 것 외에도 파이썬 스크립트를 직접 편집할 수 있으며, 문법 강조와 디버깅 등의 기능을 지원한다. 377 | 파이썬에 입문하는 경우에는 따로 텍스트 에디터를 설치할 필요 없이 IDLE만으로도 충분하다. 378 | IPython 379 | 오픈 소스 라이브러리로, 파이썬 IDLE와 달리 LaTeX나 svg, Matplotlib의 플롯 같은 것들도 출력해준다. 380 | _repr_이라는 특수 prefix가 붙은 메서드들을 클래스에 정의해 놓으면 IPython의 출력 기능과 쉽게 통합시킬 수 있다. 381 | 후술할 Jupyter의 백엔드로도 쓰인다. 382 | 383 | Python - 생태계 - 개발 환경 - 텍스트 에디터 384 | 문법 강조와 자동 들여쓰기 등의 편의 기능을 제공하는 프로그램. 메모장보다는 기능이 많고 IDE보다는 기능이 부족한, 중간 정도의 에디터라고 보면 된다. 385 | IDE보다 기능은 부족한 대신 로딩 속도가 빠르고, 자잘한 버그가 없기 때문에 개인 취향이나 프로젝트 성격에 따라 이쪽을 더 선호하기도 한다. 386 | 파이썬 문법은 C나 Java처럼 Boilerplating이 별로 없기 때문에 IDE의 자동 완성 기능이 상대적으로 덜 중요하다. 387 | 개중에는 플러그인을 설치하여 IDE 못지않은 기능을 추가할 수 있는 경우도 있다. 388 | Notepad++ 389 | Sublime Text 390 | Atom 391 | Visual Studio Code: Python 전용 플러그인을 설치하면 더 많은 기능을 이용할 수 있다. 392 | 393 | Python - 생태계 - 개발 환경 - 통합 개발 환경(IDE) 394 | PyCharm 395 | JetBrains 사에서 개발한 IDE로, 코드 컴플리션 기능이 우수하고 각종 프레임워크 지원이 가장 뛰어나다. 396 | 커뮤니티 에디션은 무료이지만 Django 같은 웹 개발에 도움이 되는 툴을 쓰려면 프로페셔널 에디션을 사용해야 한다. 397 | 프로페셔널 에디션이 없더라도 플러그인 등을 통해 기본적인 html/javascript 문법지원과 기본적인 자동완성은 가능하지만, Django 전용 자동완성(예를 들어 템플릿에서 파이썬 변수명을 자동완성해 준다던지), 실시간 렌더링 등의 기능은 사용할 수 없다. 398 | Spyder 399 | 오픈 소스 IDE로 PyCharm 프로페셔널 에디션 같은 툴을 쓰기 힘든 학생이나 개인 개발자가 사용할 만한 대안이다. 400 | Visual Studio 401 | 가장 무거운 개발 툴이지만 Breakpoint를 설정해 디버깅을 할 수 있거나, Variable Explorer을 가지고 있거나, Profiler를 가지고 있는 등 기능이 다양해서 충분한 값어치를 할 수 있으면 쓰는 것이 좋다. 402 | 그 외에도 파이썬으로 프로그래밍에 입문하는 사람들에게도 설치가 쉽다는 점에서 추천하는 편이다. 403 | 404 | Python - 생태계 - 개발 환경 - Notebook 405 | 다소 특이한 개발 환경으로, 스타일 있는 문서 양식에 코딩을 접목시킬 수 있다. 406 | 블로그나 노트를 쓰듯이 단락을 만들고, 그 안에 Cell을 만들어서 코드를 적어놓고, 실행시키면 Plot 같은 것을 보여줄 수 있다. 407 | 물론 이런 것이 무슨 프로그래밍인가 싶긴 하지만, 데이터 사이언스나 데이터 분석과 같은 분야는 완성된 시스템을 만들기보다, 파이썬 코드로 데이터를 어떻게 처리하면 되는지 프로토타입을 만들고 그것을 가지고 리포트를 쓰거나 프리젠테이션을 하는 일이 많기 때문에 많이 사용한다. 408 | 즉 이들에게는 하나의 완성된 프로그램을 만드는 것이 아니라 데이터를 이리저리 돌려보며 코딩 → 결과 확인 → 코드 수정 → 결과 확인 등의 반복적인 작업이 중요하기 때문이며, 데이터 시각화와 같은 분야에서도 코드를 셀 단위로 나누어 반복 수정하는 작업을 하는 데에 있어서 매우 유용하기 때문이다. 409 | SymPy, NumPy, SciPy, Matplotlib 같은 수학, 과학, 머신 러닝 라이브러리를 자주 이용하는 환경에서 개발할 때 유용한 편이며, pandas 등의 라이브러리를 사용하여 데이터 분석을 하는 데도 많이 사용한다. 410 | 사실상 데이터 분야에서 Notebook은 업계 표준과 같은 취급이며, 이 때문에 Google의 Colaboratory나 MS의 Azure Notebook과 같은 클라우드 기반의 데이터 분석 환경 역시 jupyter notebook을 모방하거나 탑재하고 있다. 411 | 공부하는 입장에서 스크립트 파일을 일일이 만들어야 하는 통상적인 개발 방식이 번거롭게 느껴진다면 차라리 Notebook을 이용해 각종 알고리즘을 연습해 보는 것이 좋다. 412 | 다만 파일이 단순한 스크립트 파일이 아니라 거진 워드 문서 같은 수준이 되어 버리기 때문에 (Plot 같은 것을 바이너리 형태로 저장해야 하기 때문이다) 용량이 커지고 Git과 궁합이 맞지 않게 된다는 점은 단점이다. 413 | 또한 최소 천 줄이 넘어가는 프로젝트는 노트북으로 하면 안 된다. 414 | 노트북은 프로토타이핑이나 리포트를 쓰는데에나 활용하고 진짜 개발은 파이썬 스크립트 파일을 작성해 하도록 하자. 415 | ipython 416 | Jupyter Notebook 417 | JupyterLab 418 | Google Colaboratory 419 | 420 | Python - 생태계 - 개발 환경 - 패키지 관리 421 | 각종 파이썬 라이브러리를 설치하고 관리하는 도구이다. 422 | 몇몇 파이썬 라이브러리는 리눅스의 패키지 관리자로도 설치할 수 있지만, 파이썬 패키지 관리에 특화된 Pip이나 Conda를 사용하는 것이 이후 패키지를 관리할 때 편리하다. 423 | 쓸데없는 라이브러리들이 함께 설치되거나 패키지 의존 관계가 꼬이는 것을 막으려면 하나의 패키지 관리자만 이용하는 것이 좋다. 424 | Pip 425 | 파이썬의 기본 패키지 관리자이다. 426 | 기본적으로 패키지를 모두 한 곳에 설치하기 때문에 시스템에 내장된 파이썬에 영향을 주며, 프로젝트를 여러 개 관리할 경우 호환성 문제가 생긴다. 427 | 따라서 virtualenv나 venv와 같이 가상 환경을 다루는 도구와 함께 사용하는 것이 좋다. 428 | virtualenv 429 | 파이썬 가상 환경 관리자로, 패키지를 마음대로 설치할 수 있는 가상 환경을 생성한다. 430 | 각 프로젝트마다 자신이 사용할 가상 환경을 만들어주면 프로젝트마다 필요한 패키지를 따로 설정해주는 것이 가능하다. 431 | Anaconda 432 | Conda라는 패키지 관리자 + 가상 환경 관리자를 제공하며, 수학/과학/공학 업무에 필요한 NumPy, SciPy, Jupyter Notebook 등의 수백 개의 패키지와 도구를 한번에 깔아줄 뿐만 아니라 GUI도 제공한다. 433 | 그래서 통계나 데이터 사이언스, 인공지능 등의 분야 쪽 파이썬 입문자들에게 추천하는 편이다. 434 | 다만 설치에 시간이 오래 걸리고, 어차피 몇백 개나 되는 패키지를 다 쓸 일은 없기 때문에 Conda 사용에 숙련되면 아래에 나온 Miniconda를 쓰는 것도 좋다. 435 | 2020년 부터 정부 및 200인 이상 기업에게는 유료로 바뀌었다. 436 | Miniconda 437 | 위의 Anaconda와 기본 기능은 동일하지만, 패키지는 자기가 직접 찾아서 깔아야 한다. 438 | 하지만 어차피 필요한 패키지를 설치하는 것은 #conda install <패키지명> 몇번만 두드려 보면 간단히 해결된다. 439 | 이것도 아나콘다의 변형이라서 정부 및 200인 이상 기업에게는 유료. 440 | 441 | Python - 생태계 - 개발 환경 - 코드 검사 442 | 내가 작성한 파이썬 코드가 잘 쓰였는지 검사하는 도구. 파이썬은 다른 언어에 비해 문법 규칙이 일관적이지만, 한 줄의 길이나 문자열을 감싸는 따옴표(""/'') 등 개발자 입장에서 논쟁거리가 될 만한 요소는 많다. 443 | 따라서 코딩 스타일을 통일하는 도구를 사용하면 여러 사람이 협업하면서 생기는 코드의 가독성 문제를 개선할 수 있다. 444 | 또한 코딩하는 중에도 오류나 바람직하지 않은 코드를 잡아낼 수 있는 편리한 기능을 제공하는 도구를 사용하면 버그를 일찍 잡아내고 테스트에 드는 노력을 줄일 수 있다. 445 | 코드 검사 도구의 한 갈래로 자료형 검사 도구(type checker)가 있다. 446 | 동적 언어라서 변수의 자료형을 따로 체크하지 않는 파이썬을 위해, 코드를 직접 분석하여 변수를 올바른 용도로 사용하는지, 특정 함수에 올바른 값을 전달하는지와 같은 정보를 검사한다. 447 | 비슷한 동적 언어인 JavaScript에 자료형 검사를 제공하는 TypeScript와 유사하지만, 컴파일이 필요한 TypeScript와 달리 Python은 언어 차원에서 type hint를 허용하기 때문에 type hint를 추가한 코드도 그대로 실행이 가능하다. 448 | 코드 오류 검사 449 | Pylint: Python 코드를 검사하여 오류나 바람직하지 않은 문법을 잡아내는 도구이다. 450 | Flake8: Pylint에 비해 덜 꼼꼼한 대신 더 빠르다. 451 | 자료형(타입) 검사 452 | MyPy: 파이썬을 위한 자료형 검사 도구의 원조로, 순수 Python으로 작성되었다. 453 | Pyre: 페이스북에서 만든 자료형 검사 도구로, Ocaml로 작성되었다. 454 | Pyright: 마이크로소프트에서 개발한 자료형 검사 도구로, TypeScript로 작성되었다. 455 | Visual Studio Code 플러그인을 정식 지원하며, 플러그인이 아닌 명령줄 도구로 사용하려면 Node.js를 설치해야 한다. 456 | Pytype: 구글에서 만든 자료형 검사 도구이다. 457 | 코딩 스타일 검사 및 수정 458 | autopep8: 파이썬 공식 스타일 가이드인 PEP 8에 맞게 코드를 고쳐준다. 459 | yapf: 구글에서 개발한 스타일 검사 도구. 460 | Black: 다른 스타일 검사 도구에 비해 매우 엄격한 것이 특징으로, 코딩 스타일에 대해 아예 논쟁을 못하게 한 가지 스타일을 강요한다는 컨셉을 고수한다. 461 | 이 때문에 다른 검사 도구에 비해 설정할 수 있는 옵션의 갯수가 매우 적다. 462 | 내가 원하는 코드 스타일이 아니라 Black이 강요하는 스타일을 따라가야 한다는 단점이 있지만, 대신 Black으로 처리한 코드는 누가 쓰든 비슷비슷해서 금방 익숙해진다. 463 | 개발자가 신경써야 할 것을 최소화한다는 점 덕분에 후발주자임에도 빠르게 인기를 얻었다. 464 | isort: import 문을 일관성 있게 정렬해 준다. 465 | 466 | Python - 생태계 - 라이브러리 467 | 뷰티풀 수프(Beautiful Soup): XML, HTML와 같은 구문 트리 또는 구조화된 데이터 처리를 위한 라이브러리이다. 468 | dateutil: 복잡한 날짜 및 시간 형식을 다루는 라이브러리이다. 469 | 표준 라이브러리에 포함된 datetime만으로 해결하기 어려운 날짜/시간 문자열 처리나 국제 시간에 관련된 기능을 제공한다. 470 | 필로우(Pillow): PIL은 개발이 예전에 중지되었고, PIL의 포크(fork)인 Pillow가 그 역할을 대신하고 있다. 471 | Pillow를 쓰자. 472 | PIL은 Python Imaging Library의 머릿글자로 간편한 이미지 처리를 위한 라이브러리이다. 473 | PyYAML: YAML 형식의 파일을 읽고 쓰기 위해 사용하는 라이브러리이다. 474 | requests: HTTP 요청을 보낼 때 사용하는 라이브러리이다. 475 | 표준 라이브러리에 내장된 urllib 모듈에 비해 사용이 편리하고 기능이 뛰어나다. 476 | tossi: 야생의 땅: 듀랑고를 개발한 왓 스튜디오에서 개발한 한국어 조사 처리 라이브러리. 같은 인물이 만든 korean 모듈을 대체했다. 477 | argparser 터미널에서 명령어 parser 지원 예제 478 | 479 | Python - 생태계 - 라이브러리 - 수학 480 | 범용성을 지닌 수학 라이브러리들 481 | 심파이(SymPy): 인수 분해, 미분, 적분 등 심볼릭 연산 기능을 제공한다. 482 | 넘파이(NumPy): 통계, 선형 대수, 행렬 계산, 금융 운용 등을 포함한 과학 계산과 수학 작업. 수치 해석, 특히 선형 대수(linear algebra) 계산 기능을 제공하며 자료형이 고정된 다차원 배열 클래스(n-dimensional array)와 벡터화 연산(vectorized operation)을 지원한다. 483 | 참고로 Numpy는 C언어로 제작되어, 파이썬 답지 않은 넘사벽 수준의 속도를 자랑한다. 484 | 꼭 수치해석/선형대수 목적이 아니더라도 배열형태의 데이터에 대한 처리속도를 간단하게 높이는 야매 수준으로 사용할 수 있다. 485 | 싸이파이(SciPy): 고성능 선형대수, 함수 최적화, 신호 처리, 특수한 수학 함수와 통계 분포 등 과학 계산용 함수를 모아놓은 파이썬 패키지이다. 486 | 고급 수학 함수, 수치적 미적분, 미분 방정식 계산, 최적화, 신호 처리 등을 위한 다양한 과학 기술 계산 기능이 제공된다. 487 | 488 | Python - 생태계 - 라이브러리 - 데이터 489 | 빅 데이터, 통계학 라이브러리. 490 | 판다스(pandas): 데이터 처리와 분석을 위한 라이브러리이다. 491 | 테이블 형태의 데이터를 다루기 위한 데이터프레임(DataFrame) 자료형을 제공한다. 492 | R의 data.frame을 본떠서 설계한 DataFrame이라는 데이터 구조를 기반으로 만들어졌다. 493 | Visualizing Pandas'Pivoting and Reshaping Functions 참조. 494 | 다스크(Dask) : 홈페이지 판다스의 병렬&분산처리 버전. 판다스랑 사용법이 거의 같으면서도 드라마틱하게 빨라진다. 495 | 다만 아직 갈 길이 먼 것이 흠. 496 | StatsModels: 통계 및 회귀 분석, 시계열 분석을 위한 라이브러리이다. 497 | 498 | Python - 생태계 - 라이브러리 - 그래프 (차트) 그리기 499 | 수학이나 데이터의 시각화를 전문적으로 하는 라이브러리 500 | 맷플랏립(matplotlib): 과학 계산용 그래프 라이브러리. Tkinter, wxPython, Qt, GTK+ 등의 그래픽 엔진을 사용할 수 있으며 그래프와 챠트 등을 그리기 위한 시각화 기능을 제공한다. 501 | pylab이라는 서브패키지를 제공하여 MATLAB의 그래프 기능을 거의 동일하게 사용할 수 있다. 502 | 씨본(Seaborn): matplotlib에서 지원하지 않는 고급 통계 차트를 그리기 위한 통계용 시각화 기능을 제공하는 시각화 라이브러리이다. 503 | 보케(Bokeh): 주피터 노트북이나 웹상에서 자바스크립트로 그래프나 차트를 그려주는 기능을 제공해준다. 504 | Pygal: 시각화 라이브러리이다. 505 | 506 | Python - 생태계 - 라이브러리 - 머신 러닝 507 | 머신 러닝, 딥 러닝 전문 라이브러리 508 | 텐서플로우(TensorFlow): 구글에서 오픈 소스로 공개한 기계 학습, 인공 신경망 라이브러리이다. 509 | 사이킷런(scikit-learn): 파이썬의 머신 러닝 라이브러리이다. 510 | 파이토치( PyTorch): 토치 기반의 기계 학습 라이브러리. 간결하고 구현과 성능이 빠르며, TensorFlow보다 사용자가 익히기 훨씬 쉽다. 511 | 학계에서는 2017년부터 이미 파이토치가 텐서플로우보다 더 많이 언급되고 있다. 512 | 케라스(Keras): TensorFlow, Theano, CNTK 등 딥 러닝 라이브러리를 백엔드로 사용할 수 있어 쉽게 다층 퍼셉트론 신경망 모델, 컨볼루션 신경 망 모델, 순환 신경망 모델, 조합 모델 등을 구성할 수 있다. 513 | TensorFlow 등 다른 라이브러리에 비해 쉬운 문법이 특징. 현재는 TensorFlow와 통합되었다. 514 | 515 | Python - 생태계 - 라이브러리 - GUI 프로그래밍 516 | 파이썬에서 GUI 프로그래밍에 가장 많이 쓰이는 것은 파이썬에 기본으로 포함된 Tkinter이지만 그 외에도 wxPython, PyQt, PySide, PyGTK, SFML, pyglet도 쓰인다. 517 | 브라우저에서 실행되는 javascript와 python 함수 호출 간의 경계를 거의 깨주는 eel을 사용하면 웹 기술을 사용해 GUI 프로그래밍을 할 수 있다. 518 | 519 | Python - 생태계 - 라이브러리 - GUI 프로그래밍 - tkinter 520 | tkinter는 Tk interface의 약자이다. 521 | Tk는 GUI 프로그래밍을 위한 라이브러리이다. 522 | Tcl은 프로그래밍 언어로 Tk와 함께 GUI에 쓰인다. 523 | 524 | Python - 생태계 - 라이브러리 - GUI 프로그래밍 - Qt for Python 525 | PySide2 모듈을 기반으로 Qt5 애플리케이션을 파이썬으로 작성할 수 있도록 Qt(프레임워크) 측에서 공식적으로 지원하고 있다. 526 | 527 | Python - 생태계 - 프레임워크 - 웹 프레임워크 528 | Python은 웹 서버와 웹 어플리케이션(프레임워크) 간의 호환을 위해 크게 두 가지 규격을 제시하고 있다. 529 | 하나는 Java의 서블릿을 모방한 WSGI이고, 다른 하나는 비동기형(async/await) 프로그래밍을 위해 만들어진 ASGI이다. 530 | 웹 프레임워크와 웹 서버를 선택할 땐 서로 호환이 되는지 확인해야 한다. 531 | 이 외에도 자체적으로 웹 서버를 제공하거나 독자적인 규격을 사용하는 프레임워크도 있다. 532 | WSGI 기반 (동기형) 533 | Django: 풀 스택 웹 프레임워크. 정식으로 비동기 프로그래밍이 가능한 것은 아니지만 ASGI 서버와도 부분적으로 호환이 된다. 534 | Flask: 마이크로 웹 프레임워크. 가볍고 간단한 서비스를 만들기 좋으나, 복잡한 기능은 모두 플러그인을 설치해야 한다. 535 | 사용방법 536 | Bottlepy 537 | ASGI 기반 (비동기형) 538 | Starlette 539 | FastAPI: Starlette에 데이터 검사 라이브러리인 Pydantic을 얹고 이런저런 유용한 기능을 추가한 프레임워크로, API 서버를 빠르게 개발하는 데 알맞다. 540 | 541 | Python - 생태계 - 프레임워크 - 그 외 542 | Pygame - 파이썬으로 비디오 게임을 제작하기 위한 프레임워크이다. 543 | 스크래피(Scrapy): 웹 스크래핑 및 크롤링 544 | 545 | Python - 관련 팁 546 | 문자열을 합칠 때 join을 쓰자. 547 | range 함수와 str 함수를 같이 쓰면 매우 편해지는 경우가 있다. 548 | 슬라이스(slice) 문법은 리스트/문자열의 부분을 잘라내는 것 이외에도 다양한 활용이 가능하다. 549 | 숫자, 문자, 튜플은 변경 불가능(immutable)하며, 리스트, 집합, 딕셔너리는 변경 가능(mutable)하다. 550 | 이때 변경 가능한 자료형은 다른 변수에 대입하여도 그 내용이 공유된다. 551 | 그 예로, 아래와 같은 코드가 있다고 하자. 552 | 우리가 예상한 대로, 튜플 b만 변경되고, a는 변경되지 않는다. 553 | 위의 코드에서 튜플(immutable)을 리스트(mutable)로 바꾸어 보자. 554 | 출력을 보면 b만 변경했음에도 a가 변한다는 사실을 알 수 있다. 555 | 이것은 모든 변경 가능한 자료형에 적용되며, 심지어 리스트 안의 리스트 같은 것들까지도 공유가 된다. 556 | 그러니 원본을 변경하면 안 되는 경우에는 list(), set(), dict()나 copy 모듈 등을 이용해서 객체를 복제하고 작업하자. 557 | 변경 불가능한 자료형은 원본을 변경할 수 없기 때문에 해당사항이 없다. 558 | 특히 list나 dict 자체를 함수에 인자로 전달받을 때 내부에서 리스트를 변형하는 연산을 하면 함수 밖에서도 list나 dict가 변형되니 주의하도록 하자. 559 | list.insert(0) 와 list.append()는 각각 첫번째 자리에 값을 추가하거나, 마지막 자리에 값을 추가하는 정도의 조그만한 차이일 뿐이지만, 계산 시간이 O(N)과 O(1) 수준으로 차이가 나기 때문에 첫번째 방법은 쓰지 않는 것이 좋다. 560 | 그래서 prepending에 의존하는 하는 알고리즘을 파이썬 리스트로 구현하려면, 알고리즘을 거꾸로 뒤집는 것이 좋고, 만약 알고리즘을 뒤집기 힘들다면, 파이썬 공식 라이브러리에서 제공하는 deque 같은 것을 써야 한다. 561 | 자료구조 개념에 대한 감각이 있으면 이해하기 쉽다. 562 | CPython같은 경우 JIT를 쓰지 않기 때문에 이런 것을 자동으로 최적화 해 준다고 생각하지 말자. 563 | 괄호 안에 for 과 if, else 를 넣을 시 주의하자. 564 | 1은 되지만 2는 되지 않으며 3은 된다. 565 | if만 넣을 경우 for 뒤에 써야 하며, 조건을 충족하지 않는 원소들은 생략된다(즉, 1의 결과물은 [0, 2, 4, 6, 8]이다). if와 else 모두를 넣는다면 for 앞에 넣어야 하며 조건을 충족하면 맨 앞, 아니라면 else 다음이 반환된다. 566 | 마지막으로 호출된 값(대입이 이루어지지 않은 경우)은 _ 변수에 저장된다. 567 | 또한 이 변수에 대입한 값은 버려진다. 568 | 멀티프로세싱은 __main__ 블럭 안에 들어가야 한다. 569 | 네임스페이스 문제 때문. 들어가지 않으면 오류를 뿜는다. 570 | 파이썬 2와 3에서의 range는 리턴 형식이 다르다. 571 | 2에서는 리스트를 리턴하지만 3에서는 range 객체를 리턴한다. 572 | 따라서 3에서 range를 리스트로 바꾸려면 아래와 같은 방법들로 전환해야 한다. 573 | 파이썬 2에 익숙한 사람은, 파이썬 3의 range는 파이썬 2의 xrange와 동일한 역할을 한다고 생각하면 된다. 574 | 그 외에도 파이썬 2와 3은 정수 나눗셈, print 문법, 문자열 종류, import 방식 같은 데서 차이가 많이 나는 편이다. 575 | 일부는 __future__이라는 라이브러리에서 파이썬 2에서도 3과 같은 문법을 쓸 수 있도록 해 주는 기능을 제공하고 있지만, 그렇지 않은 부분들은 stack overflow등을 참고해서 직접 만들어서 쓰는 것이 좋다. 576 | 현재 많은 오픈 소스 라이브러리들이 __future__로 도배되어 있고 가내 수공업 식으로 호환성을 뗌질해 있는 것을 보면 말이다. 577 | 파이썬 2.7이 공식적으로 지원이 중단되면 시점까지 많은 라이브러리들이 파이썬 2 지원을 철회할 계획을 가지고 있으므로, 그 때가 되면 이런 호환성 문제에서 숨통이 트일 것이다. 578 | error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools" 579 | Bolierplate 코드가 적고, 리스트와 셋, 해시 등의 자료구조를 간단한 기호로 표기할 수 있어 코딩 테스트 시 많이 사용되는 언어이기도 하다. 580 | Python으로 코드를 작성하면 같은 알고리즘을 C++, Java 등으로 구현했을 때보다 전체적인 코드 길이가 비약적으로 짧아진다. 581 | 파이썬 인터프리터라도 열어서 아무 모듈이나 임포트하거나, print 함수에 대해 dir(print)를 입력해보면 파이썬의 구조를 좀 더 잘 알게 된다. 582 | 우리가 사용했던 함수가 다르게 보일 것이다. 583 | 584 | Python - 도서 585 | 파이썬은 2021년 현재까지도 이거다! 586 | 할 만한 명저가 없다. 587 | 프로그래밍 입문부터 실사용까지 오만가지 책들이 난립해 있어서 핵심을 관통하는 주제를 딱히 잡기 어려워서인 듯 하다. 588 | 파이썬 관련 책은 대형 서점에 가면 파이썬 분류가 따로 잡혀서 어마어마하게 난립해 있을 정도로 경쟁이 치열하다. 589 | 파이썬만 따로 분류가 잡혀서 매대를 꽉 채운 파이썬 책들을 보다 보면 춘추전국시대 저리가라 할 수준이다. 590 | 그러나 도서들이 죄다 특정 분야에만 치중해서 전반적인 내용을 관통한 책은 별로 없는게 문제이다. 591 | Ruby같은 경우는 기타 프로그래밍 언어에 Programming Ruby 딱 한권만 달아놔도 재고가 없을 정도로 인기인 것과 정 반대. Python은 책이 워낙 많다보니 서점에도 재고가 수두룩하다. 592 | 서울대학교의 일부 강좌에서 이번학기 학부 수업용 교재로 사용하기 시작하였다. 593 | 대한민국에서 입문 서적으로는 위키독스에 연재된 강의를 편집한 Do It! 점프 투 파이썬이라는 서적이 인기가 많다. 594 | 컴퓨터 과학 부문 베스트셀러 수준. 기초적인 내용을 다루며 대상 독자도 비전문가라 매우 깊이 있는 책이라 보기는 어렵고 어디까지나 입문 서적이다. 595 | 그리고 한국에서만 인기가 있고, 점프 투 파이썬 정도의 입문서는 너무나도 많다. 596 | 서점에 가면 매대에 깔린게 점프 투 파이썬 정도의 입문서들. 그러나 해당 책은 한국 국내에 커뮤니티가 형성(네이버 카페)되어 있어서 질문/답변이 빨라 베스트셀러에 올랐다. 597 | 또다른 입문서로는 일본에서 츠지 신고가 써서 나온 파이썬 더 쉽게, 더 깊게(원판) 파이썬 쉽게, 더 쉽게(2017년 개정판)가 있다. 598 | 2014년 판은 Python 2 기준이고 2017년 판은 Python 3 기준이다. 599 | Python 입문을 벗어나고 나면, 기계학습 분야로 갈 것이냐, 빅데이터 분야로 갈 것이냐에 따라서 추천 도서가 달라진다. 600 | 생활코딩에서도 이거 때문에 관련 문의가 페이스북 페이지에 올라오는 편이다. 601 | 빅데이터 분야(데이터 분석 분야)로 가는 데에는 책이 많은데 학원 교재로는 파이썬 데이터 분석 입문: 엑셀 및 CSV 파일 처리부터 데이터베이스, 시각화, 통계분석, 자동화까지라는 책을 많이 쓴다. 602 | 이 분야에서 가장 많이 사용하는 Pandas 에만 집중하고 싶다면 Pandas 프로젝트를 시작한 웨스 맥키니(Wes Mckinney)가 저술한 '파이썬 라이브러리를 활용한 데이터 분석'으로 시작해도 좋다. 603 | Python 기계학습 딥러닝 분야만큼은 명저가 하나 나왔다. 604 | 일본의 사이토 고키가 쓴 "밑바닥부터 시작하는 딥러닝"이라는 책이다. 605 | 원서 일본어로 나왔는데, 일본 내에서 사이토 고키가 직접 감수를 맡은 영어판이 같이 나와 이 영어판을 기반으로 미국에서 인기를 끌었다. 606 | 그리고 2016년 구글 딥마인드 챌린지 매치로 인공지능 분야가 한국 일반인에게 알려지면서 해당 도서가 2017년 한국어로 번역 출간되었다. 607 | 번역 질도 굉장히 깔끔해서 보기 좋다. 608 | 결정적으로 책이 두껍지 않고 얇다. 609 | 얇은 책인데 핵심만 집어넣어서 이론을 완성해가지고 대통일 명저로 꼽힌다. 610 | 한국 국내에서 주식 투자를 하는 사람 중에서 이른바 알고리즘 트레이딩, 쉽게말해 개인판 프로그램 매매를 짜려는 사람도 있다. 611 | 이런 사람들은 파이썬으로 배우는 알고리즘 트레이딩이라는 책이 인기가 좋다. 612 | 한국 개미투자자들이 주로 사용하는 키움증권, 미래에셋대우, 이베스트투자증권, 대신증권 API를 활용해, 간단한 프로그램을 짜서 프로그램 매매를 할 수 있기 때문이다. 613 | 원래 Python 속도가 느려서 원래 알고리즘 트레이딩(개인 프로그램 매매)는 Python보다 속도가 빠른 R이나 C언어로 하는게 원칙이다. 614 | 미국 금융업계에서는 R로 하는 프로그램 매매를 가르친다. 615 | 그런데 한국에서는 주식 투자자들 보고 Python 외에 R이나 C언어까지 배우라고 하기는 어렵다고 생각했는지, Python 알고리즘 트레이딩 책이 나왔다. 616 | 해당 책은 2017년 나온 이후 인기를 끌어서 2019년 개정판이 나올 정도가 됐다. 617 | Python으로 알고리즘 문제를 풀이하는 책도 나와 있다. 618 | 과거에는 알고리즘 대회나 코딩 테스트시 C++을 주로 사용해왔으나 직관적이고 쉬운 문법으로 인해 Python이 점점 인기를 얻고 있다. 619 | 이 책은 국내 첫 출간된 Python 알고리즘 코딩 테스트 책으로 자료구조와 알고리즘을 그림으로 도식화해 이해하기 쉽게 설명하고, 카카오 코딩 테스트 기출 문제 포함 주제별 다양한 알고리즘 코딩 테스트 문제를 다양한 각도에서 효율적인 방식으로 풀이하여 좋은 반응을 얻고 있다. 620 | 나무위키 또한 이 책에서 사용을 허락한 일러스트를 이용해 다양한 알고리즘을 효과적으로 설명하고 있다. 621 | 622 | Python - 여담 623 | 구글에서 python이라고 검색하면 제일 위에 뜨는 게 바다 괴물이나 뱀이 아니라 이거다. 624 | pyBreakout이라는 게임은 파이썬으로만 작성되었다. 625 | 오로지 pygame만 사용했으며, 개발자가 초등학생이다. 626 | Python의 공식 documentation은 정말 형편없기로 유명하다. 627 | 구체적으로는 직관성이 떨어지고 예시가 부실한 것이 그 이유인데, 꼭 필요할 때 읽으려면 헤매기 십상이다. 628 | 심지어 이는 국내도 아닌 영어가 모국어인 프로그래머들의 공론인데, Python을 찬양하는 프로그래머들도 인정하는 부분이다. 629 | 다만 최신 버전으로 갈수록 가독성이 조금씩 개선되어 가고 있다. 630 | Google Android OS에서는 공식적으로 Python을 미지원한다. 631 | 하지만 SL4A나 Linux Emulator를 설치 후 Python 실행이 가능하다. 632 | 비교내용 633 | 만약 파이썬으로 짠 코드가 잘 작동되는 것을 넘어 가독성이 높고 유지보수도 쉬운 코드라면 이를 파이썬다운(pythonic, 파이써닉) 코드라며 대우한다. 634 | 일반 프로그래머라면 이러한 파이써닉 코드를 지향해야 한다. 635 | 띵소프트에서 개발 중인 게임 페리아 연대기에서는 고대언어라고 한다. 636 | 2013년 재미있게도 한 헤드헌터로부터 경력직 파이썬 개발자 취업제안을 받았다고 한다. 637 | 즉, '''파이썬 창시자에게 파이썬 '경력직' 개발자를 구하는 수준의 메일을 보낸 것'''. 638 | C++, Java와 함께 구글의 3대 개발 언어 중 하나로 알려져 있다. 639 | 문명 4의 스크립트 언어로 쓰였다. 640 | Lua와 더불어 게임 스크립트 언어의 양대 산맥. 641 | 심즈 4 역시 Python을 기반으로 해서 동작한다. 642 | 클라이언트를 살짝 보면 수많은 .pyo 파일들의 향연을 볼 수 있다. 643 | 심즈 4의 최적화는 나름 우수한 편. 근데 pyo가 3.5 버전에서 삭제되고 pyc로 대체되었다. 644 | 킹덤 언더 파이어의 엔진에도 쓰였다. 645 | 500여 개의 자체모듈이 누더기처럼 돌아갔다고 한다. 646 | 월드 오브 탱크는 상당 부분이 파이썬으로 구현되어있다. 647 | 유저가 작성하는 모드도 로직 부분은 파이썬으로 구현된다. 648 | EVE 온라인은 Python의 경량/고속 실행 버전인 Stackless Python으로 작성되었다. 649 | 개발사 CCP Games는 파이썬 재단의 정식 후원자이기도 하다. 650 | 2000년대 초에 싱글코어 CPU가 계속 쓰일 줄 알고 서버 코드를 구버전 파이썬으로 짰다가 다중 코어 사용이 힘들어지자 눈물겨운 마개조를 거듭하여 파이썬이라는 언어가 제공할 수 있는 처리 능력을 한계치까지 뽑아서 쓰고 있다. 651 | 파이썬패드 프로그래밍 기초 강의. 카이스트 프로그래밍 기초 과목과 호환되는 공개 강의이다. 652 | 인터프리터 설치 없이 기초적인 파이썬 사용법을 배울 수 있다. 653 | 코드컴뱃 홈페이지. 654 | 파이썬을 게임의 형식을 빌려 배울 수 있는 사이트이다. 655 | NumPy+SciPy+matplotlib 조합이 과학 공학 계산용으로 자주 쓰인다. 656 | 파일:external/regmedia.co.uk/swift_benchmark.jpg 657 | 2014년 6월 WWDC에서 애플이 공개한 프로그래밍 언어 Swift보다 220배 느리다고 까였다. 658 | 유저들은 C 바인딩인 ctypes를 출동 시킨다고 부들부들... 하지만 JIT 없는 동적 인터프리터 언어와 컴파일 언어의 성능을 비교하면 어떤 언어를 비교하더라도 당연히 후자가 압도적으로 유리하다는 점에서 이건 비교 자체가 잘못된 것이다. 659 | 게다가 암호화 같은 CPU heavy한 작업은 보통 다 C로 짜서 붙인다. 660 | Python 해쉬 라이브러리인 hashlib만 해도 코어가 전부 C로 되어있다. 661 | 객체 지향 프로그래밍을 배울 때 추천할 만한 언어이다. 662 | 많은 대학들이 C++ 환경에서 OOP를 가르치지만, 이 경우 필요한 객체를 만들어서 쓰는 실습이 많은데 대부분 이미 존재하는 객체를 가져다 쓴다는 개념을 이해하지 못하는 경우가 많다. 663 | STL을 쓰면 달라지지만 실습에서 STL을 요구하는 문제가 나오는 경우도 드물고, 주로 사용되는 문자열 변환, 배열 관련 연산 등은 파이썬에서 따로 임포트할 필요 없이 자료형 자체가 이미 클래스로서 편리하게 클래스 함수를 던져주기 때문에, 클래스의 재활용이라는 측면을 훨씬 이해하기 쉽다. 664 | 무엇보다 하루면 다 배울 수 있는 언어이기도 하고. 다만 대학들도 아무런 이유 없이 C++을 객체 지향 입문용으로 채택한 건 아니다. 665 | 많은 학생들이 프로그래밍 언어 중 C를 가장 먼저 배우기에, C++은 그나마 익숙한 개념들을 이용해서 객체 지향을 학습할 수 있게 한다. 666 | 물론 C++ 프로그래밍은 C 프로그래밍과는 패러다임 자체가 다르므로 주의가 필요하지만, 적어도 "C언어의 구조체 안에 함수를 정의할 수 있게 하면 C++이다"는 식의 낚시로 학생들에게 심리적 편안함을 줄 수는 있다. 667 | 최근에는 객체 지향 입문용 언어로 C++보다 파이썬을 먼저 가르치는 대학도 늘어나고 있는 추세라, 파이썬부터 먼저 공부하는 것도 나쁘지 않다. 668 | Fluent Python(번역서: 전문가를 위한 파이썬)이라는 책이 있다. 669 | 알고리즘 및 자료구조를 파이썬으로 공부하기 670 | 2014년 8월 30일, 유서깊은 파이썬행사인 PyCon이 드디어 한국에서도 성공리에 개최되었다. 671 | #공식홈페이지 672 | 2017년에는 PyCon.KR 2017(파이콘 한국 2017)이 강남 코엑스에서 열렸다(8.12~15). 673 | 2018년에는 PyCon.KR에 참가한 IntelliJ IDEA로 유명한 JetBrains의 PyCharm 프로젝트 매니저인 Dmitry Trofimov가 행사를 보고 PyCharm 한글화 오픈소스 프로젝트를 열었다. 674 | 그러나 번역이 20% 정도 되고 수 년째 멈춰 있는 상태...관심있는 사람들은 기여해 보자. 675 | 다만 개발자들은 호환성을 위해서 영어 버전을 사용하는 경우가 대부분이라 기여를 할 사람이 있을지는 의문이다. 676 | 2015년 7월 9일 "같이 번역해서 같이 봅시다"라는 표어를 내걸고 파이썬 문서를 한글로 번역하는 프로젝트가 생겼다. 677 | flowdas / 파이썬 한국어 번역 678 | 도널드 글로버가 자신의 노래 가사에 Python을 배우라는 가사를 넣기도 했다. 679 | 타오바오에서 다운로드 미러를 제공하고 있다. 680 | 귀도 반 로섬은 2019년 10월 30일부로 드랍박스에서 나오고 은퇴하였다. 681 | 그리고 2020년 11월 13일, 은퇴 생활이 지루하다며 다시 마이크로소프트 의 개발팀에 합류했다. 682 | 디시인사이드 마이너 갤러리 중 파이썬 마이너 갤러리가 있었으나 접근 제한 조치되어 아카라이브 파이썬 채널로 이주하였다. 683 | 3.5부터는 XP를 지원하지 않는다. 684 | 투어라이브 의 백엔드 기술의 대부분은 파이썬으로 구현되어있다. 685 | 2020년 5월, 3.9부터는 비스타와 7을 지원하지 않는다. 686 | -------------------------------------------------------------------------------- /test_data/test4.json: -------------------------------------------------------------------------------- 1 | { 2 | "namespace": 0, 3 | "title": "Python", 4 | "text": "[include(틀:다른 뜻1, other1=다른 의미의 Python, rd1=파이선)]\n[include(틀:프로그래밍 언어)]\n||
<-5>
'''{{{#white TIOBE 선정 올해의 프로그래밍 언어}}}''' ||\n|| 2006년[br][[Ruby]] || → || 2007년[br][[Python]] || → || 2008년[br][[C언어|C]] ||\n|| 2009년[br][[Go(프로그래밍 언어)|Go]] || → || 2010년[br][[Python]] || → || 2011년[br][[Objective-C]] ||\n|| 2017년[br][[C언어|C]] || → || 2018년[br][[Python]] || → || 2019년[br][[C언어|C]] ||\n|| 2019년[br][[C언어|C]] || → || 2020년[br][[Python]] || → || ''없음'' ||\n\n||<-2> {{{#!wiki style=\"margin: -5px -10px; padding: 5px 10px; background-image: linear-gradient(to right, #3775a9 30%, #ffdc4d 90%)\"\n'''{{{+1 {{{#000,#fff 파이썬}}}}}}'''[br]{{{#000,#fff Python}}}}}} ||\n||<-2> [[파일:python-logo-master-v3-TM.png|width=100%]] ||\n|| 개발 ||파이썬 소프트웨어 재단 (PSF) ||\n|| 버전 ||{{{+1 3.9.2}}}\n2021년 2월 19일 업데이트 ||\n|| 웹사이트 ||[[https://www.python.org/|[[파일:홈페이지 아이콘.png|width=25]]]] ||\n\n\n[목차]\n[clearfix]\n== 개요 ==\n{{{#!syntax python\n# 1\nprint(\"Hello, world!\")\n# 2\nimport __hello__\n# 둘중 하나를 선택해서 사용\n}}}\n위의 문법은 파이썬 3 기준이다. 파이썬 2에서는 print \"Hello, world!\"만 해도 충분하다.\n\n>'''\"Life is short ([[프로그래머|You]] need Python)\"'''[* Python의 엄청나게 빠른 개발 속도와 생산성을 두고 개발자들 사이에서 유행처럼 퍼진 말이다.]\n>'''인생은 짧으니, 당신은 파이썬이 필요하다.'''\n>----\n>- Bruce Eckel\n1991년에 발표된, [[MATLAB]]과 유사한 [[인터프리터]] 방식의 [[프로그래밍 언어]]. [[https://www.python.org/|공식 홈페이지]] [[https://github.com/python/cpython|공식 깃헙 저장소]]\n\n최신 버전은 2020년 12월 07일에 나온 3.9.1 버전이며 0.1버전마다 for문 등의 루프에서 연산 효율이 약 2배 빨라지는 개선이 존재하므로, 최신 버전이 3개월 이상 지나 안정화가 된 후에는 귀찮더라도 버전을 반드시 업데이트 하기를 추천한다.\n\n온라인 상으로 코드를 실행시켜 보고 싶다면 [[https://repl.it/languages/python3?v2=1|여기]]로.[* 여기에서 쓰는 버전은 3.8.2이다]\n\n창시자는 귀도 반 로섬(Guido van Rossum). 1989년 크리스마스 주에, 연구실이 닫혀있어서 '''[[국부론|심심한 김에 만든 프로그래밍 언어이다]].''' 농담이 아니고 반 로섬을 [[유럽]]에서는 [[애덤 스미스]]에 비교할 정도다. 프로그래밍 계의 경제학자라나... 심심해서 만들었다는 것은 [[https://www.python.org/doc/essays/foreword/|파이썬 서문]]과 [[https://www.imaso.co.kr/news/article_view.php?article_idx=20150921073159|마이크로소프트웨어와 한 인터뷰]]를 보면 알겠지만 사실이다. 기술자들은 대부분 [[리눅스|심심할 때]], 혹은 [[드롭박스|실수로]] 걸작을 만든다. 2000년에는 Python 2, 2008년에는 Python 3가 나왔다.\n\n이름은 귀도가 즐겨 보던 영국의 6인조 코미디 그룹 [[몬티 파이선]]에서 따왔다고 한다. 지금 CPython의 공식 [[GitHub]] 저장소를 보면 협업보조용 봇 이름들이 [[https://github.com/the-knights-who-say-ni|the-knights-who-say-ni]]([[니라고 말하는 기사]])나 [[https://github.com/bedevere-bot|bedevere]]([[베디비어]]) 같이 죄다 [[몬티 파이선과 성배]]의 배역들이다. 많은 파이썬 교재들에서 변수 이름을 [[스팸(몬티 파이선 스케치)|spam]], eggs로 짓는 등 드립을 친다. 직접적 관계는 없지만 [[42]]도 필수요소. 또한 시작 프로그램 중 하나의 이름이 아이들(Idle)인데, 탄생배경을 생각해 본다면 몬티 파이선의 멤버 에릭 아이들(Eric Idle)의 이름에서 유래하였을 가능성이 높다. 물론 사전적 의미를 생각 안 하는 건 아니라서 심볼마크가 [[뱀]] 모양이다.\n\n문법이 매우 쉬워서 초보자들이 처음 프로그래밍을 배울 때 추천되는 언어이다. 오죽하면 Python의 별명이 ''''실행할 수 있는 [[의사 코드]](Executable pseudocode)''''일 정도. 실제로도 미국 공과 대학교에서 컴퓨터 프로그래밍 입문 수업으로 Python을 많이 사용하기도 한다. 학습용으로 좋은 언어인 동시에 '''실사용률과 생산성'''도 높은 강력한 언어인 셈. 즉 '''접근성과 응용력이 좋다'''는 게 굉장히 중요하다. --배우기도 쉽고 써먹기도 쉽고-- Python의 이런 두 마리 토끼는 교육용 프로그래밍 언어인 [[BASIC]]이 [[망했어요]] 루트를 타게 된 결정적인 이유이다. Python은 BASIC과 달리 학교에서 배우고 끝나는 게 아니라 현업에서도 자주 쓰이는 언어이기 때문이다. 농담이 아니고 파이썬이 교육용 언어로 자리잡으면서 베이직은 [[마이크로소프트]]에 의해 산소호흡기를 달고 연명만 하는 신세가 됐다. MS가 없으면 [[안습|BASIC은...]]\n\n2010년 후반대에 이르러서는 풍부한 머신러닝 라이브러리와 프레임웍으로 머신러닝, 딥러닝등 인공지능 개발을 위한 언어로서 각광을 받고 있다. 사이킷-런(Scikit-learn), 텐서플로우(TensorFlow), CNTK, 아파치 스파크 MLlib(Apache Spark MLlib), 파이토치(PyTorch)등 성능도 뛰어나며 많이 사용되는 머신러닝, 딥러닝 프레임웍들이 파이썬으로 접근이 가능하다.\n\n파이선은 많은 블록코딩에 사용된다.\n\n원문보기: [[http://www.ciokorea.com/news/38148#csidxf24bb678303a92fa914daf16bfe161f|#]]\n== 특징 ==\n=== 디자인 철학 ===\n[[Perl]]의 '하나 이상의 해결법이 존재한다' 에 대비되는 '가장 아름다운 하나의 답이 존재한다' 를 기본으로 하고 있다. 이것은 남이 작성한 코드를 내가 읽고 이해해야 하는 경우 아주 절실히 느낄 수 있다. 이 점은 Tim Peters가 작성한 파이썬 기본 철학(The Zen of Python)에서 더 자세히 나열되어 있는데, 20가지 항목이라고 표현하고 있지만 실은 19가지 항목만 있는 등 '규칙'보다는 농담도 섞인 '조언'에 가까운 문항들이다. [[https://www.python.org/dev/peps/pep-0020/|#]] 콘솔에서 \"import this\"를 입력하면 [[이스터 에그]]로써 파이썬을 통해 볼 수 있다. dir(this)를 하면 ROT13으로 인코딩된 this.s를 확인할 수 있다. this.d로 dictionary( {} )를 사용해 해독하면 원문이 나온다.\n\n{{{#!folding 【PEP 20 -- The Zen of Python 펼치기 · 접기】\n * 아름다운 것이 추한 것보다 낫다. (Beautiful is better than ugly.)\n * 명시적인 것이 암시적인 것보다 낫다. (Explicit is better than implicit.)\n * 간결한 것이 복합적인 것보다 낫다. (Simple is better than complex.)\n * 복합적인 것이 복잡한 것보다 낫다. (Complex is better than complicated.)\n * 수평적인 것이 내포된 것보다 낫다. (Flat is better than nested.)\n * 여유로운 것이 밀집한 것보다 낫다. (Sparse is better than dense.)\n * 가독성은 중요하다. (Readability counts.)\n * 특별한 경우들은 규칙을 어길정도로 특별하지 않다. (Special cases aren't special enough to break the rules.)\n * 허나 실용성은 순수성을 이긴다. (Although practicality beats purity.)\n * 오류는 절대로 조용히 지나가지 않는다. (Errors should never pass silently.)\n * 명시적으로 오류를 감추려는 의도가 아니라면. (Unless explicitly silenced.)\n * 모호함을 대할때, 이를 추측하려는 유혹을 거부하라. (In the face of ambiguity, refuse the temptation to guess.)\n * 명확한-\\- 그리고 가급적이면 유일한 -\\- 하나의 방법은 항상 존재한다. (There should be one-\\- and preferably only one -\\-obvious way to do it.)\n * 비록 그 방법이 처음에는 명확해 보이지 않을지라도[* 원문에는 \"네덜란드인이 아닌 이상\" 이라는 농담조의 조건이 붙는데, 아마도 파이썬의 창시자인 귀도 반 로섬을 두고 하는 얘기로 보인다.]. (Although that way may not be obvious at first unless you're Dutch.)\n * 지금 행동에 옮기는 것이 아예 안하는 것보다는 낫다. (Now is better than never.)\n * 비록 아예 안하는 것이 지금 *당장* 하는 것보다 나을때도 많지만. (Although never is often better than *right* now.)\n * 구현 결과를 설명하기 쉽지 않다면, 그것은 나쁜 아이디어이다. (If the implementation is hard to explain, it's a bad idea.)\n * 구현 결과를 설명하기 쉽다면, 그것은 좋은 아이디어일지도 모른다. (If the implementation is easy to explain, it may be a good idea.)\n * 네임스페이스를 사용하는 것은 완전 좋은 생각이다! (Namespaces are one honking great idea -- let's do more of those!)}}}\n파이썬의 이런 철학은 이후 다른 프로그래밍 언어들에도 수출되어, [[2010년대]] 들어서는 기존 언어들도 '''파이썬처럼 최대한 문법 구조를 단순화시키고 통일하려는 문법 대통일 운동'''이 일어나기 시작했다. 이는 [[프로그래머]]들이 프로그램을 돌려보기 좋게 한다는 '''매우 좋은 영향'''이 있으니까...\n\n따라서 다른 언어들의 코딩 스타일은 각자의 취향에 맞게 [[발산 진화]]하는 반면, 파이썬은 위의 철학들을 만족 시키는 하나의 스타일로 [[수렴 진화]]하는 성향이 있다. 실제로 C 계열의 언어에서 중괄호의 위치에 대한 논쟁은 거의 종교적 논쟁에 가깝다. 현재 한국에서 가장 많이 쓰이는 방식은 C언어의 창시자 Kernighan과 Ritchie의 K&R 스타일이다. 그러나 Eric Allman의 방식을 고수하는 사람들도 제법 많다. 이외에도 중괄호 위치를 정하는 다른 방법들이 있으며 자세한 내용은 [[http://gyumee.egloos.com/1306012]]에서 확인 가능하다. --그리고 흔치는 않지만 몇몇 사람들은 그냥 들여쓰기고 뭐고 다 무시하고 쭉 작성해놓기도 한다.-- 이런 성향은 다른 언어에는 없는 파이썬스러움('''pythonic''')이라는 독특한 개념을 낳게 되었는데, 복잡하지 않으면서 의미가 명확하고, 코드의 축약보다 뚜렷하게 보이는 흐름을 중시하는 파이썬의 철학을 지칭하는 개념이다.\n\n이런 철학 때문에 문법이 굉장히 엄격한 편이다. 예를 들자면, 다른 언어에서는 해도 되고 안 해도 되는 들여쓰기가 이 언어에서는 의무로, 들여쓰기 자체로 하나의 코드 블럭이 된다. 코드 블럭을 명시적으로 표시하지 않아도 돼서 비주얼 적으로는 굉장히 깔끔한 반면 자유도를 제약한다는 평도 있다. --근데 어차피 들여쓰기는 하게 된다.--\n\n코드에서 중괄호는 모아놓고 보면 굉장히 지저분할 뿐더러, 당장 입력해야 하는 괄호가 2개나 되고,[* 대부분 IDE는 여는 괄호 1개를 입력하면, 자동으로 닫는 괄호를 입력해준다.] 괄호 하나라도 잘못 넣으면 블럭이 다 꼬여버리는 귀찮은 존재이지만(begin과 end 혹은 end.으로 구분해야 하는 파스칼에서 보면 중괄호만 해도 엄청나게 간결해 보이지만), 대신 블럭들을 이리저리 만질때는 매우 편리한 존재이다. 특히 C 코드를 종이에 출력해보면 중괄호 있고 없고의 가독성 차이가 의외로 크다. 파이썬에서는 이 중괄호를 들여쓰기로 대체하는데, 이게 블럭의 시작과 끝 지점을 찾는 부분에서 꽤 불편하다. 대신 괄호를 2개나 일일이 다 넣고, 잘못 넣지 않게 점검도 해 줘야하는 수고가 없다는 엄청난 장점이 있다.\n{{{#!syntax python\ndef factorial(x):\n if x == 0:\n return 1\n else:\n return x * factorial(x - 1)\n}}}이 들여쓰기 의무 규칙 때문에 소스 코드 들여쓰기에 탭([[Tab]]) 문자를 사용하지 '''않을 것을 매우 강력히 요구한다.'''[* Python의 형제 언어라 불리는 [[Ruby]]는 블록의 끝을 end 키워드로 구분하기 때문에 이런 문제에서는 자유로운 편이다.](들여쓰기에 최적화된 python을 쓰기싫으면 세미콜론과 중괄호, int/char 등을 수시로 많이 사용하게 될 것이다.) [[탭]] 문자는 사용자나 시스템의 설정에 따라 서로 다른 폭의 공백이 생긴다. 문제는 파이썬 인터프리터가 탭 문자 하나를 공백 1문자로 처리한다는 것이다. 탭 문자로 들여쓰기를 처리하면 자신과 다른 탭 설정을 가진 에디터에서 코드를 열어 볼 경우 코드 들여쓰기가 높은 확률로 망가져 버리고, 그걸 교정해보겠다고 들여쓰기에 공백 문자를 혼용하는 순간 해당 소스 코드는 사람이 고칠 수 없는 형태로(시각적으로는 블록이 맞지만 파이썬 인터프리터는 다른 블록으로 인식) 망가져 버린다. PEP-8에 명시된 공식 코딩 가이드에서는 [[스페이스 바]]로 '''공백 4문자'''를 넣기를 권장하고 있다. 물론 이렇게 스페이스 바를 네 번이나 치는 귀찮은 행위를 프로그래머들이 가만 놔둘 리가 없다. PyCharm, VSCode 등 Python 개발자들이 애용하는 최신 에디터는 Tab을 누르면 공백 4개로 자동 변환하여 입력되는 기능이 지원되므로 이들 에디터를 이용하면 공백 4개를 번거롭게 칠 필요가 없어진다.\n\n웃긴건 Python 2는 [[Tab]] 키를 권장한다. 탭 키를 사용하지 말 것을 요구하는 건 Python 3에서 해당하는 이야기. 물론 Python 2에서도 \"Tab 키를 쓸 경우에는 잊어버리지 말 것\"을 이야기하긴 하나, 그렇다면 처음부터 Tab 키를 막았어야 말이 된다. --첨에는 탭이 그렇게 똥인줄 몰랐어....-- [[PyCharm]] 등의 주요 에디터에는 탭 키를 썼는지 스페이스 바를 썼는지 시각적으로 구분하여 보여주는 기능이 있으므로 참고하자.\n\n참고로 위의 예시인 팩토리얼 함수는 (람다식과 ternary operator를 이용해) 다음과 같이 간결히 나타낼 수 있다. --사실 이 코드는 PEP-8 위반이다. --\n{{{#!syntax python\nfactorial = lambda x: 1 if x == 0 else x * factorial(x - 1)\n}}}C와 Java에서 쓰이는 ternary operator {{{?:}}}에 비해 훨씬 직관적으로 읽혀, '실행할 수 있는 의사코드'라는 별명을 여기서도 느낄 수 있다. 물론 쳐야 할 문자 숫자가 몇 배로 늘어나기 때문에 싫어하는 사람은 엄청나게 극혐한다.\n=== 순수 객체지향 ===\n파이썬에는 원시 타입(Primitive Type)이 존재하지 않으며, 모든 것이 객체로 취급된다. 나아가 클래스, 함수 역시 객체로 취급할 수 있다. 상수 역시 상수가 저장된 객체라고 본다. 다음과 같은 상수 할당문이 있을 때,\n{{{#!syntax python\nx = 10\n}}}\n이는 변수 x 자체에 10이 할당된 것이 아니라 x가 10이 저장된 상수 객체를 가리키는 것을 의미한다. 내부적으로는 C의 포인터 연산과 같은 동작이 행해지는 것이다. 이렇게 x에 대입되는 값을 변경할 경우,\n{{{#!syntax python\nx = 10\nx = 20\n}}}\nx가 가리키는 대상이 10이 저장된 상수 객체에서 20이 저장된 상수 객체로 바뀐 것이다. x 자체의 값이 10에서 20으로 바뀐 게 아니다.\n\n||<#fff>[[파일:2-4-4.png|width=400]]||\n|| [[https://www.onlybook.co.kr/entry/algorithm-interview|<파이썬 알고리즘 인터뷰>]] p.107, 책만, 2020 ||\n\n파이썬 버전 3의 표준 타입 계층 구조에서 주요 자료형은 그림과 같다. 이 중에서도 크게 불변 객체(Immutable Object)와 가변 객체(Mutable Object)로 나눌 수 있다. 불변 객체에는 상수(숫자), 문자열, 바이트, 그리고 튜플[* 튜플을 변경 불가능하게 막는 이유는 보안 때문이다.]이 있다. 이 네 가지를 제외한 나머지 객체는 모두 가변 객체이며, 값을 수정할 수 있다. 불변 객체의 값을 수정할 때는 바뀐 값이 저장된 새로운 객체를 생성하고 참조 대상을 새 객체를 옮기는 식으로 동작한다. 이와 같은 특징 때문에 파이썬은 순수 객체지향 언어라고 할 수 있고, 이와 같은 순수 객체지향 언어의 또다른 예로는 [[Ruby]]가 있다.\n\n함수의 매개변수로 불변 객체를 넘겼냐 가변 객체를 넘겼냐에 따라서 함수 바깥에 있는 인자의 값도 수정할 수 있는지 없는지가 달라진다. 불변객체를 넘겼으면 값의 복사만 일어나고 함수 바깥에는 영향을 주지 못하므로[* global이나 nonlocal 키워드를 사용하지 않았을 경우] '값에 의한 호출(Call by Value)'이 될 것이며, 가변 객체를 넘겼으면 함수 바깥에까지 영향을 줄 수 있으므로 '[[참조에 의한 호출]](Call by Reference)'이 될 것이다. 파이썬 공식 문서에서는 파이썬의 인자 전달 방식을 '할당에 의한 호출(Call by Assignment)', 또는 '객체 참조에 의한 호출(Call by Object Reference)'이라고 명시하고 있다.\n\n=== 반복 가능한 객체 ===\n파이썬의 가장 큰 특징 중 하나. 파이썬은 반복 가능한 객체(iterable)라는 강력한 기능을 제공한다. 이 객체는 집합, 문자열, 리스트, 튜플, 딕셔너리, 그리고 함수[* return 대신 yield를 써서 생성기(generator)를 반환한 경우.]까지도 반복이 가능하며, 이것을 for 구문에서 사용할 수 있게 해준다. 리스트와 튜플 등은 좀 편해지는 정도라 할 수 있지만, 함수의 값을 반복할 수 있다는 것은 큰 장점이다. 그 예로 n의 배수를 구하는 f(n) 함수가 있을 때,\n\n{{{#!syntax python\ndef f(n):\n x = 1\n while 1:\n yield n*x\n x += 1\n\not = f(2)\nprint ot\nprint next(ot)\nprint next(ot)\n}}}\n와 같은 함수를 만드는 것도 가능하다. 함수를 호출하고 나서도 함수가 완전히 끝나기 전까지는 지역 변수가 남아있으며, 함수가 끝나야 지역변수가 삭제된다. 따라서 함수를 호출할 때마다 x의 값이 증가한다. 이렇게 만들어진 반복 가능한 객체는 \\_\\_next\\_\\_ 함수나 next(객체) 함수, 또는 for ... in 객체 와 같은 문법들을 이용하여 순서대로 값을 호출할 수 있다. 특히 제너레이터의 경우, 미리 만들어놓는게 아니라, 호출 될 때 반환값을 새로 만들어 반환하는 방식이기 때문에 메모리 관리 면에서도 이점이 있다.\n\n== 장점 ==\n=== 높은 생산성 ===\n||<#fff>[[파일:xkcdpython.png]]||\n|| [[xkcd]] [[http://xkcd.com/353/|353화 'Python']] ||\n\n파이썬의 [[아이덴티티]]. '''그 무엇과도 바꿀 수 없는 파이썬만의 특징'''이다. 전 세계의 모든 [[프로그래밍 언어]] 중에서 파이썬 정도의 낮은 난이도를 가지면서, __범용성을 갖추고, 파이썬 수준의 프로그램 개발 속도를 따라잡는 언어가 없다__. 파이썬으로 만든 프로그램을 같은 객체지향 프로그래밍 언어인 [[Java]]나 [[C++]]로 만든다고 하는 순간 숨이 턱 막힐 정도. 이런 언어를 사용하려면 '''설계부터 난감해진다.'''\n\n[[인터프리터]] 언어이면서 우수한 자료형과 다양한 모듈 등을 제공해 개발기간이 단축되는 것이 특징. '[[C언어]]로 2년동안 완성하지 못한 프로젝트를 파이썬으로 한달만에 해냈다'는 극적인 경험담이 있을 정도다. 당장 파이썬의 집합 자료형 같은 경우 C언어로 구현하려고 하면 머리가 아파온다. C언어와의 접착성도 좋기 때문에, 일단 Python으로 빨리 구현하고, 남은 시간에 속도에 병목이 되는 부분을 C++로 전환하는 전략을 내세우고 있다. 버전이 올라가면서 Python 자체도 그리 느리지 않게 되었다. 심지어 [[어셈블리어]] 같은 저수준 언어(Low level)도 Python에서 호출 할수있다. Python은 어지간한 다른 프로그래밍 언어들을 지원하는 호환성, 응용할 곳이 무궁무진하다.-- 실행 속도만 빼고--\n\n참고로 저~~ geek 감성의 재미없는~~ [[xkcd|만화]]는 파이썬 내에 [[이스터 에그]]로 삽입되기도 했다. import antigravity로 antigravity 모듈을 불러오면 나온다.[[http://www.youtube.com/watch?v=_V0V6Rk6Fp4|영상]]\n=== 문법 통일에 따른 빠른 피드백 ===\n디자인 철학 자체가 '''가장 완벽한 하나의 아름다운 해답'''을 찾는 파이썬 특유의 철학을 찾다 보니, [[문법]] 자체가 딱 떨어지게 표현된다. 이 때문에 다른 사람이 제안하고 만든 프로그램을 수많은 사람들이 보고 쉽게 접근할 수 있다. [[Perl]] 같은 경우는 '''Write Once, Read Never'''라고 불릴 정도로 [[피드백]]과는 담을 쌓았는데, 파이썬은 문법이 통일되어 있다 보니 '''Write Once, Read Infinity'''가 되어버렸다. 그래서 프로그램 하나 만들면 다른 프로그래머들에 의해 엄청난 양의 피드백이 들어오게 되었고, 이는 곧 생산성 향상으로도 이어졌다. 괜히 파이썬이 [[https://www.tiobe.com/tiobe-index/python/|시간이 갈수록 점유율이 상승하는 언어]]가 아닌 것이다.\n\n=== 과학/공학 친화 ===\nPython은 과학과 공학 분야에서 필요한 여러 기능을 기본적으로 제공한다. 우선 언어 자체적으로 64비트를 넘어가는 매우 큰 정수를 지원한다.[* 다른 언어의 경우 64비트를 넘어가는 매우 큰 수를 사용하려면 [[Java]]의 BigInteger, [[JavaScript]]의 BigInt와 같이 별개의 클래스를 사용해야 한다.][* 큰 수 계산하기 위한 내장 함수들을 Python 2부터 저장해두었기 때문에 가능하다. 유감스럽게도 큰 수 활용 부분은 Python 2와 3가 호환이 안 되는 지점 중 하나다. 내장함수 몇몇이 2와 3에서 기능이 다르다.] 또한 [[허수]]를 기본적으로 지원하며, 표준 라이브러리의 [[https://docs.python.org/3/library/decimal.html|decimal]], [[https://docs.python.org/3/library/fractions.html|fractions]] 모듈을 사용해 소숫점과 유리수를 정밀하게 다룰 수 있다. 따라서 이러한 기능을 다루는 암호학과 통계 분야에서 쓰기에 알맞다.\n\nPython 생태계 또한 공학 및 과학 분야를 빵빵하게 지원한다. 복잡한 수치와 큰 데이터를 다루는 연산에 알맞은 NumPy, SciPy, pandas, 데이터를 그래프로 시각화하는 Matplotlib, 코드와 데이터를 함께 다룰 수 있는 Jupyter Notebook 등의 강력한 패키지와 도구를 사용할 수 있다.\n\nPython 개발자들도 이러한 사실을 잘 알고 있기 때문에 언어 차원에서 관련 패키지를 위한 기능을 제공한다. 가령 [[https://docs.python.org/3/library/constants.html#Ellipsis|Ellipsis]] ({{{...}}}) 상수는 사실상 NumPy 전용의 슬라이스 객체로 제공한다.[* Python 3.5에서 추가된 [[https://docs.python.org/3/library/typing.html|typing]] 모듈에서도 길이가 가변적인 tuple을 나타내기 위해 사용한다.] 또한 3.5부터는 [[행렬곱]]을 위한 {{{@}}} 연산자가 [[https://docs.python.org/3/whatsnew/3.5.html#whatsnew-pep-465|추가되었다]].\n\n=== 만능 언어 ===\nPyPI[[https://pypi.python.org/pypi|#]]라는 [[패키지 저장소]]가 2012년 구축되었다. 2018년 10월 기준 155,800 여개의 패키지를 제공한다. 여기에 등록된 패키지들은 pip[[https://en.wikipedia.org/wiki/Pip_(package_manager)|#]]를 통해 간단하게 내려받을 수 있다. 다만, PyPI가 최초, 최대의 패키지 저장소는 아니다.\n\nPython으로 직접 만들었거나 또는 다른 프로그램의 Wrapper가 꼭 존재한다. 사실상 못하는 것이 없다. 웹 사이트 서버를 구현하려고 하면 Python Web Framework를 쳐보자([[Django]], [[Flask]], [[Bottle]] 등). [[기계학습]] 알고리즘을 쓰고 싶다면 python machine learning이라 검색하자([[scikit-learn]]). 얼굴인식을 코드 몇 줄로 할 수도 있다([[OpenCV]]). 기본적으로 설치되는 모듈인 tkinter 모듈을 이용하면 간단한 GUI 프로그래밍을 할 수 있다. 게임도 만들 수 있다([[Pygame]]). 비주얼 노벨도 만들 수 있다([[Ren'Py]]).\n\nPython 가지고 [[스프레드시트]]나 [[데이터베이스]]까지 만드는 괴수들도 있다. Python으로 [[SQL]]을 구현하는 건 불가능하다는 소리가 있었지만 우리의 [[Nerd]]들은 해내고 말았다. [[2013년]] Python으로 관리하는 DB 개념이 잡힌 이후 수많은 [[피드백]] 끝에 [[2015년]] 도전 성공. 심지어 [[2017년]] [[프랑스]]의 중견기업에서 Python DB 프로젝트를 보더니 정말로 회사의 DB를 파이썬으로 관리하는 사업을 벌려서 DB화되지 못하고 저장되던 회사 내부의 파일형 자료들과 기존의 DB에 저장된 자료를 접합시키는 사업까지 했다 한다.\n\n물론 그렇다고 Python만 쓰는 것이 답은 아니다. 실행 속도(정확히는 CPython의 실행 속도)가 상대적으로 느린 편이라, 빠른 속도가 필요한 프로그램 작성에는 한계가 있다. 일반적으로 기계어로 컴파일하여 사용하는 [[C(프로그래밍 언어)|C]], [[C++]]보다는 당연히 느리고, [[Lua]], [[JavaScript]], [[LISP]] 계열 언어 등 동적 언어들을 전체를 주욱 놓고 비교해 봐도 속도가 빠른 편은 아니다. Python처럼 가상 머신 위에서 실행되는 [[Java]], [[JavaScript]] 등의 언어들의 경우, 속도 문제를 극복하기 위해서 [[JIT]] 컴파일러를 도입했다. Python의 사실상의 표준 구현체인 CPython은 JIT 컴파일을 도입하지 않았고, JIT 컴파일을 도입한 별도의 구현체인 PyPy가 등장했다. 통계 분야 등 특정 분야에서는 [[R(프로그래밍 언어)|R]]과 같이 그 분야에 특화된 언어를 사용하는 것이 더 편리할 수도 있다.\n\n그리고 동적 타입 언어(dynamically typed language)라는 점이 큰 프로젝트에서는 단점으로 작용하여 자료구조 설계나 디버깅이 어렵다는 지적도 있다. 다만 \"정적 타입 vs. 동적 타입\" 논쟁은 서로의 장단점이 있으며 일종의 종교 논쟁으로 취급 받는다. 일례로 OCaml 같은 강력한 타입 인터페이스(Hindley-Milner, System F 등)를 가진 경우, 모든 타입 에러(!)를 컴파일 타임에 잡아낼 수 있는 반면에, 모든 버그가 타입 에러는 아니기 때문에 여전히 테스트 및 디버깅 과정은 필요하며, 타입 시스템으로 인한 부담 때문에 빠른 구현에는 부담이 될 수 있다. 반면에 동적 언어는 빠른 구현의 이점이 있지만 타입 에러가 많이 나는 특징이 있다. 한 마디로, 컴파일 언어의 경우에는 컴파일 시간에 잡아낼 수 있는 오류를 범하게 된다는 소리. Python으로 parser를 많이 작성해봤다면, 십중팔구 읽은 숫자를 string으로 저장했다가 나중에 연산을 했더니 연산이 불가능하다면서 에러가 나거나 이상한 결과가 나온 경험이 있을 것이다.\n\n그러나 이는 커버리지가 높은 테스트 세트로 어느 정도 커버할 수 있으며 최근의 추세와 부합하는 방식이기도 하다. 또한 Python 3.5부터는 Type Hints를 이용해서 변수가 가질 수 있는 타입을 지정할 수 있게 되었다. 성능 향상에 도움은 안되지만 가능한 오류를 쉽게 찾아낼 수 있으며 [[PyCharm]]과 같은 IDE 프로그램을 이용하면 도움을 받을 수 있다.\n\n빠른 아이디어 구현이 생명인 연구소에서 각광을 받고 있고, 한국 밖에서는 당당한 주류 언어로 대우받고 있다. [[인스타그램]], [[유튜브]], [[reddit]] 등이 Python을 주로 쓰고 있다고 알려져 있으며, 외국의 구인 사이트에도 Python을 할 줄 아는 사람에 대한 수요가 많다. 컴퓨터 관련이 아닌 이공계 전반에서 많이 쓰이는 [[MATLAB]]은 오픈소스가 아니라는 점이 최근 추세와 맞지 않아 입지가 좁아지고 있다.[* MATLAB의 GUI 기반 모델링 툴박스인 Simulink는 기업용으로 구매하면 기본 toolbox가 1 copy에 천만 원 단위, 각종 전기, 전자, 기계, 유압, 항공 등에 관련한 라이브러리는 추가로 유료로 판매한다. 거기에 C로 포팅 해주는 모듈도 역시 개별적으로 추가 구매해야 한다. 만약 오픈소스 소프트웨어로 Simulink를 대체하고자 한다면 현재로서는 FMI 기능 및 C 코드로의 오토코딩 모듈이 있어야 할 것이다. 게다가 패키지 설치를 참 더럽게 이상하게 만들어 놨다. MATLAB과 같은 목적의 Python 패키지인 [[NumPy]]는 모종의 계약을 통해 문법과 함수 등의 많은 부분에서 MATLAB 함수와 호환되게 수정해 버렸고, 안 그래도 꽤 쓰였던 NumPy는 더욱 사용자가 늘어나고 있다. Python의 경우는 지원 라이브러리의 대부분이 오픈소스이기 때문에 저장소에서 그냥 커맨드 라인(pip install 패키지) 한 줄로 필요한 거의 모든 패키지를 설치해서 쓸 수 있다.] CG 업계에서도 사실상 표준으로 사용되는 스크립트 언어이다. [[Autodesk Maya|MEL]], [[3ds Max|MAXScript]] 등 툴별로 자체 스크립트 언어들이 난립하고 있었는데, 현재는 Python 스크립팅을 주력으로 밀고 있다.\n\n요즘은 가히 춘추전국시대라고 할 수 있을 만큼 새로운 언어와 프레임워크가 계속 등장하고 있으며, 아예 [[폴리글롯]](Polyglot[* 원래 언어 쪽에서 Multilingual과 같은 뜻으로 쓰이나, 컴퓨터, IT 업계에서는 여러 프로그래밍 언어를 능숙하게 구사하여 적재적소에 잘 조합하여 쓸 수 있는 능력을 뜻한다.]) 프로그래밍이라는 용어가 등장하는 시대다. 당장 [[구글]]만 해도 C++, Java, Python을 골고루 섞어서 쓴다고 알려져 있으며, 게임도 메인은 C++로 작성되었지만 스크립팅은 Python이나 [[Lua]]로 된 경우([[시드 마이어의 문명]], [[WOW]] 등)를 매우 쉽게 찾아볼 수 있다. 따라서 필요하다면 프로그래밍 언어를 가리지 않고 매우 능숙할 수 있게 사용할 수 있도록 공부해야 하며, 알고리즘, 디자인 패턴, 테스트 기법, 동시성 프로그래밍(멀티스레드, 멀티프로세스) 등의 필요한 지식을 훤하게 꿰고 있어야 제대로 된 프로그래머/개발자가 될 수 있다.\n\nPython으로 할 수 있는 것들을 모아 놓은 곳도 있다! [[https://github.com/vinta/awesome-python|Awesome Python]]\n=== 교육 ===\n파이썬은 위의 특징 때문에 교육용 프로그래밍 언어로 각광받고 있다. 한국, 미국의 여러 대학교 프로그래밍 교육들은 개론 수업 언어를 C, C++나 Java에서 Python으로 옮겨가는 추세다. \n\n주의할 점은 Python이 배우기 쉽다는 건 프로그래머 입장에서 나온 말이라는 것이다. 그마저도 다른 언어에 비해 비교적으로 쉽다는 뜻이지, 깊게 파고 들어가거나 특유의 '파이썬스러움(pythonic)'한 코딩을 하려면 생각보다 신경쓸 것도 많고 동적 언어에 익숙해져 있어야 한다. 더욱이 컴파일러 없이 프로그래밍 하는 것은 깡초보에게 권장할 만한 것이 아닌게, 정적 언어에 대한 개념도 없이 동적 언어를 잡았다가는 오히려 더 헷갈릴 수 있다. 왜 마이크로소프트가 [[TypeScript]]를 만들었는지 잠시 생각해 보기 바란다. 더욱이 파이썬은 편집증이 의심될 정도로 객체 위주로 돌아가긴 하지만, 언어의 패러다임을 보면 절차지향, 객체지향, 함수형 모두 사용할 수 있는 언어다. 극단적으로 OOP를 지향하는 Java나 C#보다[* 모든 함수가 일단 클래스 안에 있어야 하며, 전역 함수는 static 함수를 사용하는 형태로 짜야 한다.] 더 신경써야 할 것이 많다는 이야기. 하여튼 프로그래밍 자체를 마냥 쉬운 것으로 생각하다면 큰 코 다친다. 프로그래밍을 쉽게 할 수 있는 것과 좋게 하는 것에는 큰 차이가 있으며, '좋은' 프로그래밍을 하는 것은 프로그래머의 역량에 크게 좌우된다.\n\n== 문제점 ==\n파이썬은 시스템을 건드리거나 반복연산이 많은 것은 하기 어렵지만 python num 처럼 따로 모듈을 지원하기 때문에 크게 걱정할 필요는 없다(그래도 python num을 사용해도 느린건 느리다;;).\n이 단점은 반복 연산이 있는 C를 사용하여 작성하면 사라진다.\n\n=== 멀티스레딩 불가 문제 ===\n파이썬은 [[스레드#s-3|멀티스레딩]]을 지원하기 위하여 GIL(Global Interpreter Lock), 즉 전역 인터프리터 락을 도입하여 사용하게 되었다. 따라서, python 스레드 10개를 만들어도 실제 Pthread/윈도우 스레드가 10개가 만들어지긴 하는데, GIL때문에 개중 동시에 하나밖에 안돌아가는 기이한 구조를 갖고 있다. 물론, 내부적으로 IO작업이 있을 시 바로 다른 스레드로 문맥 교환을 해주고, 바이트 코트를 100번 실행한 다음에는 인터프리터 차원에서 다른 스레드로 교체 해주므로 동시 작업 비슷한 효과가 난다. 이것은 구현이 매우 쉬워지고 빠른 개발을 할 수 있다는 장점이 있으나, 다중 코어 CPU가 보편화된 2006년 이후에는 다중 코어를 제대로 활용하지 못하는 구조적인 문제 때문에 성능에서 밀린다는 평가를 받게 되었다. 만일 특정 프로그램에 순진하게 CPU 코어를 2개 이상 동원하려고 할 경우, 뮤텍스(MutEx), 즉 한 스레드에 여러 개의 CPU가 연산을 행하여 내부 정보를 오염 시키는 것을 방지하는 역할을 맡는 GIL이 병목 현상을 일으켜 코어 하나를 쓸 때보다 오히려 성능이 크게 저하된다는 것. 구글 내부에서 이미 가루가 되도록 까인 부분이다.\n\n더불어, 예전의 Python에는 CPU-bound한 스레드가 I/O-bound한 스레드와 함께 돌아갈 때, I/O-bound한 스레드가 실행되어야 할 상황에서도 context switch가 제대로 이루어지지 않는 문제가 있었다. 이 때문에 CPU-bound 스레드가 GIL을 지나치게 오래 점유하게 되면서 I/O 반응 속도가 느려지고, 다른 스레드는 GIL을 획득하려고 계속 시도하느라 CPU 시간을 낭비하게 되었다. 이에 대해 파이썬 전문가인 [[https://www.dabeaz.com/|David Beazley]]가 2009년에 [[https://archive.org/details/pyvideo_588___mindblowing-python-gil|Mindblowing Python GIL]]이라는 강연에서 지적하였다.[* [[http://www.dabeaz.com/GIL/|Beazley의 홈페이지]]에서 더 많은 시각 자료와 영상을 제공하고 있다.] 이후 Antoine Pitrou라는 개발자가 GIL을 뜯어고쳐 해당 문제를 해결하였고, [[https://docs.python.org/3.2/whatsnew/3.2.html#multi-threading|Python 3.2부터는 새로운 GIL이 적용되어서]] 성능이 어느 정도 개선되었다.\n\n이런 문제점 때문에 파이썬에서 병렬 처리가 필요할 때는 다중 [[스레드]]가 아닌 다중 프로세스로 GIL을 우회하는 방식을 사용한다. 2008년 이후에 multiprocessing이라는 모듈을 제공하는데 이 모듈은 자식 프로세스를 만드는 방향으로 다중 코어 사용 시 성능의 향상을 꾀하고 있다.\n\n단, CPU 부하가 큰 작업을 돌리는 것이 아니면 GIL을 체감하기는 생각보다 쉽지 않다. 다중 스레딩으로 CPU의 여러 코어를 최대한 이용하고 싶은 경우에는 GIL가 굉장히 아쉬운 이슈지만, CPU를 별로 쓰지 않거나 I/O가 주가 되는 작업은 유의미한 성능 차이가 없다. 게다가 어설프게 코어 몇개 깔짝깔짝 이용해서 계산하는 것보다는 그냥 C언어로 모듈을 짜서 붙이는 게 더 빠르다. 즉, python에서 CPU를 많이 먹는 부분은 C 모듈을 짜서 붙이거나, 이미 C 모듈로 짜여있는 라이브러리를 사용하거나(Numpy, Scipy 등), 필요하다면 multiprocessing 모듈을 이용하여 멀티코어를 활용하는 편. 그 이상의 CPU-heavy한 작업은 처음부터 [[C]], [[C++]]로 짜는 게 맞다.\n\n자세히 알고 싶다면 다음 링크들을 참조.(너무 오래된 링크들이라 차라리 인터넷 검색해서 최근 글들을 보기 바란다.)\n\n * [[http://highthroughput.org/wp/cb-1136/|파이썬 GIL 깊숙히! (上) (2006년도)]]\n * [[http://highthroughput.org/wp/cb-1146/|파이썬 GIL 깊숙히! (上) 에 대한 몇 가지 변명 (2007년도)]]\n * [[http://highthroughput.org/wp/python-multiprocessing/|“파이썬은 멀티코어 줘도 쓰잘데기가 없나요?”에 대한 파이썬 2.6의 대답 (2008년도)]]\n * [[http://www.youtube.com/watch?v=Obt-vMVdM8s|Understanding the Python GIL (유튜브) (2010년도)]]\n * [[http://deview.kr/2014/session?seq=47|Python에서의 동시성/병렬성 (2014년도)]]\n\n하지만 대규모 연산의 멀티코어의 성능 향상을 보기 위한 것 말고도, I/O가 주가 되는 작업(즉, 여러 개의 I/O 이벤트를 기다리는 것)을 위해서 멀티스레드를 사용하는 경우가 많고,[* 사실 GIL 방식으로 만들 당시 싱글코어가 일반적이었다는 걸 생각해보면 싱글코어에서의 멀티쓰레딩 목적 자체가 멀티코어 성능 향상보다는 이런 다중 이벤트 루프 구현을 하기 위한 것이라고 봐야 하며, 그런 관점에서는 GIL이 합리적인 선택이었다고 할 수 있다.] 이런 경우에도 복잡한 동기화를 해야 하는 멀티쓰레딩을 사용하는 건 낭비이다. 왜냐하면 디버깅도 힘들 뿐만 아니라, 실제로는 I/O를 위해 기다리는 시간이 실제 I/O가 발생했을 때 필요한 처리 작업을 수행하는 시간보다 월등히 긴 경우가 많아 여러 개의 스레드를 관리하기 위한 자원만 낭비하는 꼴이기 때문이다.\n\n따라서 [[Go(프로그래밍 언어)|Go]]나 [[Erlang]] 같은 최근의 프로그래밍 언어들은 [[코루틴]]이란 개념을 도입해[* 단, 코루틴이라는 개념 자체가 이런 최근의 프로그래밍 언어에서 처음으로 등장한 것은 아니다. 코루틴의 개념은 1950년대에 이미 나왔다.] 이러한 \"event multiplexing\"을 싱글스레드로도 구현할 수 있게 하고 있다. 특히 멀티쓰레딩할 때 필요한 각종 동기화 문제 없이 마치 싱글 스레드 코드를 짜는 것과 거의 동일한 방식으로 코드를 작성할 수 있으면서도 그러한 코드들이 \"동시에\" 동작하는 것처럼 실행해주므로 프로그래머 입장에서 매우 편하다. 실제로는 각 이벤트에 필요한 처리를 하고 다음 이벤트가 발생하기 전까지 비는 시간에 다른 이벤트를 처리하는 코드를 실행시켜주는 방식으로, 시분할과 비슷하지만 문맥 전환이 프로그래머가 작성한 코드에서 명시적으로 다음 이벤트를 기다려야 할 필요가 있을 때 협력적으로 발생한다는 차이점이 있다.\n\n[[C(프로그래밍 언어)|C]]같은 언어에서 이러한 코루틴 지원이 잘 안 되는 이유는, 언어적 차원에서 함수 중간에 실행을 멈추고 다른 함수를 실행할 수 있게 해줘야 하는데 스레드 별로 stack이 1개밖에 없는 구조에서는 구현이 어렵고 하나의 함수로 짜야 할 내용을 여러 개의 [[callback 함수]]로 쪼개면 코드가 지저분해진다는 단점이 크기 때문이다. 이런 callback형태를 사용하는 게 [[Node.js]] 개발 환경이다. 현재로써는 이런 콜백 방식이 유연하면서 퍼포먼스가 좋은 방식이지만 언어적으로 약간 더럽다. 위에서 기술한 Stackless Python에서 코루틴을 먼저 지원할 수 있었던 것도 이런 배경이 있다.\n\n다행히 Python은 (stackless가 아니더라도) yield 키워드를 통해 함수 실행 흐름을 제어할 수 있다. Python 3.4 버전부터는 표준 라이브러리의 각종 파일 입출력, subprocess, socket 통신 등의 기능들을 모두 코루틴화 해주는 asyncio 패키지가 기본 탑재되었다. Python 3.5 부터는 [[C##]]를 본딴 async 함수 선언자와 await 키워드가 포함되어 asyncio 라이브러리에 의존할 수밖에 없던 코루틴 기능을 다른 서드파티 라이브러리도 보다 쉽게 지원할 수 있도록 바뀌고, 코루틴 내부에서의 예외처리 과정이 개선되었다.\n\n==== 멀티코어로 프로그램 돌리기 ====\n[[유닉스]], [[리눅스]], [[macOS]]의 파이썬에서 [[멀티코어]]를 쓰려면 아래와 비슷한 방식으로 [[소스 코드]]를 적으면 된다.\n\n{{{#!syntax python\nimport multiprocessing as mp\n\ndef work(job_list):\n return job_list + 1\n\np = mp.Pool(4)\np.map_async(work, job_list).get()\n}}}\n\n[[윈도우즈]]는 [[포크]](fork) [[함수]]가 없어 아래 [[코드]]를 추가해야 한다.\n\n{{{#!syntax python\nif __name__ == '__main__':\n mp.freeze_support()\n}}}\n\n[[https://blog.naver.com/ossiriand/220548193193|[python] 파이썬으로 시도해보는 멀티 코어 프로세싱, 자고 있는 코어들을 깨우기 2015. 11. 24.]]\n\n=== 난잡한 패키지 관리 및 하위 호환 에러 ===\n최신 언어에 비해 패키지를 설치하거나 만들어 배포하는 방식이 복잡하다. 이는 역사가 오래된 언어이다 보니 패키지를 다루는 방식이 여러 차례 바뀌었기 때문이다.\n\n==== 패키지 설치 및 관리 ====\n오늘날 파이썬 라이브러리를 설치할 때는 주로 pip을 이용한다.\n{{{pip install <패키지명>\n}}} 이 방식은 모든 패키지를 기본적으로 설치된 파이썬에 추가하기 때문에 몇 가지 문제가 생긴다.\n\n우선 여러 프로젝트를 동시에 작업할 때 호환성 문제가 생길 수 있다. 가령 프로젝트 A는 라이브러리 X의 1.1 버전을 사용하는데, 다른 프로젝트 B는 호환성 문제 때문에 X의 1.0 버전을 사용해야 할 경우가 있다. 이 경우 라이브러리 X의 1.1 버전과 1.0 버전을 동시에 설치할 수 없기 때문에, ''가상 환경''이라는 것을 만들어 프로젝트 A와 B에서 사용하는 패키지를 분리해야 한다. 가상 환경은 [[https://virtualenv.pypa.io/|virtualenv]]라는 도구를 이용해 만들 수 있으며, Python 3.3부터는 표준 라이브러리에 포함된 [[https://docs.python.org/3/library/venv.html|venv]] 모듈을 직접 호출하여 만들 수 있다.\n{{{# virtualenv를 사용할 경우\nvirtualenv my-venv\n# venv를 사용할 경우\npython -m venv my-venv\n}}} 위의 명령은 현재 디렉토리에 {{{my-venv}}}라는 가상 환경을 생성한다.[* JavaScript의 [[npm]]이 {{{#npm init}}}으로 프로젝트를 생성하는 것과 비슷하다.] 일반적으로는 가상 환경 이름도 {{{venv}}}로 한다.\n\n또한 pip은 패키지 간의 호환성을 꼼꼼하게 따지지 않는다. 가령 위의 프로젝트 A와 B를 남들이 사용할 수 있게 라이브러리로 만들었다고 하자. 다른 컴퓨터에서 pip을 사용해 A를 설치하면 A가 필요한 X의 1.1 버전이 설치된다. 이후 B를 설치하면 X의 1.1 버전을 삭제하고 1.0 버전을 설치하기 때문에 A를 쓸 수 없게 된다.[* 반대로 B부터 설치한 다음 A를 설치하면 B가 쓸 수 없게 된다.] npm과 같은 현대적인 패키지 관리자들은 패키지 호환성을 꼼꼼하게 검사하기 때문에 이런 상황에서는 B를 설치하려 하면 거부하지만, pip은 그런 거 없다.\n\n리눅스와 같이 자체적으로 파이썬을 탑재한 운영체제에서는 호환성 문제를 특히 신경써야 한다. 시스템에 내장된 핵심 도구들이 기본적으로 설치된 파이썬 라이브러리를 사용하기 때문이다. 만약 패키지를 설치하다가 호환성 문제가 생기면 최악의 경우 OS를 재설치해야 할 수 있다. 따라서 이런 OS에서는 시스템 내장 파이썬에 패키지를 설치하면 안 되며, 대신 {{{#pip install --user}}}로 사용자별 기본 환경에 설치하거나 별도의 가상 환경을 만들어야 한다.\n\n혹여나 프로그램 간 접합 등을 이유로 파이썬의 라이브러리를 사용하다 해당 기능을 외부 모듈(.msi, .exe, .pkg등의 설치파일)을 이용해 서버에 내장하여 돌리려는 때에는 정말 지옥을 맛볼 수 있다. 파이썬의 라이브러리가 불러오는 코어와 서버에 설치되는 모듈이 불러오는 코어가 다르기 때문. (--다른 것이 코어 경로뿐이라면 그나마 낫지만 내부 로직마저 다르다면...?--이런 경우는 상상하면 수명만 줄어들 뿐이다.) 이를 고치려면 에러의 콜스택을 따라가며 어디서 문제가 생겼을지 머리를 쥐어짜고 모듈 내의 코드를 뜯어 고치는 수밖에 없다. \n사실 이 문제는 다른 언어에서도 있을 수 있는 일이다. 다만 파이썬의 경우 패키지 버전의 통일성 부족과 만나버리는데, 버전에 따라 천차만별로 다를 이 대처법들이 인터넷 온갖 구석을 다 뒤져도 나오지 않아 아스트랄한 난이도를 선사한다. (나오긴 하지만, 해결되지 않는 경우가 많다. 물론 직접 질문을 올려도 대부분 답은 안나온다.) 차라리 처음 발견되면 사용하는 라이브러리나 내부 구조를 바꿔서 피해갈 수 있지만, 이미 진행될대로 진행된 프로젝트인 경우 그저 행운이 함께하길 빌 뿐이다.\n==== 패키지 개발 및 배포 ====\n파이썬으로 만든 프로그램이나 라이브러리를 다른 사람들이 사용할 수 있게 만들려면 복잡한 과정을 거쳐야 한다.\n\n파이썬의 라이브러리 개발 방식은 세월이 흐름에 따라 여러 차례 바뀌었다. 패키지 관리자라는 개념이 없어서 각자 프로그램의 소스 코드를 다운로드해 쓰던 시절에는 {{{setup.py}}}라는 설치 스크립트를 각자 만들어서 파이썬 프로그램과 함께 배포하는 것이 관행이었다.[* 복잡한 설치 스크립트가 필요한 이유는 여러 OS 간의 호환성 문제를 해결하기 위함도 있지만, C와 C++ 코드를 함께 사용한 라이브러리를 배포하기 위함이다. 이러한 언어는 해당 OS에 맞게 컴파일해야 하는데, 수많은 OS에 맞춰 컴파일하는 것은 문제가 있다.] 이를 언어 차원에서 지원하기 위해 Python 1.6부터는 [[https://docs.python.org/3/distutils/|distutils]]라는 빌드 도구를 기본 탑재하였다. 그런데 distutils는 자신의 프로그램이 필요로 하는 다른 패키지를 설치하지 못한다는 치명적인 문제가 있어서[* 가령 내가 만든 패키지 A가 B에 의존하고, B는 C에 의존할 경우, 예전에는 사용자가 A, B, C를 일일이 설치해야 했다.], 이를 해결하기 위해 [[https://setuptools.readthedocs.io/|setuptools]]라는 도구가 등장하였다.\n\n세월이 흘러 pip이라는 패키지 관리자와 PyPI라는 패키지 저장소가 등장하면서, {{{setup.py}}}를 만드는 기존의 방식의 단점이 부각되었다.\n\n * {{{setup.py}}}를 실행하는 데 필요한 도구[* setuptools나 설치에 필요한 다른 기능. 또한 C/C++ 코드를 사용하는 경우에는 해당 시스템에 C/C++ 컴파일러도 설치되어 있어야 한다.]가 있는지 확인하고, 없으면 자동으로 설치하거나 사용자에게 알려주는 기능이 없다.\n * {{{setup.py}}}는 파이썬 코드로 작성하기 때문에 패키지 이름이나 버전과 같은 메타데이터를 추출하는 것이 까다롭다.\n * {{{setup.py}}}에는 아무 파이썬 코드나 넣을 수 있으므로 악의적인 코드를 심을 수 있다.\n * {{{setup.py}}}는 setuptools를 직접 {{{import}}}하기 때문에 사용자가 다른 빌드 도구를 선택할 수 없다.\n\n이 때문에 {{{setup.py}}}를 작성하는 대신 {{{pyproject.toml}}}[* [[npm]]이 사용하는 {{{package.json}}}과 유사하지만, [[https://en.wikipedia.org/wiki/TOML|TOML]]이라는 파일 형식을 사용한다.]이라는 설정파일을 사용하는 표준안인 [[https://www.python.org/dev/peps/pep-0518/|PEP-518]]이 등장하였다. pip 10.0부터는 {{{pyproject.toml}}}을 지원한다. 다만 운영체제 중에는 최신 버전의 pip을 탑재하지 않은 경우도 많기 때문에 pip을 업데이트해야 한다. [[https://flit.readthedocs.io/|flit]]이나 [[https://python-poetry.org/|Poetry]] 등의 개발 도구를 사용하면 {{{setup.py}}}를 작성하지 않고 패키지를 만들어 배포할 수 있다. 물론 예전 방식대로 distutils/setuptools를 사용하면서 {{{setup.py}}}과 {{{pyproject.toml}}}를 함께 사용하는 것도 가능하다.\n\nPython 으로 개발한 SW를 공개 배포하는 경우 소스 코드가 그대로 노출된다. 예를 들어 상용 프로그램이나, 보안을 유지해야 하는 경우 파이썬 코드를 숨겨야 한다. \n * Py파일을 Bytecode로 컴파일하는 방법[[https://kibua20.tistory.com/72|#]]\n * PyInstaller를 사용해서 EXE 또는 ELF 형식의 실행 파일을 만드는 방법 [[https://kibua20.tistory.com/93|사용법과 주의사항]]\n가장 쉬운 방법은 byte code인 pyc파일로 변환하는 방법이다. 하지만, 이 방법은 조금만 노력하면 디컴파일이 쉽게 되기 때문에 코드를 숨길 수 없고 다만 코드 보기를 조금 어렵게 만드는 것으로 이해해야 한다. Pyc 파일보다 나은 방법은 PyInstaller를 사용하는 방법이다. PyInstaller는 Py파일을 종속성을 분석해서 필요한 shared lib를 하나에 폴더에 패키징하고, EXE나 ELF의 실행 파일을 생성하여 소스 코드를 숨길 수 있다. PyInstaller로 패키징하는 과정에서 --key 옵션을 사용하면 AES256 으로 Bytecode를 암호화한다.\n\n\n== 다양한 python 구현체 종류 ==\n보통 말하는 Python은 [[C(프로그래밍 언어)|C]]로 구현되었으며, 다른 구현체와 구분하여 언급할 때는 [[CPython]]이라고 표기한다. [[https://hg.python.org/cpython/file/tip|#1]] 또는 [[https://github.com/python/cpython|#2]]에서 [[소스 코드]]를 열람해볼 수 있다.\n\n[[Stackless Python]]은 CPython에서 C 스택을 없앤 것이다.\n\n[[Cython]]은 파이썬 소스 코드를 [[C 언어]] 코드로 변환하여 [[컴파일]]한다.\n\n[[Pyston]]은 [[C++]]로 구현되었다.\n\n파이썬 자체로 구현된 [[PyPy]]도 있다. Pyston과 PyPy는 [[JIT]]가 구현되어 있다.\n\n[[Java]]로 구현되어 [[Java Virtual Machine]] 위에서 돌아가는 [[Jython]]과 [[C\\#]]으로 구현된 [[.NET#Framework|.NET Framework]] 위에서 동작하는 [[IronPython]]이 있다.\n\nJython과 IronPython은 [[가상머신]]에서 동작하는 구현체이다. 시작부터 [[JVM]] 또는 [[.NET]] CLR 위에서 동작하는 Python 구현체를 도입하는 경우는 매우 드물다. 기존에 Java나 .NET Framework에서 개발되어 운영되던 프로그램이나 시스템이 존재하고, 이 환경 하에서 Python의 간결하고 편리한 기능과 높은 생산성을 도입하고자 할 때 사용된다. \n\nJython과 IronPython은 둘 다 CPython에 비하면 실행 속도가 매우 느리며, Jython은 경우에 따라서 심각할 정도로 많이 느리다. 따라서 주요 기능을 수행하는 데에는 문제가 있지만, 보조 기능에서 사용하면 번거로운 작업들을 매우 손쉽게 Python 스크립트로 Java, .NET Framework의 자원을 그대로 끌어다 써서 할 수 있기 때문에 개발 공수와 편리함에서 큰 장점이 있다.\n\n[[JavaScript]]로 구현한 [[Brython]]과 [[Skulpt]]도 있다. [[https://www.pythonpad.co/pads/new/|Pythonpad]]에서 Brython 기반으로 코드를 실행해볼 수 있다.\n\n한편 [[중국]]에서는 [[Chinese Python]]이라는, 중국어 문법으로 한자를 쳐서 돌아가는 언어를 독자 개발했다.\n\n=== [anchor(stackless)]Stackless Python ===\n[[http://stackless.com/|홈페이지]]\n\n파이썬의 표준 구현인 CPython은 이름 그대로 [[C(프로그래밍 언어)|C]]로 만들어져 있는데, 파이썬 프로그램의 함수 호출 [[스택]](Call stack)을 구현할 때 그만 C의 호출 스택[* C 시간에 스택 영역 힙 영역 할 때 나오는 그 스택이다.]에 그대로 얹어가도록 구현되고 말았다. 때문에 파이썬에서 얼마나 메모리를 많이 쓸 수 있느냐에 관계없이 C 호출 스택을 꽉 채우는 순간 그대로 [[스택 오버플로우]] 에러가 뜨게 되어버렸고[* C 레벨에서 만들어주는 스택이라 \"C로 짜여진 프로그램\"인 CPython은 손을 댈 수가 없다. --원칙적으로는 말이지-- ], 파이썬 프로그램의 호출 스택, 즉 프로그램의 실행 흐름을 CPython 스스로 제어할 수가 없게 되어 [[코루틴]] 등의 실행 흐름을 제어하는 언어 기능을 쓸 수 없게 되고 말았다.\n\nChristian Tismer라는 개발자는 이 문제를 타파하려면 \"CPython 소스코드를 수정해서[* CPython은 [[http://docs.python.org/license.html|GPL 호환의 독자 라이선스를 가진 오픈소스 프로젝트]]다.] C 스택을 쓰는 부분을 전부 들어내고 새로 호출 스택을 짤 수밖에 없다\"고 생각했고, 그것을 실제로 실행에 옮긴 것이 Stackless Python이다. 이름의 Stackless는 그래서 사실 C 호출 스택이 없다는 의미. Stackless Python은 스택 오버플로우 에러가 덜 난다는 사소한 장점[* 메모리의 용량이 유한한 이상 스택 오버플로우 에러가 안 날 수는 없다.] 외에도, 스스로 제어할 수 있는 자체적인 호출 스택을 갖고 있기 때문에 마이크로쓰레드[* OS가 직접 관리하는 쓰레드가 아닌, 유저 프로세스 차원에서 직접 돌리는 쓰레드. 그린 쓰레드(green thread)라고도 하는데 [[Ruby]] 1.8까지 지원하는 쓰레드가 바로 이것이다.]나 [[코루틴]] 같은 기능들을 쓸 수 있게 됐고, 덕분에 쓰레드도 [[고자]]고 코루틴도 안되는 CPython에 비해 동시성 처리에서 훨씬 강력한 이득을 낼 수 있게 됐다. CPython도 3.4 버전 이후로 코루틴을 지원한다. 아래 멀티쓰레딩 섹션 참조.\n\n다만, 앞서 말했듯이 CPython을 개조한 것이기 때문에, 파이썬의 버전이 올라갈 때마다 개조한 코드가 이상없이 동작하는지 항상 확인해야 하고, 이 기능이 운영체제나 하드웨어에도 영향을 받는 까닭에 심하면 각각의 운영체제나 CPU별로 개발을 따로 해야 하는 피곤한 작업을 Python이 망할 때까지 해야 하는 지겨운 길을 걷게 되는 것이었다. 그래서 실제로 한동안 Stackless Python의 개발이 잠시 중단된 일도 있었을 정도.\n\n그런 와중에 [[PyPy]] 리드 개발자 Armin Rigo가 \"C 호출 스택도 어차피 메모리에 있잖아? '''그러면 그걸 'memcpy()'로 통째로 복사하고 덮어 씌우면 호출 스택을 저장하고 복구하는 거 아냐?'''\"라는 실로 마개조스러운 아이디어를 내놓는데, Christian Tismer가 여기에 매우 깊은 감명을 받고 Armin Rigo와 함께 구현한 결과 [[http://pypi.python.org/pypi/greenlet|greenlet]]이라고 하는 '''import만 하면 [[코루틴]]을 쓸 수 있는 모듈'''을 만들어내기에 이른다. 같은 걸 구현하려고 언어 인터프리터 자체를 뜯어 고치는 수고에 비하면 놀랄 만큼의 노력 절약이 아닐 수 없다. 다만 이 짓을 제대로 구현한 Stackless Python에 비하면 아무래도 성능이 딸리기 때문에 정말 절실하게 성능이 필요한 [[EVE 온라인]]과 같은 경우엔 Stackless Python을 쓴다.\n\n하지만... Armin Rigo와 Christian Tismer는 지금 둘 다 [[PyPy]]를 만들고 있고, PyPy는 자체 스택을 쓸 수 있는 Stackless 모드의 '''[[JIT|JIT 컴파일러]]'''를 만들어낼 수 있다.\n\n=== [anchor(cython)]C 언어 확장, Cython ===\n--싸이썬-- --[[싸이|Psy]]son--\nPython의 속도를 높이고자 아예 C언어로 변환하여 컴파일하는 방법을 택한 패키지. 파이썬의 문법을 확장하여 정적 타입 선언 기능을 넣어, 기존의 C 코드를 쉽게 접착할 수 있도록 만들었다. Python C API를 이용하여 C 코드를 직접 접착하는 기존의 방식보다 훨씬 사용하기 쉽고, C언어로 변환되어 컴파일 된다는 점 때문에 ctypes로 덧씌우는 것 없이 네이티브 코드(*.so, *.dll)를 직접 사용할 수 있다. 이것을 사용하면 적게는 열 배 정도에서 많게는 천 배 이상까지 속도 향상을 경험할 수 있다. (물론, 파이썬과 C의 구현 차이를 잘 이해하고 컴파일이 제대로 동작할 수 있게하기 위한 코드 수정이 요구된다. 그냥 냅다 넣고 돌려버리면 제기능을 제대로 발휘하지 못하거나 심지어는 거의 발전이 없는 경우도 생길 수 있다. 프로파일링은 언제 어디서나 기본이다.)\n\nC를 모르는 상태에서 Cython을 사용하는 것이 아예 의미가 없는 것은 아니지만, C와 Python 둘 모두에 익숙할 때 Cython을 가장 효과적으로 쓸 수 있다. 고성능이 필요하면 일단 코드 수정이 불필요한 [[PyPy]]를 시도하고, 그걸로는 만족스럽지 않을 때 외부 라이브러리를 도입해 보고, 그걸로도 부족할 때 고려해보자. Cython의 대안으로는, SWIG, CFFI(C Foreign Function Interface), pybind(C++ 전용) 등의 도구들이 있다.\n\n참고로, PyPy도 Cython에 크게 밀리지 않을 정도로 속도가 빠르고, PyPy를 사용하여 실행했을 때 속도 향상이 별로 없다면 Cython을 사용하여 C로 변환해도 상황이 비슷한 경우가 많다. Cython을 사용하여 속도 향상 효과를 얻고자 한다면, 파이썬 코드를 바로 실행할 수 있는 PyPy를 사용하여 속도를 미리 체크해보는 것이 유용한 방법이 될 수 있다.\n\n=== [anchor(pyston)]C++ 구현, Pyston (프로젝트 중단) ===\nPyston은 [[LLVM]] 컴파일러를 사용한다. Pyston은 [[JIT]]([[just-in-time]]) [[컴파일러]]를 내장하여 반복되는 [[소스 코드]]를 빠르게 실행할 수 있다.\n\n2014년 4월 프로젝트가 시작되었으며, Python 2.7 호환, x86 64비트 플랫폼을 목표로 개발 중에 있다. [[https://blogs.dropbox.com/tech/2014/04/introducing-pyston-an-upcoming-jit-based-python-implementation/|Dropbox Tech Blog - Introducing Pyston: an upcoming, JIT-based Python implementation (April 3, 2014)]]\n\nPyston은 [[C++]]로 작성되어졌다. [[https://github.com/dropbox/pyston/wiki/Technical-overview|Technical overview · dropbox/pyston Wiki · GitHub (1 Sep 2016)]]\n\n[[우분투]]에서만 테스트되고 있다. 그러다가 2017년 1월 31일부로 [[Dropbox]]에서 공식적으로 스폰싱을 종료했다. [[https://blog.pyston.org/2017/01/31/pyston-0-6-1-released-and-future-plans/|Pyston 0.6.1 released, and future plans (January 31, 2017)]] 메인테이너가 Dropbox 직원인데 더 이상 참여를 못하는 사실상 프로젝트 중단이다. 직후 프로젝트 리더였던 Kevin Modzelewski는 퇴사하였다.\n\n성능은 상당히 훌륭한 편이었으나, CPython과의 호환성을 오랫동안 맞추지 못했고, 프로젝트가 시작됐을 때와 다르게 Dropbox의 코드가 Go랑 Python3로 많이 이전된 것이 원인으로 보인다(즉, 굳이 투자하면서 개발을 지속할 이유가 없는 상황). 또한 곧 Python2 버전이 공식적으로 지원이 중단될 예정이라서 완전하게 돌아가게 되는 시점(이조차 아무도 알 수 없었다)에서 이 프로젝트의 의미가 많이 퇴색될 수밖에 없었던 것.\n\n[[Dropbox]]는 [[Pyston]]에서 [[PyPy]]로 옮겼다가 현재는 [[Go(프로그래밍 언어)|Go]]를 쓰고 있다. [[https://blogs.dropbox.com/tech/2014/07/open-sourcing-our-go-libraries/|Dropbox Tech Blog: Open Sourcing Our Go Libraries (July 1, 2014)]]\n\n[[https://github.com/dropbox/pyston|홈페이지]]\n\n=== Python 구현, PyPy ===\n[include(틀:상세 내용, 문서명=PyPy)]\nPython으로 Python을 만드는 프로젝트. JIT 컴파일을 사용하기 때문에 훨씬 빠르다.\n\n=== [anchor(jython)]Java 구현, Jython ===\nJython은 [[Java]]로 구현되어 [[Java Virtual Machine|JVM]] 위에서 실행된다. [[https://github.com/jythontools/jython|#]] CPython이 C언어와 결합성, 접착성이 좋은 것처럼 Jython은 Java와 결합성이 대단히 좋으며, 실제로 Java 진영의 메이저 업체인 [[오라클(기업)|Oracle]], [[IBM]] 등에서도 자사 제품에 Jython을 내장하여 스크립팅 기능을 제공하고 있을 정도다.\n\nJython은 [[Java Virtual Machine|JVM]] 위에서 실행되며, Python Module이 제공하는 API는 물론이고, [[JDK]]가 제공하는 모든 API를 그대로 사용할 수 있다. 오히려 pycrpyto와 같이 C언어로 구현된 CPython 모듈은 Jython에서 사용할 수 없다. 그러나 일단 Java Class라면, 설령 JNI로 되어있어서 C로 작성된 동적 모듈(*.dll, *.so 등)을 사용한다고 해도 Jython에서 사용하는데 아무런 제약이 없다. 또한 JVM 위에서 실행된다는 점 때문에 CPython의 GIL이 이식 되지 않았으며, CPython이 멀티스레드에서 보이는 단점이 Jython에는 존재하지 않는다. threading, threadsafety 등의 Python에서 제공하는 멀티스레드(락, 동기화 관련) 기능이 마음에 들지 않으면 java.util.concurrent에서 제공하는 Java API를 사용하면 된다!\n\n=== [anchor(ironpython)].NET Framework 구현, IronPython ===\nMicrosoft [[.NET#Framework|.NET Framework]]의 가상머신인 CLR 상에서 구현되고 이 위에서 동작하는 Python이다. 정확히 말하면 이들 동적언어를 CLR 위에서 구현하기 위한 DLR이라는 프레임워크 기반이다. 제작자 Jim Hugunin[[https://en.wikipedia.org/wiki/Jim_Hugunin|#]]은 [[Jython]]의 제작자이며, [[NumPy]]의 전신인 Numeric 라이브러리의 제작자이기도 하다. 따라서 당연히 .NET Framework 환경에서 제작된 DLL과 결합성이 매우 좋다. Jython과 마찬가지로 병렬 프로그래밍 환경에서 GIL 때문에 고민할 필요가 없다.\n\n자매품으로는 [[C\\#]]로 작성된 모듈을 마치 파이썬 모듈처럼 임포트해서 쓸 수 있는 [[https://github.com/pythonnet/pythonnet|Python for .NET]]이 있으며 이 경우에는 CPython 위에서 돌아간다.\n\n=== [anchor(brython)]JavaScript 구현, Brython ===\n[[JavaScript]]로 구현되었고, JavaScript를 대신하여 웹 브라우저에서 스크립트 형태로 Python을 실행할 것을 목적으로 하는 'Brython'이 있다. Python3를 구현했으며, 다음과 같이 script 태그의 type을 text/python으로 지정하여 실행할 수 있다.\n\n{{{#!syntax python\n\n\n\n Brython\n \n\n\n \n\n \n\n\n}}}\n\n==== 자바스크립트로 컴파일 transcrypt ====\n[[http://www.transcrypt.org|홈페이지]]\n\n[[타입스크립트]]와 비슷한 방식으로 파이썬 코드를 자바스크립트로 컴파일해서 일반적인 자바스크립트와 혼합하여 사용할 수 있게 해준다. (Ex. 파이썬 + [[jQuery]])\n\n=== Micro Python ===\n[[https://micropython.org/|홈페이지]]\n[[https://micropython.org/unicorn/|공홈에서 제공하는 웹에뮬레이터]]\n\n파이썬3의 기능을 임베디드 보드에 최적화 하여 구현한 프로그래밍 언어이다. Windows OS와 Windows Embeded OS와의 관계를 생각하면 이해하기 쉽다. 국내에서는 주로 마이크로비트보드에서 사용할 목적으로 많이 사용된다. 카시오 FX-9860 GIII에 탑제되어 있기도 하다.\n\n== 생태계 ==\n\n=== 개발 환경 ===\n * 콘솔\n 윈도우 명령 프롬프트나 리눅스 Bash 같은 곳에서 실행하는 콘솔형 파이썬 인터프리터다. 여기서도 충분히 간단한 코딩을 할 수 있고, 콘솔 상에서도 pretty printer를 이용해 다양한 자료 구조를 ASCII Art로 출력해 주는 기능까지 이용해볼 수 있다.\n * IDLE\n 파이썬 기본 탑재 콘솔로, 순수 파이썬으로 작성되었다. 콘솔과 같이 직접 명령을 입력하는 것 외에도 파이썬 스크립트를 직접 편집할 수 있으며, 문법 강조와 디버깅 등의 기능을 지원한다. 파이썬에 입문하는 경우에는 따로 텍스트 에디터를 설치할 필요 없이 IDLE만으로도 충분하다.\n * IPython\n 오픈 소스 라이브러리로, 파이썬 IDLE와 달리 LaTeX나 svg, Matplotlib의 플롯 같은 것들도 출력해준다. {{{_repr_}}}이라는 특수 prefix가 붙은 메서드들을 클래스에 정의해 놓으면 IPython의 출력 기능과 쉽게 통합시킬 수 있다. 후술할 Jupyter의 백엔드로도 쓰인다.\n\n==== 텍스트 에디터 ====\n문법 강조와 자동 들여쓰기 등의 편의 기능을 제공하는 프로그램. 메모장보다는 기능이 많고 [[IDE]]보다는 기능이 부족한, 중간 정도의 에디터라고 보면 된다.\n\n[[IDE]]보다 기능은 부족한 대신 로딩 속도가 빠르고, 자잘한 버그가 없기 때문에 개인 취향이나 프로젝트 성격에 따라 이쪽을 더 선호하기도 한다. 파이썬 문법은 C나 Java처럼 Boilerplating이 별로 없기 때문에 IDE의 자동 완성 기능이 상대적으로 덜 중요하다. 개중에는 플러그인을 설치하여 IDE 못지않은 기능을 추가할 수 있는 경우도 있다.\n\n * [[Notepad++]]\n * [[Sublime Text]]\n * [[Atom(에디터)|Atom]]\n * [[비주얼 스튜디오 코드|Visual Studio Code]]: Python 전용 플러그인을 설치하면 더 많은 기능을 이용할 수 있다.\n\n==== [[통합 개발 환경|통합 개발 환경(IDE)]] ====\n * [[PyCharm]]\n [[JetBrains]] 사에서 개발한 IDE로, 코드 컴플리션 기능이 우수하고 각종 프레임워크 지원이 가장 뛰어나다. 커뮤니티 에디션은 무료이지만 [[Django]] 같은 웹 개발에 도움이 되는 툴을 쓰려면 프로페셔널 에디션을 사용해야 한다. 프로페셔널 에디션이 없더라도 플러그인 등을 통해 기본적인 html/javascript 문법지원과 기본적인 자동완성은 가능하지만, Django 전용 자동완성(예를 들어 템플릿에서 파이썬 변수명을 자동완성해 준다던지), 실시간 렌더링 등의 기능은 사용할 수 없다.\n * Spyder\n 오픈 소스 IDE로 [[PyCharm]] 프로페셔널 에디션 같은 툴을 쓰기 힘든 학생[* PyCharm 프로페셔널은 대학생한테는 무료이다]이나 개인 개발자가 사용할 만한 대안이다.\n * [[비주얼 스튜디오|Visual Studio]]\n 가장 무거운 개발 툴이지만 Breakpoint를 설정해 디버깅을 할 수 있거나, Variable Explorer을 가지고 있거나, Profiler를 가지고 있는 등 기능이 다양해서 충분한 값어치를 할 수 있으면 쓰는 것이 좋다. 그 외에도 파이썬으로 프로그래밍에 입문하는 사람들에게도 설치가 쉽다는 점에서 추천하는 편이다.\n\n==== Notebook ====\n다소 특이한 개발 환경으로, 스타일 있는 문서 양식에 코딩을 접목시킬 수 있다. 블로그나 노트를 쓰듯이 단락을 만들고, 그 안에 Cell을 만들어서 코드를 적어놓고, 실행시키면 Plot 같은 것을 보여줄 수 있다.\n\n물론 이런 것이 무슨 프로그래밍인가 싶긴 하지만, 데이터 사이언스나 데이터 분석과 같은 분야는 완성된 시스템을 만들기보다, 파이썬 코드로 데이터를 어떻게 처리하면 되는지 프로토타입을 만들고 그것을 가지고 리포트를 쓰거나 프리젠테이션을 하는 일이 많기 때문에 많이 사용한다. 즉 이들에게는 하나의 완성된 프로그램을 만드는 것이 아니라 데이터를 이리저리 돌려보며 코딩 → 결과 확인 → 코드 수정 → 결과 확인 등의 반복적인 작업이 중요하기 때문이며, 데이터 시각화와 같은 분야에서도 코드를 셀 단위로 나누어 반복 수정하는 작업을 하는 데에 있어서 매우 유용하기 때문이다. SymPy, NumPy, SciPy, Matplotlib 같은 수학, 과학, 머신 러닝 라이브러리를 자주 이용하는 환경에서 개발할 때 유용한 편이며, pandas 등의 라이브러리를 사용하여 데이터 분석을 하는 데도 많이 사용한다.\n\n사실상 데이터 분야에서 Notebook은 업계 표준과 같은 취급이며, 이 때문에 Google의 Colaboratory나 MS의 Azure Notebook과 같은 클라우드 기반의 데이터 분석 환경 역시 jupyter notebook을 모방하거나 탑재하고 있다.\n \n공부하는 입장에서 스크립트 파일을 일일이 만들어야 하는 통상적인 개발 방식이 번거롭게 느껴진다면 차라리 Notebook을 이용해 각종 알고리즘을 연습해 보는 것이 좋다. 다만 파일이 단순한 스크립트 파일이 아니라 거진 워드 문서 같은 수준이 되어 버리기 때문에 (Plot 같은 것을 바이너리 형태로 저장해야 하기 때문이다) 용량이 커지고 Git과 궁합이 맞지 않게 된다는 점은 단점이다. 또한 최소 천 줄이 넘어가는 프로젝트는 노트북으로 하면 안 된다. 노트북은 프로토타이핑이나 리포트를 쓰는데에나 활용하고 진짜 개발은 파이썬 스크립트 파일을 작성해 하도록 하자.\n \n * ipython[* 터미널 기반의 노트북 환경 인터프리터. 기존의 인터프리터와 구분되는 UI를 가지고있다. 주피터 노트북은 ipython이 웹브라우저 기반으로 작동하는 것]\n * Jupyter Notebook[* 알 수 없는 이유로 실행버튼을 눌러도 스크립트가 전혀 실행되지 않고 별표만 띄우는 일이 종종 있다. 이게 걸려버리면 기존에 정상적으로 실행된 스크립트를 다시 실행시키면 별표만 나온다. ~~보통 입문자들이 코드를 이상하게 짜면 저리 되는데, 신기한 건 에러도 안 뿜고 별표만 띄우고 뻗어버린다는 거다.~~ 커널을 리셋하면 해결되긴 하는데 머지않아 또 뻗기도 한다. 밑에 있는 구글 콜라보는 이게 좀 덜한 편.]\n * JupyterLab[* 주피터 노트북의 상위호환 버전. 인터페이스 부분이 노트북에 비해 개선되어 더 깔끔해졌다. 테마나 터미널 설정도 가능해 눈이 편하다. 이전의 노트북을 더 선호하는 사람도 있는 편.]\n * [[https://colab.research.google.com/|Google Colaboratory]][* 구글에서 제공하는 주피터 노트북 환경으로. 별도의 설치가 전혀 필요없다. 심지어 휴대폰에서도 돌아간다! 대형 프로젝트가 아닌 간단한 문제풀이나 데이터 분석 용도로 사용할 수 있다. 다만 첫 실행의 경우 실행속도가 다소 느릴 수 있다. 인터넷에 연결된 상태에서 철저하게 웹 위에서 돌아가는지라 본인 컴퓨터에 없는 모듈도 즉석에서 받아 실행시킬 수 있다. 만들어진 노트 파일은 본인의 구글 드라이브에 저장된다.]\n\n==== 패키지 관리 ====\n각종 파이썬 라이브러리를 설치하고 관리하는 도구이다. 몇몇 파이썬 라이브러리는 리눅스의 패키지 관리자로도 설치할 수 있지만, 파이썬 패키지 관리에 특화된 Pip이나 Conda를 사용하는 것이 이후 패키지를 관리할 때 편리하다. 쓸데없는 라이브러리들이 함께 설치되거나 패키지 의존 관계가 꼬이는 것을 막으려면 하나의 패키지 관리자만 이용하는 것이 좋다.[* 단, Conda에는 등록되지 않아서 Pip으로만 설치할 수 있는 패키지는 어쩔 수 없이 Pip을 사용해야 한다.]\n\n * Pip\n 파이썬의 기본 패키지 관리자이다. 기본적으로 패키지를 모두 한 곳에 설치하기 때문에 시스템에 내장된 파이썬에 영향을 주며, 프로젝트를 여러 개 관리할 경우 호환성 문제가 생긴다. 따라서 virtualenv나 venv와 같이 가상 환경을 다루는 도구와 함께 사용하는 것이 좋다.\n * virtualenv\n 파이썬 가상 환경 관리자로, 패키지를 마음대로 설치할 수 있는 가상 환경을 생성한다. 각 프로젝트마다 자신이 사용할 가상 환경을 만들어주면 프로젝트마다 필요한 패키지를 따로 설정해주는 것이 가능하다.\n \n * Anaconda\n Conda라는 패키지 관리자 + 가상 환경 관리자를 제공하며, 수학/과학/공학 업무에 필요한 NumPy, SciPy, Jupyter Notebook 등의 수백 개의 패키지와 도구를 한번에 깔아줄 뿐만 아니라 GUI도 제공한다. 그래서 통계나 데이터 사이언스, 인공지능 등의 분야 쪽 파이썬 입문자들에게 추천하는 편이다. 다만 설치에 시간이 오래 걸리고, 어차피 몇백 개나 되는 패키지를 다 쓸 일은 없기 때문에 Conda 사용에 숙련되면 아래에 나온 Miniconda를 쓰는 것도 좋다. 2020년 부터 정부 및 200인 이상 기업에게는 유료로 바뀌었다. \n\n * Miniconda\n 위의 Anaconda와 기본 기능은 동일하지만, 패키지는 자기가 직접 찾아서 깔아야 한다. 하지만 어차피 필요한 패키지를 설치하는 것은 {{{#conda install <패키지명>}}} 몇번만 두드려 보면 간단히 해결된다. 이것도 아나콘다의 변형이라서 정부 및 200인 이상 기업에게는 유료.\n\n==== 코드 검사 ====\n내가 작성한 파이썬 코드가 잘 쓰였는지 검사하는 도구. 파이썬은 다른 언어에 비해 문법 규칙이 일관적이지만, 한 줄의 길이나 문자열을 감싸는 따옴표({{{\"\"}}}/{{{''}}}) 등 개발자 입장에서 논쟁거리가 될 만한 요소는 많다. 따라서 코딩 스타일을 통일하는 도구를 사용하면 여러 사람이 협업하면서 생기는 코드의 가독성 문제를 개선할 수 있다. 또한 코딩하는 중에도 오류나 바람직하지 않은 코드를 잡아낼 수 있는 편리한 기능을 제공하는 도구를 사용하면 버그를 일찍 잡아내고 테스트에 드는 노력을 줄일 수 있다.\n\n코드 검사 도구의 한 갈래로 자료형 검사 도구(type checker)가 있다. 동적 언어라서 변수의 자료형을 따로 체크하지 않는 파이썬을 위해, 코드를 직접 분석하여 변수를 올바른 용도로 사용하는지, 특정 함수에 올바른 값을 전달하는지와 같은 정보를 검사한다. 비슷한 동적 언어인 [[JavaScript]]에 자료형 검사를 제공하는 [[TypeScript]]와 유사하지만, 컴파일이 필요한 TypeScript와 달리 Python은 언어 차원에서 type hint를 허용하기 때문에[* 단, 허용할 뿐이지 파이썬이 스스로 자료형을 검사하지는 않는다. Type hint는 다른 도구가 읽고 분석하기 위한 용도이다.] type hint를 추가한 코드도 그대로 실행이 가능하다.\n\n * 코드 오류 검사\n * [[https://www.pylint.org/|Pylint]]: Python 코드를 검사하여 오류나 바람직하지 않은 문법을 잡아내는 도구이다.\n * [[https://flake8.pycqa.org/|Flake8]]: Pylint에 비해 덜 꼼꼼한 대신 더 빠르다.\n * 자료형(타입) 검사\n * [[http://mypy-lang.org/|MyPy]]: 파이썬을 위한 자료형 검사 도구의 원조로, 순수 Python으로 작성되었다.\n * [[https://pyre-check.org/|Pyre]]: [[페이스북]]에서 만든 자료형 검사 도구로, [[Ocaml]]로 작성되었다.\n * [[https://github.com/microsoft/pyright|Pyright]]: [[마이크로소프트]]에서 개발한 자료형 검사 도구로, [[TypeScript]]로 작성되었다. Visual Studio Code 플러그인을 정식 지원하며, 플러그인이 아닌 명령줄 도구로 사용하려면 [[Node.js]]를 설치해야 한다.\n * [[https://google.github.io/pytype/|Pytype]]: [[구글]]에서 만든 자료형 검사 도구이다.\n * 코딩 스타일 검사 및 수정\n * [[https://github.com/hhatto/autopep8|autopep8]]: 파이썬 공식 스타일 가이드인 [[https://www.python.org/dev/peps/pep-0008/|PEP 8]]에 맞게 코드를 고쳐준다.\n * [[https://github.com/google/yapf|yapf]]: [[구글]]에서 개발한 스타일 검사 도구.\n * [[https://black.readthedocs.io/|Black]]: 다른 스타일 검사 도구에 비해 매우 엄격한 것이 특징으로, '''코딩 스타일에 대해 아예 논쟁을 못하게 한 가지 스타일을 강요한다'''는 컨셉을 고수한다. 이 때문에 다른 검사 도구에 비해 설정할 수 있는 옵션의 갯수가 매우 적다. 내가 원하는 코드 스타일이 아니라 Black이 강요하는 스타일을 따라가야 한다는 단점이 있지만, 대신 Black으로 처리한 코드는 누가 쓰든 비슷비슷해서 금방 익숙해진다. 개발자가 신경써야 할 것을 최소화한다는 점 덕분에 후발주자임에도 빠르게 인기를 얻었다.\n * [[https://timothycrosley.github.io/isort/|isort]]: import 문을 일관성 있게 정렬해 준다.\n\n=== [anchor(library)]라이브러리 ===\n * 뷰티풀 수프(Beautiful Soup): XML, HTML와 같은 구문 트리 또는 구조화된 데이터 처리를 위한 [[라이브러리]]이다.\n * [[https://dateutil.readthedocs.io/|dateutil]]: 복잡한 날짜 및 시간 형식을 다루는 라이브러리이다. 표준 라이브러리에 포함된 [[https://docs.python.org/3/library/datetime.html|datetime]]만으로 해결하기 어려운 날짜/시간 문자열 처리나 국제 시간에 관련된 기능을 제공한다.\n * 필로우(Pillow): PIL은 개발이 예전에 중지되었고, PIL의 [[포크]](fork)인 Pillow가 그 역할을 대신하고 있다. Pillow를 쓰자. PIL은 Python Imaging Library의 머릿글자로 간편한 이미지 처리를 위한 라이브러리이다.\n * [[https://pyyaml.org/|PyYAML]]: [[YAML]] 형식의 파일을 읽고 쓰기 위해 사용하는 라이브러리이다.\n * [[https://requests.readthedocs.io/|requests]]: HTTP 요청을 보낼 때 사용하는 라이브러리이다. 표준 라이브러리에 내장된 [[https://docs.python.org/3/library/urllib.html|urllib]] 모듈에 비해 사용이 편리하고 기능이 뛰어나다.\n * [[https://github.com/what-studio/tossi|tossi]]: [[야생의 땅: 듀랑고]]를 개발한 왓 스튜디오에서 개발한 한국어 조사 처리 라이브러리. 같은 인물이 만든 korean 모듈을 대체했다.\n * [[https://docs.python.org/ko/3/library/argparse.html|argparser]] 터미널에서 명령어 parser 지원 [[https://kibua20.tistory.com/120|예제]]\n\n==== 수학 ====\n범용성을 지닌 [[수학]] 라이브러리들\n * 심파이(SymPy): 인수 분해, 미분, 적분 등 심볼릭 연산 기능을 제공한다.\n * [[NumPy|넘파이]](NumPy): 통계, 선형 대수, 행렬 계산, 금융 운용 등을 포함한 과학 계산과 수학 작업. 수치 해석, 특히 선형 대수(linear algebra) 계산 기능을 제공하며 자료형이 고정된 다차원 배열 클래스(n-dimensional array)와 벡터화 연산(vectorized operation)을 지원한다. 참고로 Numpy는 C언어로 제작되어, 파이썬 답지 않은 넘사벽 수준의 속도를 자랑한다. 꼭 수치해석/선형대수 목적이 아니더라도 배열형태의 데이터에 대한 처리속도를 간단하게 높이는 야매 수준으로 사용할 수 있다.\n * 싸이파이(SciPy): 고성능 선형대수, 함수 최적화, 신호 처리, 특수한 수학 함수와 통계 분포 등 과학 계산용 함수를 모아놓은 파이썬 패키지이다. 고급 수학 함수, 수치적 미적분, 미분 방정식 계산, 최적화, 신호 처리 등을 위한 다양한 과학 기술 계산 기능이 제공된다.\n\n==== 데이터 ====\n[[빅 데이터]], [[통계학]] 라이브러리.\n * [[pandas|판다스(pandas)]]: [[데이터 처리]]와 분석을 위한 라이브러리이다. 테이블 형태의 데이터를 다루기 위한 데이터프레임(DataFrame) 자료형을 제공한다. [[R(프로그래밍 언어)|R]]의 data.frame을 본떠서 설계한 DataFrame이라는 데이터 구조를 기반으로 만들어졌다. [[https://jalammar.github.io/visualizing-pandas-pivoting-and-reshaping/|Visualizing Pandas' Pivoting and Reshaping Functions]] 참조.\n * 다스크(Dask) : [[https://dask.org/|홈페이지]] 판다스의 병렬&분산처리 버전. 판다스랑 사용법이 거의 같으면서도 드라마틱하게 빨라진다. 다만 아직 갈 길이 먼 것이 흠.\n * StatsModels: [[통계]] 및 [[회귀 분석]], [[시계열 분석]]을 위한 라이브러리이다.\n\n==== 그래프 (차트) 그리기 ====\n수학이나 데이터의 시각화를 전문적으로 하는 라이브러리\n * 맷플랏립(matplotlib): 과학 계산용 그래프 라이브러리. Tkinter, wxPython, [[Qt(프레임워크)|Qt]], GTK+ 등의 그래픽 엔진을 사용할 수 있으며 그래프와 챠트 등을 그리기 위한 시각화 기능을 제공한다. pylab이라는 서브패키지를 제공하여 [[MATLAB]]의 그래프 기능을 거의 동일하게 사용할 수 있다.\n * 씨본(Seaborn): matplotlib에서 지원하지 않는 고급 통계 차트를 그리기 위한 통계용 시각화 기능을 제공하는 시각화 라이브러리이다.\n * [[보케#python]](Bokeh): 주피터 노트북이나 웹상에서 자바스크립트로 그래프나 차트를 그려주는 기능을 제공해준다.\n * Pygal: 시각화 라이브러리이다.\n\n==== [anchor(libraryml)]머신 러닝 ====\n머신 러닝, 딥 러닝 전문 라이브러리\n * [[텐서플로우]]([[TensorFlow]]): 구글에서 오픈 소스로 공개한 [[기계 학습]], 인공 신경망 라이브러리이다. \n * 사이킷런(scikit-learn): 파이썬의 [[머신 러닝]] 라이브러리이다.\n * [[파이토치]]([[https://github.com/pytorch/pytorch| PyTorch]]): 토치 기반의 기계 학습 라이브러리. 간결하고 구현과 성능이 빠르며, TensorFlow보다 사용자가 익히기 훨씬 쉽다. 학계에서는 2017년부터 이미 파이토치가 텐서플로우보다 더 많이 언급되고 있다.\n * 케라스(Keras): TensorFlow, Theano, CNTK 등 [[딥 러닝]] 라이브러리를 백엔드로 사용할 수 있어 쉽게 다층 퍼셉트론 신경망 모델, 컨볼루션 신경 망 모델, 순환 신경망 모델, 조합 모델 등을 구성할 수 있다. TensorFlow 등 다른 라이브러리에 비해 쉬운 문법이 특징. 현재는 TensorFlow와 통합되었다.\n\n==== [anchor(gui)]GUI 프로그래밍 ====\n파이썬에서 [[GUI]] 프로그래밍에 가장 많이 쓰이는 것은 파이썬에 기본으로 포함된 Tkinter이지만 그 외에도 [[wxWidgets|wxPython]], [[Qt(프레임워크)#s-9.1|PyQt]], [[https://doc.qt.io/qtforpython/| PySide]][* PySide2를 Qt for Python에서 공식적으로 지원하고 있다.], PyGTK, [[SFML]], pyglet도 쓰인다. 브라우저에서 실행되는 javascript와 python 함수 호출 간의 경계를 거의 깨주는 eel을 사용하면 웹 기술을 사용해 GUI 프로그래밍을 할 수 있다.\n\n===== [anchor(tkinter)]tkinter =====\ntkinter는 Tk interface의 약자이다. Tk는 [[GUI]] 프로그래밍을 위한 [[라이브러리]]이다. Tcl은 프로그래밍 언어로 Tk와 함께 GUI에 쓰인다.\n\n===== [[https://doc.qt.io/qtforpython/|Qt for Python]] =====\nPySide2 모듈을 기반으로 Qt5 애플리케이션을 파이썬으로 작성할 수 있도록 [[Qt(프레임워크)#s-9.1]] 측에서 공식적으로 지원하고 있다.\n\n=== 프레임워크 ===\n==== 웹 프레임워크 ====\nPython은 [[웹 서버]][* 하드웨어인 서버 컴퓨터가 아니라, 그 위에서 돌아가는 소프트웨어를 말하는 것이다. 웹 서버는 네트워크 요청을 받아 웹 어플리케이션이 처리할 수 있는 형태로 만들어 넘겨주며, 소켓이나 프로세스 풀과 같은 자원을 관리한다.]와 웹 어플리케이션(프레임워크) 간의 호환을 위해 크게 두 가지 규격을 제시하고 있다. 하나는 Java의 서블릿을 모방한 [[https://wsgi.readthedocs.io/|WSGI]]이고, 다른 하나는 비동기형(async/await) 프로그래밍을 위해 만들어진 [[https://asgi.readthedocs.io/|ASGI]]이다. 웹 프레임워크와 웹 서버를 선택할 땐 서로 호환이 되는지 확인해야 한다. 이 외에도 자체적으로 웹 서버를 제공하거나 독자적인 규격을 사용하는 프레임워크도 있다.\n\n * WSGI 기반 (동기형)\n * [[Django]]: 풀 스택 [[웹 프레임워크]]. 정식으로 비동기 프로그래밍이 가능한 것은 아니지만 ASGI 서버와도 부분적으로 호환이 된다.\n * [[Flask]]: 마이크로 웹 프레임워크. 가볍고 간단한 서비스를 만들기 좋으나, 복잡한 기능은 모두 플러그인을 설치해야 한다.[[https://kibua20.tistory.com/110|사용방법]]\n * [[https://bottlepy.org/|Bottlepy]]\n * ASGI 기반 (비동기형)\n * [[https://www.starlette.io/|Starlette]]\n * [[https://fastapi.tiangolo.com/|FastAPI]]: Starlette에 데이터 검사 라이브러리인 Pydantic을 얹고 이런저런 유용한 기능을 추가한 프레임워크로, [[API]] 서버를 빠르게 개발하는 데 알맞다.\n\n==== 그 외 ====\n * [[Pygame]] - 파이썬으로 비디오 게임을 제작하기 위한 [[프레임워크]]이다.\n * [[https://scrapy.org/| 스크래피(Scrapy)]]: 웹 스크래핑 및 크롤링\n\n== 관련 팁 ==\n * 문자열을 합칠 때 join을 쓰자. range 함수와 str 함수를 같이 쓰면 매우 편해지는 경우가 있다.\n {{{#!syntax python\n''.join(str(x) for x in range(10))\n}}}\n\n * 슬라이스(slice) 문법은 리스트/문자열의 부분을 잘라내는 것 이외에도 다양한 활용이 가능하다.\n {{{#!syntax python\n# 문자열 뒤집기\na = 'abc'\nprint(a[::-1]) # 출력: cba\n\n# 리스트 복사\na = [1, 2, 3]\nb = a[:]\nprint(b) # 출력: [1, 2, 3]\nprint(a is b) # 출력: False\n\nc = [[1, 2], [3, 4]]\nd = c[:]\nc[0] = [5, 6] # 리스트 자체는 복사되지만\nc[1][0] = 7 # 리스트의 원소들까지 복사되지는 않으므로 주의해서 사용하자.\nprint(c) # 출력: [[5, 6], [7, 4]]\nprint(d) # 출력: [[1, 2], [7, 4]]\nprint('%s, %s, %s' % (c is d, c[0] is d[0], c[1] is d[1])) # 출력: False, False, True\n}}}\n\n * 숫자, 문자, 튜플은 변경 불가능(immutable)하며, 리스트, 집합, 딕셔너리는 변경 가능(mutable)하다. 이때 '''변경 가능한 자료형은 다른 변수에 대입하여도 그 내용이 공유된다.''' 그 예로, 아래와 같은 코드가 있다고 하자.\n {{{#!syntax python\na = (1, 2, 3)\nb = a\nb += (2, 1)\nprint(a) # 출력: (1, 2, 3)\nprint(b) # 출력: (1, 2, 3, 2, 1)\n}}}\n 우리가 예상한 대로, 튜플 b만 변경되고, a는 변경되지 않는다. 위의 코드에서 튜플(immutable)을 리스트(mutable)로 바꾸어 보자.\n {{{#!syntax python\na = [1, 2, 3]\nb = a\nb += [2, 1]\nprint(a) # 출력: [1, 2, 3, 2, 1]\nprint(b) # 출력: [1, 2, 3, 2, 1]\n}}}\n 출력을 보면 b만 변경했음에도 a가 변한다는 사실을 알 수 있다. 이것은 모든 변경 가능한 자료형에 적용되며, '''심지어 리스트 안의 리스트 같은 것들까지도 공유가 된다.''' 그러니 원본을 변경하면 안 되는 경우에는 list(), set(), dict()나 copy 모듈 등을 이용해서 객체를 복제하고 작업하자. 변경 불가능한 자료형은 원본을 변경할 수 없기 때문에 해당사항이 없다.\n 특히 list나 dict 자체를 함수에 인자로 전달받을 때 내부에서 리스트를 변형하는 연산을 하면 함수 밖에서도 list나 dict가 변형되니 주의하도록 하자.\n\n * list.insert(0) 와 list.append()는 각각 첫번째 자리에 값을 추가하거나, 마지막 자리에 값을 추가하는 정도의 조그만한 차이일 뿐이지만, 계산 시간이 O(N)과 O(1) 수준으로 차이가 나기 때문에 첫번째 방법은 쓰지 않는 것이 좋다.\n 그래서 prepending에 의존하는 하는 알고리즘을 파이썬 리스트로 구현하려면, 알고리즘을 거꾸로 뒤집는 것이 좋고, 만약 알고리즘을 뒤집기 힘들다면, 파이썬 공식 라이브러리에서 제공하는 deque 같은 것을 써야 한다. [[자료구조]] 개념에 대한 감각이 있으면 이해하기 쉽다.\n CPython같은 경우 JIT를 쓰지 않기 때문에 이런 것을 자동으로 최적화 해 준다고 생각하지 말자.\n\n * 괄호 안에 for 과 if, else 를 넣을 시 주의하자. \n {{{#!syntax python\n#1\nlist(x for x in range(10) if x%2 == 0)\n#2\nlist(x for x in range(10) if x%2 == 0 else 0)\n#3\nlist(x if x%2 == 0 else 0 for x in range(10))\n}}}\n 1은 되지만 2는 되지 않으며 3은 된다. if만 넣을 경우 for 뒤에 써야 하며, '''조건을 충족하지 않는 원소들은 생략된다'''(즉, 1의 결과물은 [0, 2, 4, 6, 8]이다). if와 else 모두를 넣는다면 for 앞에 넣어야 하며 조건을 충족하면 맨 앞, 아니라면 else 다음이 반환된다.\n\n * 마지막으로 호출된 값(대입이 이루어지지 않은 경우)은 '''_''' 변수에 저장된다. 또한 이 변수에 대입한 값은 버려진다.\n\n * 멀티프로세싱은 \\_\\_main\\_\\_ 블럭 안에 들어가야 한다. 네임스페이스 문제 때문. 들어가지 않으면 오류를 뿜는다.\n {{{#!syntax python\n#if 대신 while도 가능.\nif __name__ == '__main__':\n}}}\n\n * 파이썬 2와 3에서의 range는 리턴 형식이 다르다. 2에서는 리스트를 리턴하지만 3에서는 range 객체를 리턴한다. 따라서 3에서 range를 리스트로 바꾸려면 아래와 같은 방법들로 전환해야 한다. 파이썬 2에 익숙한 사람은, 파이썬 3의 range는 파이썬 2의 xrange와 동일한 역할을 한다고 생각하면 된다.\n {{{#!syntax python\nlist(range(10))\n[*range(10)]\n}}}\n 그 외에도 파이썬 2와 3은 정수 나눗셈, print 문법, 문자열 종류, import 방식 같은 데서 차이가 많이 나는 편이다. 일부는 {{{__future__}}}이라는 라이브러리에서 파이썬 2에서도 3과 같은 문법을 쓸 수 있도록 해 주는 기능을 제공하고 있지만, 그렇지 않은 부분들은 stack overflow등을 참고해서 직접 만들어서 쓰는 것이 좋다. 현재 많은 오픈 소스 라이브러리들이 {{{__future__}}}로 도배되어 있고 가내 수공업 식으로 호환성을 뗌질해 있는 것을 보면 말이다. 파이썬 2.7이 공식적으로 지원이 중단되면 시점까지 많은 라이브러리들이 파이썬 2 지원을 철회할 계획을 가지고 있으므로, 그 때가 되면 이런 호환성 문제에서 숨통이 트일 것이다.\n\n * [[http://freesugar.tistory.com/37|error: Microsoft Visual C++ 14.0 is required. Get it with \"Microsoft Visual C++ Build Tools\"]]\n\n * Bolierplate 코드가 적고, 리스트와 셋, 해시 등의 자료구조를 간단한 기호로 표기할 수 있어 코딩 테스트 시 많이 사용되는 언어이기도 하다. Python으로 코드를 작성하면 같은 알고리즘을 C++, Java 등으로 구현했을 때보다 전체적인 코드 길이가 비약적으로 짧아진다.\n\n * 파이썬 인터프리터라도 열어서 아무 모듈이나 임포트하거나, print 함수에 대해 dir(print)를 입력해보면 파이썬의 구조를 좀 더 잘 알게 된다. 우리가 사용했던 함수가 다르게 보일 것이다.\n\n== [[Python/문법|문법]] ==\n[include(틀:상세 내용, 문서명=Python/문법)]\n\n== 도서 ==\n파이썬은 [[2021년]] 현재까지도 '''이거다!''' 할 만한 명저가 없다. [[프로그래밍]] 입문부터 실사용까지 오만가지 책들이 난립해 있어서 핵심을 관통하는 주제를 딱히 잡기 어려워서인 듯 하다. (--사실 기본기와 개념만 제대로 익힌 다음에는 제일 배우기 쉬운 방법이 구글링이라 카더라.--)\n\n파이썬 관련 책은 대형 서점에 가면 파이썬 분류가 따로 잡혀서 어마어마하게 난립해 있을 정도로 경쟁이 치열하다. 파이썬만 따로 분류가 잡혀서 매대를 꽉 채운 파이썬 책들을 보다 보면 [[춘추전국시대]] 저리가라 할 수준이다. 그러나 도서들이 죄다 특정 분야에만 치중해서 전반적인 내용을 관통한 책은 별로 없는게 문제이다. [[Ruby]]같은 경우는 기타 프로그래밍 언어에 Programming Ruby 딱 한권만 달아놔도 재고가 없을 정도로 인기인 것과 정 반대. Python은 책이 워낙 많다보니 [[서점]]에도 재고가 수두룩하다. \n\n||<-2> '''바로 쓰는 파이썬(기초편)''' ||\n|| [[파일:바로 쓰는 파이썬.jpg|width=100%]] ||\n|| [[https://www.snupress.com/book/category?md=view&goodsidx=3069|관련 링크]] ||\n[[서울대학교]]의 일부 강좌에서 이번학기 학부 수업용 교재로 사용하기 시작하였다.\n\n||<-2> '''Do It! 점프 투 파이썬''' ||\n|| [[파일:x9788997390915.jpg|width=100%]] ||\n|| [[https://book.naver.com/bookdb/book_detail.nhn?bid=10290989|관련 링크]] ||\n[[대한민국]]에서 입문 서적으로는 위키독스에 연재된 강의를 편집한 [[https://book.naver.com/bookdb/book_detail.nhn?bid=10290989|Do It! 점프 투 파이썬]]이라는 서적이 인기가 많다. 컴퓨터 과학 부문 베스트셀러 수준. 기초적인 내용을 다루며 대상 독자도 비전문가라 매우 깊이 있는 책이라 보기는 어렵고 어디까지나 입문 서적이다. 그리고 [[한국]]에서만 인기가 있고, 점프 투 파이썬 정도의 '''입문서는 너무나도 많다'''. [[서점]]에 가면 매대에 깔린게 점프 투 파이썬 정도의 입문서들. 그러나 해당 책은 한국 국내에 커뮤니티가 형성([[네이버 카페]])되어 있어서 질문/답변이 빨라 [[베스트셀러]]에 올랐다. \n\n||<-2> '''파이썬 쉽게, 더 쉽게''' ||\n|| [[파일:1185890025_f.jpg|width=100%]] || [[파일:x9791188621477.jpg|width=100%]] ||\n|| 2014년 판 || 2017년 개정판 ||\n또다른 입문서로는 [[일본]]에서 츠지 신고가 써서 나온 [[https://book.naver.com/bookdb/book_detail.nhn?bid=8109043|파이썬 더 쉽게, 더 깊게(원판)]] [[https://book.naver.com/bookdb/book_detail.nhn?bid=14364860|파이썬 쉽게, 더 쉽게(2017년 개정판)]]가 있다. 2014년 판은 Python 2 기준이고 2017년 판은 Python 3 기준이다. \n\nPython 입문을 벗어나고 나면, [[기계학습]] 분야로 갈 것이냐, [[빅데이터]] 분야로 갈 것이냐에 따라서 추천 도서가 달라진다. [[생활코딩]]에서도 이거 때문에 관련 문의가 [[페이스북]] 페이지에 올라오는 편이다.\n[[빅데이터]] 분야(데이터 분석 분야)로 가는 데에는 책이 많은데 학원 교재로는 [[https://book.naver.com/bookdb/book_detail.nhn?bid=12657786|파이썬 데이터 분석 입문: 엑셀 및 CSV 파일 처리부터 데이터베이스, 시각화, 통계분석, 자동화까지]]라는 책을 많이 쓴다. 이 분야에서 가장 많이 사용하는 Pandas 에만 집중하고 싶다면 Pandas 프로젝트를 시작한 웨스 맥키니(Wes Mckinney)가 저술한 '파이썬 라이브러리를 활용한 데이터 분석'으로 시작해도 좋다.\n\n||<-2> '''밑바닥부터 시작하는 [[딥러닝]]''' ||\n|| [[파일:91LOp7zilgL.jpg|width=100%]] || [[파일:x9788968484636.jpg|width=100%]] ||\n|| [[https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585|일본 원서]] || [[https://book.naver.com/bookdb/book_detail.nhn?bid=11492334|한국어 번역서]] ||\nPython [[기계학습]] [[딥러닝]] 분야만큼은 명저가 하나 나왔다. 일본의 사이토 고키가 쓴 \"밑바닥부터 시작하는 딥러닝\"이라는 책이다. 원서 [[일본어]]로 나왔는데, 일본 내에서 사이토 고키가 직접 감수를 맡은 [[영어]]판이 같이 나와 이 영어판을 기반으로 [[미국]]에서 인기를 끌었다. 그리고 [[2016년]] [[구글 딥마인드 챌린지 매치]]로 [[인공지능]] 분야가 한국 일반인에게 알려지면서 해당 도서가 [[2017년]] [[한국어]]로 번역 출간되었다. 번역 질도 굉장히 깔끔해서 보기 좋다. 결정적으로 책이 두껍지 않고 얇다. [[얇은 책]]인데 핵심만 집어넣어서 이론을 완성해가지고 대통일 명저로 꼽힌다. \n\n[[한국]] 국내에서 [[주식]] [[투자]]를 하는 사람 중에서 이른바 [[알고리즘 트레이딩]], 쉽게말해 개인판 [[프로그램 매매]][* [[프로그램 매매]]는 동시에 5억 원 이상의 매매를 내는 거래로, 원래는 [[한국예탁결제원]]의 승인을 받은 [[기관]] 투자자나 [[외국인]] 투자자만 사전에 예탁결제원에 프로그램을 등록하고 매매할 수 있다. 그런데 동시에 5억원 미만의 거래를 하는 개인투자자들까지 예탁결제원이 간섭하기는 뭐했는지 이쪽은 규제 사각지대다.]를 짜려는 사람도 있다. 이런 사람들은 [[https://book.naver.com/bookdb/book_detail.nhn?bid=14623546|파이썬으로 배우는 알고리즘 트레이딩]]이라는 책이 인기가 좋다. [[한국]] [[개미]]투자자들이 주로 사용하는 [[키움증권]], [[미래에셋대우]], [[이베스트투자증권]], [[대신증권]] API를 활용해, 간단한 프로그램을 짜서 프로그램 매매를 할 수 있기 때문이다. 원래 Python 속도가 느려서 원래 알고리즘 트레이딩(개인 프로그램 매매)는 Python보다 속도가 빠른 [[R(프로그래밍 언어)|R]]이나 [[C언어]]로 하는게 원칙이다. [[미국]] [[금융]]업계에서는 R로 하는 프로그램 매매를 가르친다.[* [[일본]]은 [[Ruby]]가 대세라서, Ruby로 하는 [[알고리즘 트레이딩]]이 많다. Ruby로 만든 트레이딩 툴은 Python과 비슷한 퍼포먼스가 난다.] 그런데 한국에서는 주식 투자자들 보고 Python 외에 R이나 [[C언어]]까지 배우라고 하기는 어렵다고 생각했는지, Python 알고리즘 트레이딩 책이 나왔다. 해당 책은 [[2017년]] 나온 이후 인기를 끌어서 [[2019년]] 개정판이 나올 정도가 됐다.\n\n||<-2> '''파이썬 알고리즘 인터뷰''' ||\n|| [[파일:pai_cover.jpg|width=100%]] ||\n|| [[https://book.naver.com/bookdb/book_detail.nhn?bid=16406247|관련 링크]] ||\nPython으로 알고리즘 문제를 풀이하는 책도 나와 있다. 과거에는 알고리즘 대회나 코딩 테스트시 C++을 주로 사용해왔으나 직관적이고 쉬운 문법으로 인해 Python이 점점 인기를 얻고 있다. 이 책은 국내 첫 출간된 Python 알고리즘 코딩 테스트 책으로 자료구조와 알고리즘을 그림으로 도식화해 이해하기 쉽게 설명하고, 카카오 코딩 테스트 기출 문제 포함 주제별 다양한 알고리즘 코딩 테스트 문제를 다양한 각도에서 효율적인 방식으로 풀이하여 좋은 반응을 얻고 있다. 나무위키 또한 이 책에서 사용을 허락한 일러스트를 이용해 다양한 알고리즘을 효과적으로 설명하고 있다.\n\n== 여담 ==\n * [[구글]]에서 python이라고 검색하면 제일 위에 뜨는 게 바다 괴물이나 [[파이톤#s-1|뱀]]이 아니라 이거다.\n\n * [[pyBreakout]]이라는 게임은 파이썬으로만 작성되었다. 오로지 pygame만 사용했으며, 개발자가 초등학생이다.\n\n * Python의 공식 documentation은 정말 형편없기로 유명하다. 구체적으로는 직관성이 떨어지고 예시가 부실한 것이 그 이유인데, 꼭 필요할 때 읽으려면 헤매기 십상이다. 심지어 이는 국내도 아닌 영어가 모국어인 프로그래머들의 공론인데, Python을 찬양하는 프로그래머들도 인정하는 부분이다. 다만 최신 버전으로 갈수록 가독성이 조금씩 개선되어 가고 있다.\n\n * Google Android OS에서는 공식적으로 Python을 미지원한다. 하지만 SL4A나 Linux Emulator를 설치 후 Python 실행이 가능하다.[[https://kibua20.tistory.com/117|비교내용]]\n\n * 만약 파이썬으로 짠 코드가 잘 작동되는 것을 넘어 가독성이 높고 유지보수도 쉬운 코드라면 이를 파이썬다운(pythonic, 파이써닉) 코드라며 대우한다. 일반 프로그래머라면 이러한 파이써닉 코드를 지향해야 한다.\n\n * [[띵소프트]]에서 개발 중인 게임 [[페리아 연대기]]에서는 '''고대언어'''라고 한다.\n\n * [[https://plus.google.com/115212051037621986145/posts/R8jEVrobbRj|2013년 재미있게도 한 헤드헌터로부터 경력직 파이썬 개발자 취업제안을 받았다고 한다.]] 즉, '''파이썬 창시자에게 파이썬 '경력직' 개발자를 구하는 수준의 메일을 보낸 것'''.\n\n * [[C++]], [[Java]]와 함께 [[구글]]의 3대 개발 언어 중 하나로 알려져 있다.\n\n * [[문명 4]]의 스크립트 언어로 쓰였다. [[Lua]]와 더불어 게임 스크립트 언어의 양대 산맥.\n\n * [[심즈 4]] 역시 Python을 기반으로 해서 동작한다. 클라이언트를 살짝 보면 수많은 .pyo 파일들의 향연을 볼 수 있다. 심즈 4의 최적화는 나름 우수한 편. 근데 pyo가 3.5 버전에서 삭제되고 pyc로 대체되었다.\n\n * [[킹덤 언더 파이어]]의 엔진에도 쓰였다. 500여 개의 자체모듈이 누더기처럼 돌아갔다고 한다.\n\n * [[월드 오브 탱크]]는 상당 부분이 파이썬으로 구현되어있다. 유저가 작성하는 모드도 로직 부분은 파이썬으로 구현된다.\n\n * [[EVE 온라인]]은 Python의 경량/고속 실행 버전인 Stackless Python으로 작성되었다. 개발사 CCP Games는 파이썬 재단의 정식 후원자이기도 하다. 2000년대 초에 싱글코어 CPU가 계속 쓰일 줄 알고 서버 코드를 구버전 파이썬으로 짰다가 다중 코어 사용이 힘들어지자[* 전장에서 일어나는 일을 제외한 나머지 시시콜콜한 일을 다른 코어로 돌리기는 하였으나, 게임의 최소 단위인 전장은 구조상의 한계로 하나의 코어만 동원할 수 있다.] 눈물겨운 마개조를 거듭하여 파이썬이라는 언어가 제공할 수 있는 처리 능력을 한계치까지 뽑아서 쓰고 있다.\n\n * [[https://www.pythonpad.co/courses/intro-1/|파이썬패드 프로그래밍 기초 강의]]. 카이스트 프로그래밍 기초 과목과 호환되는 공개 강의이다. 인터프리터 설치 없이 기초적인 파이썬 사용법을 배울 수 있다.\n\n * [[https://codecombat.com|코드컴뱃 홈페이지]]. 파이썬을 게임의 형식을 빌려 배울 수 있는 사이트이다.\n\n * [[http://www.numpy.org/|NumPy]]+[[http://www.scipy.org/|SciPy]]+[[http://matplotlib.org/|matplotlib]] 조합이 과학 공학 계산용으로 자주 쓰인다.\n\n * [[파일:external/regmedia.co.uk/swift_benchmark.jpg]]\n 2014년 6월 WWDC에서 애플이 공개한 프로그래밍 언어 [[Swift(프로그래밍 언어)|Swift]]보다 220배 느리다고 까였다. 유저들은 [[C(프로그래밍 언어)|C]] 바인딩인 ctypes를 출동 시킨다고 부들부들... '''하지만 [[JIT]] 없는 동적 인터프리터 언어와 컴파일 언어의 성능을 비교하면 어떤 언어를 비교하더라도 당연히 후자가 압도적으로 유리하다는 점에서 이건 비교 자체가 잘못된 것이다.''' 게다가 암호화 같은 CPU heavy한 작업은 보통 다 C로 짜서 붙인다. Python 해쉬 라이브러리인 hashlib만 해도 코어가 전부 C로 되어있다.\n\n * [[객체 지향 프로그래밍]]을 배울 때 추천할 만한 언어이다. 많은 대학들이 [[C++]] 환경에서 OOP를 가르치지만, 이 경우 필요한 객체를 만들어서 쓰는 실습이 많은데 대부분 이미 존재하는 객체를 가져다 쓴다는 개념을 이해하지 못하는 경우가 많다. STL을 쓰면 달라지지만 실습에서 STL을 요구하는 문제가 나오는 경우도 드물고, 주로 사용되는 문자열 변환, 배열 관련 연산 등은 파이썬에서 따로 임포트할 필요 없이 자료형 자체가 이미 클래스로서 편리하게 클래스 함수를 던져주기 때문에, 클래스의 재활용이라는 측면을 훨씬 이해하기 쉽다. 무엇보다 하루면 다 배울 수 있는 언어이기도 하고. 다만 대학들도 아무런 이유 없이 C++을 객체 지향 입문용으로 채택한 건 아니다. 많은 학생들이 프로그래밍 언어 중 C를 가장 먼저 배우기에, C++은 그나마 익숙한 개념들을 이용해서 객체 지향을 학습할 수 있게 한다. 물론 C++ 프로그래밍은 C 프로그래밍과는 패러다임 자체가 다르므로 주의가 필요하지만, 적어도 \"[[C언어]]의 [[구조체]] 안에 함수를 정의할 수 있게 하면 C++이다\"는 식의 낚시로 학생들에게 심리적 편안함을 줄 수는 있다. 최근에는 객체 지향 입문용 언어로 C++보다 파이썬을 먼저 가르치는 대학도 늘어나고 있는 추세라, 파이썬부터 먼저 공부하는 것도 나쁘지 않다.\n * Fluent Python(번역서: 전문가를 위한 파이썬)이라는 책이 있다.\n\n * [[https://doc.lagout.org/programmation/python/Data%20Structures%20and%20Algorithms%20in%20Python%20%5BGoodrich%2C%20Tamassia%20%26%20Goldwasser%202013-03-18%5D.pdf|알고리즘 및 자료구조를 파이썬]]으로 공부하기\n\n * [[2014년]] 8월 30일, 유서깊은 파이썬행사인 PyCon이 드디어 한국에서도 성공리에 개최되었다. [[http://pycon.kr/2014|#공식홈페이지]]\n [[2015년]] 8월 29일, PyCon 2015가 [[상암]] 누리꿈스퀘어에서 약 700명의 규모로 개최되었다. [[http://pycon.kr/2015|#공식홈페이지]]\n [[2016년]]에는 PyCon APAC가 [[한국]]에서[* 강남 코엑스에서 13~14일 아카마이에서 15일(튜토리얼).] 성공리에 개최되었다.[[https://www.pycon.kr/2016apac/|#공식홈페이지]]\n [[2017년]]에는 PyCon.KR 2017(파이콘 한국 2017)이 강남 [[코엑스]]에서 열렸다(8.12~15).\n [[2018년]]에는 PyCon.KR에 참가한 [[IntelliJ IDEA]]로 유명한 [[JetBrains]]의 [[PyCharm]] 프로젝트 매니저인 Dmitry Trofimov가 행사를 보고 [[https://github.com/traff/pycharm-kr|PyCharm 한글화 오픈소스 프로젝트]]를 열었다. 그러나 번역이 20% 정도 되고 수 년째 멈춰 있는 상태...관심있는 사람들은 기여해 보자. 다만 개발자들은 호환성을 위해서 영어 버전을 사용하는 경우가 대부분이라 기여를 할 사람이 있을지는 의문이다.\n\n * 2015년 7월 9일 \"같이 번역해서 같이 봅시다\"라는 표어를 내걸고 파이썬 문서를 '''한글로 번역하는''' 프로젝트가 생겼다. [[http://www.flowdas.com/pages/python-docs-ko.html|flowdas / 파이썬 한국어 번역]]\n\n * [[도널드 글로버]]가 자신의 노래 가사에 Python을 배우라는 가사를 넣기도 했다.\n\n * [[타오바오]]에서 [[https://npm.taobao.org/mirrors/python/|다운로드 미러]]를 제공하고 있다.\n\n * 귀도 반 로섬은 2019년 10월 30일부로 [[드랍박스]]에서 나오고 은퇴하였다.\n\n * 그리고 2020년 11월 13일, 은퇴 생활이 지루하다며 다시 [[마이크로소프트]] 의 개발팀에 합류했다. [* [[https://twitter.com/gvanrossum/status/1326932991566700549|트윗]] ]\n\n * [[디시인사이드]] [[마이너 갤러리]] 중 [[https://gall.dcinside.com/python|파이썬 마이너 갤러리]]가 있었으나 접근 제한 조치되어 [[아카라이브]] [[https://arca.live/b/python|파이썬 채널]]로 이주하였다.\n\n * 3.5부터는 XP를 지원하지 않는다. \n\n * [[투어라이브 ]]의 백엔드 기술의 대부분은 파이썬으로 구현되어있다. \n\n * 2020년 5월, 3.9부터는 비스타와 7을 지원하지 않는다.\n\n[[분류:Python]]", 5 | "contributors": [ 6 | "203.241.183.12", 7 | "wikior", 8 | "39.119.129.24", 9 | "cksgh9103", 10 | "lallasweet", 11 | "lifeeraser", 12 | "210.101.187.205", 13 | "wtousim", 14 | "benquan1812", 15 | "61.254.37.240", 16 | "113.59.178.10", 17 | "piingn", 18 | "121.125.172.41", 19 | "122.44.174.52", 20 | "seacrest", 21 | "depth", 22 | "14.41.41.91", 23 | "halfling", 24 | "211.185.250.158", 25 | "dbstjd56599", 26 | "1.229.188.147", 27 | "125.181.58.208", 28 | "lesmeasurables", 29 | "zoroark571", 30 | "rafina227", 31 | "211.223.35.76", 32 | "chcv", 33 | "archevil", 34 | "223.222.170.133", 35 | "jjin3826", 36 | "210.121.232.120", 37 | "kkkyyy03", 38 | "175.123.58.63", 39 | "112.171.89.167", 40 | "pistol", 41 | "121.127.84.205", 42 | "detegice", 43 | "chiantiscarlett", 44 | "arduino", 45 | "203.251.29.244", 46 | "ddssz033", 47 | "218.239.156.125", 48 | "124.50.97.25", 49 | "175.197.4.193", 50 | "220.71.126.100", 51 | "gyumin202", 52 | "175.119.80.41", 53 | "211.170.11.154", 54 | "superman", 55 | "117.123.13.121", 56 | "aninteger", 57 | "hanzaixing", 58 | "notebox9245", 59 | "ninanyong", 60 | "121.161.88.13", 61 | "14.46.222.205", 62 | "222.107.66.182", 63 | "hoonnam", 64 | "damena_inazuma", 65 | "iz7h", 66 | "syntax0", 67 | "fred6758", 68 | "126.15.241.156", 69 | "203.234.243.93", 70 | "125.142.252.250", 71 | "116.125.117.239", 72 | "chaneyoon", 73 | "myweet", 74 | "210.207.20.50", 75 | "64.233.173.226", 76 | "175.127.179.215", 77 | "jason2357y", 78 | "116.127.137.127", 79 | "211.196.191.136", 80 | "14.32.105.91", 81 | "112.156.240.224", 82 | "blackj0221", 83 | "hyphen", 84 | "64.180.168.141", 85 | "118.217.34.111", 86 | "14.42.39.82", 87 | "121.137.63.56", 88 | "qurate5031", 89 | "bglassm", 90 | "112.171.19.10", 91 | "alfalfa", 92 | "mangal", 93 | "secon", 94 | "121.138.88.245", 95 | "minikupa", 96 | "121.187.207.51", 97 | "southsea6", 98 | "121.155.143.136", 99 | "58.126.228.82", 100 | "59.7.246.12", 101 | "180.229.33.234", 102 | "211.252.20.97", 103 | "r:pckdrms", 104 | "monoasterisk", 105 | "175.125.25.60", 106 | "124.80.40.167", 107 | "khb", 108 | "49.50.0.194", 109 | "14.54.24.2", 110 | "220.85.177.8", 111 | "sju07144", 112 | "122.44.177.108", 113 | "gusaka213", 114 | "pirunhd", 115 | "jjikkses", 116 | "zweihaender", 117 | "suplexhold", 118 | "211.199.35.44", 119 | "miroo4517", 120 | "219.250.138.110", 121 | "183.97.197.160", 122 | "kanaraten", 123 | "59.19.188.186", 124 | "121.141.115.10", 125 | "namsan", 126 | "119.203.247.119", 127 | "121.129.97.167", 128 | "110.11.76.84", 129 | "218.39.116.97", 130 | "great_red", 131 | "45.115.65.100", 132 | "kerrigan", 133 | "rambor12", 134 | "125.177.122.42", 135 | "112.109.62.176", 136 | "58.120.205.181", 137 | "210.108.251.60", 138 | "kpjhg0124", 139 | "182.230.208.229", 140 | "gusunbark", 141 | "diddnjswns07", 142 | "121.162.51.10", 143 | "1.252.23.30", 144 | "libro", 145 | "pppp", 146 | "jjangsepd", 147 | "125.183.95.237", 148 | "sangh518", 149 | "175.194.45.196", 150 | "doubleplus", 151 | "mapirus", 152 | "e080hsm", 153 | "kongkongduri", 154 | "1.251.244.192", 155 | "175.116.127.44", 156 | "121.179.17.200", 157 | "fairy", 158 | "60.253.6.80", 159 | "vincent525", 160 | "58.29.38.128", 161 | "picachu2333", 162 | "61.75.146.155", 163 | "rudiblaz", 164 | "142.147.59.203", 165 | "heffykuma", 166 | "king0816", 167 | "mungyu", 168 | "106.242.15.210", 169 | "ldmsys", 170 | "albert_einstein", 171 | "142.105.55.123", 172 | "210.90.249.160", 173 | "rladbqls1", 174 | "nonnonapp", 175 | "winster77", 176 | "democraz", 177 | "sincity", 178 | "sequentialaccess", 179 | "rqme20", 180 | "112.170.60.253", 181 | "simonfly05", 182 | "121.138.83.21", 183 | "211.219.104.85", 184 | "162.222.168.66", 185 | "211.252.95.147", 186 | "121.167.209.189", 187 | "hks01108", 188 | "175.197.32.54", 189 | "1.210.0.80", 190 | "kimsu21", 191 | "otimtim", 192 | "210.117.181.205", 193 | "prime235711", 194 | "one", 195 | "yerel", 196 | "caenhon", 197 | "112.172.211.218", 198 | "221.155.89.188", 199 | "222.65.189.224", 200 | "211.209.249.63", 201 | "finefain", 202 | "sylee957", 203 | "jebi", 204 | "118.217.134.214", 205 | "59.10.206.166", 206 | "116.122.87.8", 207 | "avantgarde95", 208 | "owb101", 209 | "user0320", 210 | "222.120.77.100", 211 | "sm5good1234", 212 | "agenti", 213 | "221.155.195.238", 214 | "ztarqwe", 215 | "nancykwon", 216 | "175.192.173.207", 217 | "14.45.91.209", 218 | "39.116.141.238", 219 | "118.176.119.138", 220 | "seungwoo208", 221 | "124.80.44.22", 222 | "louise0404", 223 | "anatra95", 224 | "118.36.189.201", 225 | "121.157.194.44", 226 | "118.219.105.8", 227 | "ik1ne", 228 | "112.156.2.91", 229 | "210.179.98.189", 230 | "myanonnw", 231 | "kazuya0227", 232 | "73.9.103.38", 233 | "223.62.169.8", 234 | "121.127.84.236", 235 | "loked", 236 | "14.39.24.173", 237 | "jibril_lee", 238 | "natreebin", 239 | "zrwgy", 240 | "daressalaam", 241 | "211.106.189.139", 242 | "211.247.73.132", 243 | "219.254.86.110", 244 | "centercho", 245 | "115.139.63.189", 246 | "kibua20", 247 | "mechartist", 248 | "117.111.14.62", 249 | "ysggun", 250 | "115.140.219.171", 251 | "kaizer1028", 252 | "121.130.81.191", 253 | "1.249.134.85", 254 | "lht1324", 255 | "220.89.64.229", 256 | "secwind", 257 | "tripleh147", 258 | "r:daze3819", 259 | "122.36.104.189", 260 | "210.138.208.41", 261 | "pseudojo", 262 | "awesome", 263 | "61.74.89.239", 264 | "r:asdefary", 265 | "hided", 266 | "39.7.56.74", 267 | "angelbot", 268 | "211.52.193.38", 269 | "119.194.212.13", 270 | "dogyun0906", 271 | "1.238.216.12", 272 | "mswgen", 273 | "118.34.181.214", 274 | "carlos", 275 | "182.227.60.100", 276 | "116.42.180.231", 277 | "jhseo1107", 278 | "117.123.33.154", 279 | "116.67.26.128", 280 | "xhaser", 281 | "rbalsdldi", 282 | "youngplus31", 283 | "222.101.105.135", 284 | "211.219.154.133", 285 | "2du", 286 | "123.215.30.152", 287 | "jinski", 288 | "121.169.34.38", 289 | "prozect", 290 | "r:cbq", 291 | "41.73.7.108", 292 | "drod7429", 293 | "lulin_pollux", 294 | "119.202.86.70", 295 | "95.130.9.89", 296 | "182.221.33.142", 297 | "drago777", 298 | "genic", 299 | "221.151.251.185", 300 | "24.66.178.27", 301 | "118.34.159.136", 302 | "122.44.162.131", 303 | "165.132.144.164", 304 | "112.160.104.90", 305 | "murtin", 306 | "makerj", 307 | "58.236.166.34", 308 | "nargronus", 309 | "175.127.108.99", 310 | "crommune", 311 | "220.93.130.63", 312 | "say8425", 313 | "126.22.52.172", 314 | "210.178.183.175", 315 | "119.70.151.150", 316 | "125.135.167.145", 317 | "dontsaymyid", 318 | "hoya", 319 | "203.104.128.125", 320 | "222.232.180.49", 321 | "gyeonsil", 322 | "123.143.54.70", 323 | "58.228.56.97", 324 | "dlfwkflq", 325 | "accessable", 326 | "archshootr", 327 | "27.122.242.76", 328 | "173.70.53.126", 329 | "zeplin_y", 330 | "128.134.102.49", 331 | "112.161.64.225", 332 | "kghnkl0103", 333 | "175.212.99.237", 334 | "ranoma", 335 | "220.89.5.75", 336 | "175.121.118.43", 337 | "121.161.89.25", 338 | "222.100.64.108", 339 | "ruukkge", 340 | "nnsyc4906", 341 | "raon917", 342 | "125.179.238.97", 343 | "sura148", 344 | "hoejin88", 345 | "114.200.49.161", 346 | "222.120.77.154", 347 | "175.113.90.137", 348 | "125.142.117.68", 349 | "imaginedragoons", 350 | "175.201.166.127", 351 | "130.245.207.43", 352 | "61.72.95.133", 353 | "science", 354 | "kbumsik", 355 | "168.126.6.84", 356 | "211.223.188.220", 357 | "ssut", 358 | "kiwitree2", 359 | "bomoung79", 360 | "121.134.119.26", 361 | "183.97.197.41", 362 | "grakham", 363 | "118.175.155.156", 364 | "183.101.131.246", 365 | "namubot", 366 | "182.221.71.208", 367 | "211.209.90.163", 368 | "dhkim0800", 369 | "39.115.23.2", 370 | "66.249.82.244", 371 | "118.221.101.119", 372 | "nuerburgring", 373 | "61.75.27.205", 374 | "116.39.112.57", 375 | "14.46.253.39", 376 | "a3963409", 377 | "115.126.243.244", 378 | "112.154.54.156", 379 | "freaxtux", 380 | "hyunmyu", 381 | "kiwitree", 382 | "opskos", 383 | "58.120.75.105", 384 | "oc819", 385 | "godeer", 386 | "nasa010", 387 | "175.199.216.215", 388 | "harry9939", 389 | "14.32.45.90", 390 | "59.17.245.59", 391 | "int", 392 | "211.217.122.170", 393 | "rtyu1120", 394 | "183.96.134.33", 395 | "121.64.201.163", 396 | "ssangmun2", 397 | "61.102.73.205", 398 | "sizzflair97", 399 | "jaepilnim", 400 | "49.169.136.74", 401 | "125.132.199.173", 402 | "222.112.33.74", 403 | "221.155.149.49", 404 | "39.118.136.74", 405 | "kemo", 406 | "210.0.41.65", 407 | "47.23.149.58", 408 | "musoftware", 409 | "211.247.111.100", 410 | "117.16.196.138", 411 | "124.54.119.44", 412 | "210.222.42.158", 413 | "bluefairy", 414 | "konan8205", 415 | "simple0925", 416 | "116.120.166.236", 417 | "166.104.144.171", 418 | "124.55.8.72", 419 | "175.118.200.137", 420 | "jimmy1223", 421 | "royleejr", 422 | "piousness554", 423 | "sdynet", 424 | "samduk", 425 | "110.14.225.174", 426 | "membership20", 427 | "1.242.112.218", 428 | "121.168.139.226", 429 | "180.81.65.111", 430 | "dmscks2015", 431 | "175.121.118.83", 432 | "revery", 433 | "lgp5859", 434 | "meatloaf", 435 | "143.248.32.198", 436 | "1.251.62.6", 437 | "railgun", 438 | "wrsohn07", 439 | "1.227.231.196", 440 | "1.231.83.102", 441 | "49.50.0.178", 442 | "myh2910", 443 | "likejazz", 444 | "70.187.179.99", 445 | "183.107.37.56", 446 | "218.237.156.159" 447 | ] 448 | } 449 | --------------------------------------------------------------------------------