A Byte of Python


프로그래밍 2014-08-18 / 추천수 0 / 스크랩수 0 http://blog.chch.kr/smartcom/52883.html

"A Byte of Python" 은 무료로 제공되는 파이썬 프로그래밍 교재입니다.이 책은 파이썬을 처음 접하는 분들을 위한 튜토리얼 혹은 가이드의 역할을하도록 쓰여졌습니다. 컴퓨터로 텍스트 문서를 작성하고 저장할 줄만 알면충분합니다! 이 책은 바로 그런 분들을 위해 쓰여진 책입니다.

1. 책머리

1.1. 서평

아래는 독자들의 서평입니다:

This is the best beginner’s tutorial I’ve ever seen! Thank you for your effort.

The best thing i found was "A Byte of Python", which is simply a brilliant book for abeginner. It’s well written, the concepts are well explained with self evident examples.

Excellent gentle introduction to programming #Python for beginners

Best newbie guide to python

start to love python with every single page read

perfect beginners guide for python, will give u key to unlock magical world of python

I should be doing my actual "work" but just found "A Byte of Python". A great guide with greatexamples.

Recently started reading a Byte of python. Awesome work. And that too for free. Highly recommendedfor aspiring pythonistas.

A Byte of Python, written by Swaroop. (this is the book I’m currently reading). Probably the bestto start with, and probably the best in the world for every newbie or even a more experienced user.

Enjoying Reading #ByteOfPython by @swaroopch best book ever

Thank you so much for writing A Byte Of Python. I just started learning how to code two days agoand I’m already building some simple games. Your guide has been a dream and I just wanted to letyou know how valuable it has been.

* Franklin

I’m from Dayanandasagar College of Engineering (7th sem, CSE). Firstly i want to say that your book"The byte of python" is too good a book for a beginner in python like me.The concepts are so wellexplained with simple examples that helped me to easily learn python. Thank you so much.

* Madhura

I am a 18 year old IT student studying at University in Ireland. I would like to express mygratitude to you for writing your book "A Byte of Python", I already had knowledge of 3 programminglangagues - C, Java and Javascript, and Python was by far the easiest langague I have ever learned,and that was mainly because your book was fantastic and made learning python very simple andinteresting. It is one of the best written and easy to follow programming books I have everread. Congratulations and keep up the great work.

* Matt

Hi, I’m from Dominican Republic. My name is Pavel, recently I read your book A Byte of Python andI consider it excellent!! :). I learnt much from all the examples. Your book is of great help fornewbies like me…

I am a student from China, Now ,I have read you book A byte of Python, Oh it’s beautiful. The bookis very simple but can help all the first learnners. You know I am interesting in Java and cloudcomputing many times, i have to coding programm for the server, so i think python is a good choice,finish your book, i think its not only a good choice its must use the Python. My English is notvery well, the email to you, i just wanna thank you! Best Wishes for you and your family.

* Roy Lau

I recently finished reading Byte of Python, and I thought I really ought to thank you. I was verysad to reach the final pages as I now have to go back to dull, tedious oreilly or etc. manuals forlearning about python. Anyway, I really appreciate your book.

Dear Swaroop, I am taking a class from an instructor that has no interest in teaching. We are usingLearning Python, second edition, by O’Reilly. It is not a text for beginner without any programmingknowledge, and an instructor that should be working in another field. Thank you very much for yourbook, without it I would be clueless about Python and programming. Thanks a million, you are ableto break the message down to a level that beginners can understand and not everyone can.

I love your book! It is the greatest Python tutorial ever, and a very useful reference. Brilliant,a true masterpiece! Keep up the good work!

* Chris-Andr Sommerseth

I’m just e-mailing you to thank you for writing Byte of Python online. I had been attemptingPython for a few months prior to stumbling across your book, and although I made limited successwith pyGame, I never completed a program.

Thanks to your simplification of the categories, Python actually seems a reachable goal. It seemslike I have finally learned the foundations and I can continue into my real goal, game development.

Once again, thanks VERY much for placing such a structured and helpful guide to basic programmingon the web. It shoved me into and out of OOP with an understanding where two text books hadfailed.

I would like to thank you for your book A Byte of Python which i myself find the best way tolearn python. I am a 15 year old i live in egypt my name is Ahmed. Python was my second programminglanguage i learn visual basic 6 at school but didn’t enjoy it, however i really enjoyed learningpython. I made the addressbook program and i was sucessful. i will try to start make more programsand read python programs (if you could tell me source that would be helpful). I will also start onlearning java and if you can tell me where to find a tutorial as good as yours for java that wouldhelp me a lot. Thanx.

A wonderful resource for beginners wanting to learn more about Python is the 110-page PDF tutorialA Byte of Python by Swaroop C H. It is well-written, easy to follow, and may be the bestintroduction to Python programming available.

Yesterday I got through most of Byte of Python on my Nokia N800 and it’s the easiest and mostconcise introduction to Python I have yet encountered. Highly recommended as a starting point forlearning Python.

Byte of Vim and Python by @swaroopch is by far the best works in technical writing to me. Excellentreads #FeelGoodFactor

"Byte of python" best one by far man

(in response to the question "Can anyone suggest a good, inexpensive resource for learning thebasics of Python? ")

The Book Byte of python was very helpful ..Thanks bigtime :)

Always been a fan of A Byte of Python - made for both new and experienced programmers.

I started learning python few days ago from your book..thanks for such a nice book. it is so wellwritten, you made my life easy..so you found a new fan of yours..thats me :) tons of thanks.

Before I started to learn Python, I’ve acquired basic programming skills in Assembly, C, C++, C#and Java. The very reason I wanted to learn Python is it’s popular (people are talking about it)and powerful (reality). This book written by Mr. Swaroop is a very good guide for both brand-newprogrammers and new python programmers. Took 10 half days to go through it. Great Help!

Thank you ever so much for this book!!

This book cleared up many questions I had about certain aspects of Python such as object orientedprogramming.

I do not feel like an expert at OO but I know this book helped me on a first step or two.

I have now written several python programs that actually do real things for me as a systemadministrator. They are all procedural oriented but they are small by most peoples standards.

Again, thanks for this book. Thank you for having it on the web.

* Bob

I just want to thank you for writing the first book on programming I’ve ever really read. Python isnow my first language, and I can just imagine all the possibilities. So thank you for giving me thetools to create things I never would have imagined I could do before.

* The Walrus

I wanted to thank you for writing A Byte Of Python (2 & 3 Versions). It has been invaluable tomy learning experience in Python & Programming in general.

Needless to say, I am a beginner in the programming world, a couple of months of self study up tothis point. I had been using youtube tutorials & some other online tutorials including other freebooks. I decided to dig into your book yesterday, & I’ve learned more on the first few pages thanany other book or tutorial. A few things I had been confused about, were cleared right up with aGREAT example & explanation. Can’t wait to read (and learn) more!!

Thank you so much for not only writing the book, but for putting it under the creative commonslicense (free). Thank goodness there are unselfish people like you out there to help & teach therest of us.

* Chris

I wrote you back in 2011 and I was just getting into Python and wanted to thank you for yourtutorial "A Byte of Python". Without it, I would have fallen by the wayside. Since then I havegone on to program a number of functions in my organization with this language with yet more on thehorizon. I would not call myself an advanced programmer by any stretch but I notice the occasionalrequest for assistance now from others since I started using it. I discovered, while reading"Byte" why I had ceased studying C and C++ and it was because the book given to me started out withan example containing an augmented assignment. Of course, there was no explanation for thisarrangement of operators and I fell on my head trying to make sense of what was on the writtenpage. As I recall it was a most frustrating exercise which I eventually abandoned. Doesn’t mean Cor C++ is impossible to learn, or even that I am stupid, but it does mean that the documentation Iworked my way through did not define the symbols and words which is an essential part of anyinstruction. Just as computers will not be able to understand a computer word or computer symbolthat is outside the syntax for the language being used, a student new to any field will not grasphis subject if he encounters words or symbols for which there are no definitions. You get a "bluescreen" as it were in either case. The solution is simple, though: find the word or symbol and getthe proper definition or symbol and lo and behold,the computer or student can proceed. Your bookwas so well put together that I found very little in it I couldn’t grasp. So, thank you. Iencourage you to continue to include full definitions of terms. The documentation with Python isgood, once you know, (the examples are its strength from what I see) but in many cases it seemsthat you have to know in order to understand the documentation which to my mind is not whatshould be. Third party tutorials express the need for clarification of the documentation and theirsuccess largely depends on the words that are used to describe the terminology. I have recommendedyour book to many others. Some in Australia, some in the Caribbean and yet others in the US. Itfills a niche no others do. I hope you are doing well and wish you all the success in the future.

* Nick

hey, this is ankush(19). I was facing a great difficulty to start with python. I tried a lot ofbooks but all were bulkier and not target oriented; and then i found this lovely one, which made melove python in no time. Thanks a lot for this "beautiful piece of book".

* Ankush

I would like to thank you for your excellent guide on Python. I am a molecular biologist (withlittle programming background) and for my work I need to handle big datasets of DNA sequences andto analyse microscope images. For both things, programming in python has been useful, if notessential to complete and publish a 6-years project.

That such a guide is freely available is a clear sign that the forces of evil are not yet rulingthe world! :)

* Luca

Since this is going to be the first language you learn, you should use A Byte of Python. It reallygives a proper introduction into programming in Python and it is paced well enough for the averagebeginner. The most important thing from then on will be actually starting to practice making yourown little programs.

Just to say a loud and happy thank you very much for publishing "A Byte of Python" and "A Byte ofVim". Those books were very useful to me four or five years ago when I starting learningprogramming. Right now I’m developing a project that was a dream for a long, long time and justwant to say thank you. Keep walking. You are a source of motivation. All the best.

* Jocimar

Finished reading A byte of Python in 3 days. It is thoroughly interesting. Not a single page wasboring. I want to understand the Orca screen reader code. Your book has hopefully equipped mefor it.

* Dattatray

Hi, A byte of python is really a good reading for python beginners. So, again, NICE WORK!

i’m a 4 years experienced Java&C developer from China. Recently, i want to do some work on zim-wikinote project which uses pygtk to implement.

i read your book in 6 days, and i can read and write python code examples now.thx for your contribution.plz keep your enthusiasm to make this world better, this is just a little encourage from China.Your readerLee

* LEE

이 책은 NASA에서도 읽혀지고 있습니다!제트 추진 연구소(Jet PropulsionLaboratory) 의 Deep Space Network 프로젝트에서 이용되고 있습니다.

1.2. 수업 교재

이 책은 다음과 같은 교육 기관에서 교재로 이용되었거나, 이용되고 있습니다.

1.3. 권리 및 권한

이 책은 Creative CommonsAttribution-ShareAlike 4.0 International License 허가서 아래에 배포됩니다.

이것은 당신이 다음의 권리를 갖는 것을 뜻합니다:

  • 이 책의 복제, 배포, 전시, 공연 및 공중송신을 할 수 있습니다.

  • 이 책을 개작, 수정하거나 이차저작물을 작성할 수 있습니다 (특히 번역판을 제작할 수 있습니다).

  • 이 책을 영리 목적으로 이용할 수 있습니다.

다음의 내용을 숙지해주시기 바랍니다:

  • 이 책의 전자책/출력본을 판매하실 경우, 명백하고 눈에 잘 띄는 방법으로 이 책의 원 저자로부터 판매되는 것이 아님을 명시하지 않는 한이 책을 판매하실 수 없습니다.

  • 이러한 권리에 관련된 내용은 반드시 책의 도입부에 적혀 있어야 하며,이 문서의 첫 페이지에는 http://swaroopch.com/notes/python 로 연결되는 링크가 반드시 있어야 하고,원 저자의 글을 이 곳에서 내려받을 수 있다는 사실을 명시해야 합니다.

  • 따로 명시되어 있지 않는 한, 이 책에서 사용된 모든 코드 및 스크립트는3-clause BSD License아래에 배포됩니다.

1.4. 책을 읽으세요!

http://swaroopch.com/notes/python (영문) 또는 http://byteofpython-korean.sourceforge.net/byte_of_python.html (한글) 에서 이 책을 온라인으로 읽으실 수 있습니다.

1.5. 책 구입하기

종이 책을 좋아하시는 분들, 혹은 이 책의 발전과 개선을 위해 도움을 주시려는 분들께서는이 책의 하드카피 출력본을 http://swaroopch.com/buybook 에서 구입할 수 있습니다.

1.6. 내려받기

이 책의 지속적인 발전을 바라신다면, http://swaroopch.com/buybook 에서 책을 구입하시는 것을 고려해 주세요.

1.7. 번역본 읽기

이 책의 번역본을 읽고 싶으신 분들, 혹은 이 책을 번역하는데 도움을 주시려는 분은번역 챕터를 읽어 주세요.

2. 헌정

이 책을 저희를 GNU/Linux, 그리고 오픈 소스의 세계로 이끌어주신Kalyan Varma, 그리고 PESIT의 다른 많은 분들께 바칩니다.

또한 좋은 친구이자 스승이 되어주셨던, 그리운 고 Atul Chitnis를 기억하며 이 책을 바칩니다.

마지막으로 지금의 인터넷을 탄생시킨 주역들에게 이 책을 바칩니다. 이 책은 2003년도에 처음으로 작성되었습니다만, 여전히 많이 읽히고 있습니다. 이것은 바로 이들이 개척해 왔던 지식의 공유 정신 덕분입니다.

3. 서문

파이썬은 간단하면서도 강력하다고 할 수 있을만한 몇 안되는 프로그래밍 언어들 중 하나일 것입니다.파이썬은 초보자와 숙련자에게 모두 유용한 언어이며, 또 파이썬 프로그래밍은 즐겁습니다.이 책은 여러분이 파이썬이라는 아름다운 프로그래밍 언어를 배울 수 있도록 돕고,여러분이 하고자 하는 일을 빠르고 쉽게 해결하는 방법을 보여드리는 것을 목적으로 작성되었습니다.

3.1. 이 책은 누가 읽으면 좋을까요?

이 책은 파이썬의 가이드 혹은 튜토리얼의 역할을 하도록 작성되었습니다.프로그래밍에 대해 아무런 지식이 없는 완전 초보자들을 주 독자로 설정하였습니다.물론 경험이 많은 프로그래머들에게도 유용한 책입니다.

이 책의 목표는 컴퓨터로 텍스트 문서를 저장하는 것밖에 모르는 사람도 이 책을 통해파이썬을 배울 수 있도록 하는 것입니다. 물론 여러분이 이전에 프로그래밍 경험이 있다고 하더라도이 책을 통해 파이썬을 익힐 수 있을 것입니다.

만약 여러분이 전에 프로그래밍을 해 본 경험이 있다면, 아마도 여러분은 여러분이 가장 좋아하는 언어와 파이썬이어떻게 다른지에 대해 관심이 있을 것입니다. 저는 이 책에서 다른 언어와 파이썬과의 많은 차이점을 강조해 두었습니다.하지만 주의하세요, 얼마 안 지나서 여러분이 가장 좋아하는 언어는 파이썬이 될 것입니다!

3.2. History Lesson

제가 파이썬을 처음 시작하게 된 계기는 전에 작성했던 Diamond 라는 소프트웨어를 좀 더 쉽게 설치할수 있게 하기 위해 그것의 설치 프로그램을 작성하려고 했던 일이었습니다. 당시에 Qt 라이브러리를사용하고 싶었는데, 이를 위해 파이썬과 펄 중 하나를 골라야 했었지요. 그래서 인터넷을 찾아보았는데유명한 해커 Eric S. Raymond 가 쓴 글을 발견하게 되었습니다.거기에는 파이썬이 어떻게 자신이 가장 좋아하는 프로그래밍 언어가 되었는지에 대해 적혀 있었지요.또한 당시 Perl-Qt 바인딩에 비해 PyQt 바인딩이 좀 더 안정적이었기도 해서, 저는 파이썬을 선택하게되었습니다.

다음으로 저는 좋은 파이썬 책이 있는지 찾아보기 시작했습니다. 그런데, 아무것도 찾을 수가 없었습니다!몇 권의 오라일리(O’Reilly) 책을 찾았지만 이것들은 너무 비싸고 초보자를 위한 가이드이기보다는 레퍼런스매뉴얼에 가까웠습니다. 그래서, 저는 파이썬 문서를 검색해보기 시작했습니다. 그렇지만 제가 찾은 것들은너무 간략하거나 짧은 것들 뿐이었습니다. 저는 이런 문서들을 통해 기본적인 것들에 대한 도움을 받을 수있었지만 파이썬에 대해 완전히 알 수는 없었습니다. 또 저는 프로그래밍을 전에 해 보았기 때문에 이런짧은 문서들을 겨우겨우 이해해나갈 수 있었지만, 초보자에게는 불가능한 일이라는 것도 알게 되었습니다.

제가 파이썬을 처음 시작하고 6 개월정도 지난 뒤, 저는 레드햇 리눅스(Red Hat Linux) 9.0 을 설치하였는데불현듯 KWord를 사용하여 파이썬에 대해 뭔가 적어보자는 생각이 떠올랐습니다. 처음에는 몇 장으로시작했지만 곧 30 페이지 정도의 문서가 되었습니다. 그렇게 되니 좀 더 내용을 정리해서 책의 형태로만들면 좀 더 유용하겠다는 생각을 했습니다. 그 후 많은 재작성 끝에, 파이썬이라는 언어를 익히는데 유용한 현재의 가이드를 만들 수 있었습니다. 저는 이 책이 저의 기여로 만들어졌지만 오픈 소스공동체에 기여할 수 있기를 바랍니다.

이 책은 파이썬에 대한 저의 개인 노트에서 출발했고, 앞으로도 같은 방식으로 편집될 것입니다.물론 다른 사람들이 이 책을 읽기 쉽게 하기 위한 노력 또한 계속 기울일 것이고요 :)

또 오픈 소스 정신 안에서, 많은 열정적인 독자들의 제안과 비평 그리고 피드백을 통해 이 책이 지금까지 성장할 수 있었음을 알립니다.

3.3. 변경 기록

  • 이 책은 2014년 3월 ~ 4월 사이에 마지막으로 변경되었으며,Emacs 24adoc-mode 를 이용하여Asciidoc 으로 변환되었습니다.

  • 2008년에 이 책은 파이썬 3.0 에 대응하도록 변경되었습니다만 (당시 3.0 에 대응하는 몇 안되는 책 중하나였습니다), 현재는 다시 파이썬 2에 대응하도록 변경되었습니다. 그 이유는 자신의시스템에 기본으로 설치되어 있는 파이썬 2와 직접 설치하고 설정해야 하는 파이썬 3 사이에서혼란을 겪는 독자들이 많았기 때문인데, 이는 새로 설치한 파이썬을 설정하는 과정을 설명하는여러 다른 문서들이 파이썬 2를 기준으로 작성되어 있기 때문입니다. 그래서 저는 괜히 파이썬 3을 고집해서독자들을 괴롭히고 있는 것은 아닌가 하는 고민에 빠졌고 또 파이썬 2 나 3 중 하나만잘 배워 두어도 독자들에게는 충분히 유용할 수 있다는 생각에, 다시 파이썬 2를 선택하게 되었습니다.

이 책은 여러분과 같은 독자들의 도움이 필요합니다. 책을 읽다가 설명이 좋지 않거나, 부족하거나 또는잘못된 부분이 있다면 지적해 주시기 바랍니다. 코멘트나 제안이 있으실 경우 이 책의 저자역자 에게 연락해 주시기 바랍니다.

3.4. 공식 홈페이지

이 책의 공식 홈페이지는 http://swaroopch.com/notes/python 이며 여기서 이 책을 온라인으로 읽으실 수 있고, 최신 버전의 책을내려받을 수 있으며 책을 구매하거나 피드백을 남길 수 있습니다.

3.5. 생각할 것들

소프트웨어를 설계하는 데에는 두 가지 방법이 있습니다. 하나는 설계를 굉장히 간단하게 하여서 결함이없도록 하는 것입니다. 또 하나는 설계를 아주 완벽하게 하여 결함이 있을 수 없도록 하는 것입니다.

(There are two ways of constructing a software design: one way is to make it so simple that thereare obviously no deficiencies; the other is to make it so complicated that there are no obviousdeficiencies.)

? C. A. R. Hoare

삶에 있어 성공이라고 하는 것은 재능과 요행보다는 집중력과 참을성에 달려 있습니다.

(Success in life is a matter not so much of talent and opportunity as of concentration andperseverance.)

? C. W. Wendte

4. 소개

파이썬은 간단하면서도 강력하다고 할 수 있을만한 몇 안되는 언어들 중 하나라고 할 수 있을 것입니다.곧 여러분은 문제를 해결하는데 파이썬이라는 언어의 문법과 구조에 별로 신경쓰지 않고도문제를 푸는것 자체에 쉽게 집중할 수 있다는데 놀라게 될 것입니다.

다음은 파이썬의 공식 소개글입니다.

파이썬은 배우기 쉽고, 강력한 프로그래밍 언어입니다.파이썬은 효율적인 고수준 데이터 구조를 갖추고 있으며,간단하지만 효과적인 객체 지향 프로그래밍 접근법 또한 갖추고 있습니다.우아한 문법과 동적 타이핑, 그리고 인터프리팅 환경을 갖춘 파이썬은다양한 분야, 다양한 플랫폼에서 사용될 수 있는 최적의 스크립팅,RAD(rapid application development - 빠른 프로그램 개발) 언어입니다.

다음 섹션에서 이러한 파이썬의 특징에 대해 상세히 다룰 것입니다.

파이썬이라는 이름의 유래

파이썬의 창시자 귀도 반 로섬(Guido van Rossum)이 BBC에서 방영되던"Monty Python’s Flying Circus"라는 TV 프로그램의 이름을 따서 지었습니다.사실 귀도는 뱀이라는 긴 몸으로 다른 동물의 몸을 휘감아 으깨어 부수고 먹어치우는동물을 딱히 좋아하지는 않는다고 합니다.

4.1. 파이썬의 특징

단순함

파이썬은 단순하고 최소화된 언어입니다. 잘 쓰여진 파이썬 프로그램을 읽는 것은좀 딱딱하게 쓰여진 영어 문장을 읽는 것과 크게 다르지 않습니다!이러한 프로그램 코드같지 않아 보이는 특성은 파이썬의 가장 강력한 특성들 중 하나입니다.이로 인해 파이썬이라는 언어 자체보다 여러분이 풀고자 하는 문제에 더 쉽게 집중할 수 있습니다.

배우기 쉬운 언어

곧 알게 되시겠지만, 파이썬은 정말 배우기 쉬운 언어입니다.위에서 이미 이야기했지만, 파이썬은 굉장히 쉬운 문법 체계를 갖고 있습니다.

자유, 오픈 소스 소프트웨어

파이썬은 FLOSS (Free/Libr? and Open Source Software - 자유, 오픈 소스 소프트웨어)의 좋은 예입니다.이것은 이 소프트웨어의 복사본을 마음대로 배포할 수 있고, 소스 코드가 공개되어 있어 언제든지 읽을 수 있으며,필요한 부분을 고칠 수 있고, 새로운 자유 소프트웨어를 작성할 때 이 프로그램의 일부를 사용해도 된다는 것을 의미합니다.FLOSS는 지식을 공유하는 공동체를 기반으로 하고 있습니다.이것은 왜 파이썬이라는 언어가 이렇게 좋은 언어가 되었는지를 설명하는 좋은 이유입니다.파이썬은 좀 더 나은 파이썬을 만들고자 하는 공동체의 노력에 의해 지속적으로 개선되고 있기 때문입니다.

고수준 언어

여러분이 파이썬으로 프로그램을 작성할 때,메모리를 관리한다던가 하는 저수준의 세부적인 사항들을 신경쓸 필요가 없습니다.

이식성

파이썬은 소스가 공개되어 있으므로, 여러 플랫폼을 지원하도록 수정되어 왔습니다.따라서 여러분이 프로그램을 작성할 때 특정 플랫폼에서만 사용되는 몇몇 기능들을 사용하지 않으면,작성한 모든 파이썬 프로그램은 어떤 수정 없이도 파이썬이 동작하는 모든 플랫폼 위에서 동작할 수 있습니다.

파이썬은 GNU/Linux(리눅스), Windows(윈도우즈), FreeBSD, Macintosh(맥킨토시), Solaris(솔라리스),OS/2, Amiga(아미가), AROS, AS/400, BeOS, OS/390, z/OS, Palm OS(팜 OS), QNX, VMS, Psion,Acorn RISC OS, VxWorks, PlayStation(플레이스테이션), Sharp Zaurus(샤프 자우르스), Windows CE(윈도우즈 CE),PocketPC(포켓 PC) 상에서 동작합니다.

혹은 Kivy 와 같은 플랫폼을 활용하면,여러분의 컴퓨터 iPhone, iPad, Android상에서 동작하는 게임을 제작할 수도 있습니다.

인터프리터 언어

이 부분은 설명이 조금 필요합니다.

컴파일러 언어인 C 혹은 C++로 작성된 프로그램은 컴파일러에 여러 옵션과 플래그를 주어프로그래머가 작성한 소스 코드로부터 컴퓨터가 사용하는 언어 (0과 1로 구성된 바이너리 코드)로번역하게 하는 과정을 거칩니다.이렇게 번역된 프로그램을 실행하면, 링커 또는 로더라고 불리우는 소프트웨어가 프로그램을 하드 디스크로부터 메모리로 불러들인 후프로그램을 실행하게 됩니다.

반면에 파이썬은 이러한 컴파일 과정을 필요로 하지 않습니다.파이썬 프로그램은 파이썬으로 된 소스 코드로부터 곧바로 실행됩니다.이때 파이썬은 내부적으로 실행되는 소스 코드를 바이트코드라고 불리우는 중간 단계의 형태로 변환한 후,이것을 다시 여러분의 컴퓨터가 사용하는 언어로 변환한 다음 실제로 실행하게 됩니다.사실 이 모든 과정은, 여러분이 컴파일이라는 과정을 신경쓰지 않고서도,즉 여러분이 필요한 라이브러리를 갖고 있는지 링크가 잘 되었는지 잘 로드 되었는지 등을 신경쓰지 않고서도파이썬을 쉽게 사용할 수 있게 해 줍니다.또한 이 특성은 여러분이 작성한 파이썬 프로그램이 여러 플랫폼에서 잘 동작하게 해 주므로,다른 컴퓨터에 프로그램을 단순히 복사하기만 해도 곧바로 잘 동작하게 됩니다!

객체 지향 언어

파이썬은 절차 지향 프로그래밍 및 객체 지향 프로그래밍을 지원합니다.절차 지향 언어에서는, 프로그램은 프로시저 또는 함수들로 구성되는데이것들은 단순히 프로그램에서 많이 재사용되는 코드 조각들을 의미합니다.반면 객체 지향 언어에서는, 프로그램은 객체로 구성되어 있는데 객체란데이터와 기능이 결합된 하나의 대상을 의미합니다.파이썬은 특히 C++이나 Java와 같은 언어들에 비해 매우 강력하고도 쉬운 방법으로 객체 지향을 지원합니다.

확장성

만약 여러분이 작성해야 하는 프로그램의 일부분이 빠른 속도로 동작해야 하거나 혹은알고리즘의 일부를 공개하고 싶지 않은 경우, 코드의 일부분을 C 혹은 C++로 작성한 후파이썬 프로그램에서 읽어들여 사용하도록 할 수 있습니다.

포함성

여러분의 C/C++ 프로그램에 파이썬을 포함하도록 하여 여러분의 프로그램을 사용하는 사용자들이스크립팅 기능을 사용하도록 할 수 있습니다.

확장 가능한 라이브러리

파이썬은 방대한 표준 라이브러리를 갖추고 있습니다. 여기에는 정규 표현식,자동 문서 생성, 유닛 테스트, 쓰레딩, 데이터베이스, 웹 브라우저, CGI, FTP, 전자메일, XML,XML-RPC, HTML, WAV 파일, 암호화 알고리즘, GUI (graphical user interfaces) 등등이 들어 있으며,여러 시스템 관련 기능들 또한 포함되어 있습니다. 이러한 기능들은 파이썬이설치되어 있는 어떤 시스템에서든지 사용 가능하다는 점을 기억하세요.

이러한 표준 라이브러리 외에도, 파이썬 패키지 인덱스(Python Package Index)에 다양한 라이브러리가 공개되어 있습니다.

요약

파이썬은 흥미진진하고 강력한 언어입니다. 파이썬의 빠른 성능과 여러 기능들의 조화는여러분이 재미있고 쉽게 파이썬으로 프로그램을 작성할 수 있도록 해 줍니다.

4.2. 파이썬 2 vs 3

만약 여러분이 파이썬 2와 3의 차이에 대해 큰 관심이 없으시다면 이 섹션을 무시하셔도 좋습니다.그렇지만 여러분이 어떤 버전의 파이썬을 사용하고 있는지는 알고 계시는 것이 좋습니다.

일단 어느 한 쪽이든지 적절히 이해하고 사용하는 방법을 익히고 나면,여러분은 두 버전의 차이점을 쉽게 배울 수 있고 두 버전 모두 쉽게 사용할 수 있다는 점을 기억하세요.어려운 부분은 프로그래밍이라는 것을 배우고 파이썬 언어의 원리를 이해하는 것입니다.이것이 바로 이 책의 목표이며, 이 목표를 달성하고 나면여러분이 처한 상황에 따라 파이썬 2나 3 모두 쉽게 사용할 수 있게 될 것입니다.

파이썬 2와 파이썬 3의 차이점에 대해 자세하게 알고 싶으시다면 다음을 참조하세요:

4.3. 프로그래머들이 말하는 파이썬

ESR(Eric S. Raymond)과 같은 위대한 해커들이 파이썬을 뭐라고 표현했는지 알아보세요:

  1. Eric S. Raymond 는 "성당과 시장(The Cathedral and the Bazaar)" 의 저자이며, 또한오픈 소스(Open Source) 라는 단어의 창시자입니다. 그는 어떻게파이썬이 자신이 가장 좋아하는 언어가 되었는지에 대한 글을 남겼습니다. 또 이 글은 제가 파이썬을처음 시작하게 된 계기가 된 글이기도 합니다.

  2. Bruce Eckel 은 유명한 책 Thinking in JavaThinking in C++ 의 저자입니다. 그는파이썬이 아닌 다른 어떤 언어도 그가 파이썬을 사용할 때만큼 생산적이도록 하지 못했다고 말합니다.또 그는 프로그래머에게 있어서 문제를 쉽게 해결하는 데 초점을 맞추는 언어는 아마도 파이썬이 유일하지않을까 라는 말도 남겼습니다. 좀 더 자세한 사항은 인터뷰 전문을 읽어 보세요.

  3. Peter Norvig 은 유명한 Lisp 프로그래머이며 또 구글의 검색 품질 책임자 로 일하고 있습니다(이것을 지적해준 귀도 반 로섬에게 감사드립니다). 그는파이썬으로 프로그래밍 하는 것은 마치 의사코드로 프로그램하는 것 같다고말합니다. 그는 또한 파이썬은 언제나 구글의 가장 중요한 부분을 담당하고 있다는 사실도 밝혀 주었습니다.이에 대해서는 여러분이 직접 구글 채용(Google Jobs) 페이지에 방문해 보시면소프트웨어 엔지니어로 채용되는 조건에 파이썬에 대한 지식이 필수 사항으로 되어 있는 것을 확인해보실 수 있습니다.

5. 설치

이 책에서 "파이썬 2" 라고 부르는 것은, 파이썬 버전 2.7이상의모든 버전을 의미합니다.

5.1. 윈도우 환경에서의 설치

https://www.python.org/downloads/ 에 방문하셔서 최신 버전의 설치 프로그램을 내려받아 설치하세요.설치 방법은 다른 소프트웨어를 설치 할 때와 같습니다.

주의: 혹시 설치 도중 기본으로 설치하도록 표시된 "추가 기능"을 선택하지 않을 것인지 물어도,선택을 해제하지 말아 주세요.

5.1.1. 명령 프롬프트에서 사용하기

여러분이 파이썬을 윈도우의 명령 프롬프트 (DOS 프롬프트) 상에서 사용하고 싶으시다면,PATH 환경 변수를 알맞게 설정해 주어야 합니다.

윈도우 2000, XP, 2003의 경우, <code>제어판</code> → <code>시스템</code> → <code>고급</code> → <code>환경 변수</code>로 들어가세요.이제 시스템 변수 목록에 있는 <code>PATH</code>를 선택한 뒤, <code>편집</code> 버튼을 누르고 <code>;C:\Python27</code>(이 폴더가 실제로 존재하는지 다시 한번 확인하세요. 더 최신 버전의 파이썬을 설치한 경우 폴더 이름이 다를 수 있습니다)이라는 문자열을 이미 있던 문자열의 맨 뒤에 추가하세요.물론 이 경로는 올바르게 지정된 디렉토리이어야 합니다.

그 이전 버전의 윈도우를 사용하시는 분들은, <code>C:\AUTOEXEC.BAT</code>를 열고 맨 뒷줄에<code>PATH=%PATH%;C:\Python27</code> 이라고 마지막에 한 줄 추가한 뒤시스템을 재시작하세요. 윈도우 NT의 경우, <code>AUTOEXEC.NT</code> 파일을 편집하세요.

윈도우 비스타:

  1. 시작 메뉴를 클릭하고, <code>제어판</code>을 클릭하세요.

  2. <code>시스템</code>을 클릭하면, 오른쪽에 "컴퓨터에 대한 기본 정보 보기" 창이 보일 것입니다.

  3. 왼쪽에는 <code>작업</code> 항목 아래 여러 메뉴들이 있는데, 이 중 "고급 시스템 설정" 항목이 보일 것입니다. 이것을 클릭하세요.

  4. 그러면 시스템 속성 대화상자의 고급 탭이 보이게 됩니다. 오른쪽 아래에 있는 환경 변수 버튼을 클릭하세요.

  5. 아래쪽의 "시스템 변수"라고 적혀 있는 목록에 있는 <code>PATH</code>항목을 선택하고, 편집 버튼을 클릭하세요.

  6. 경로를 수정하세요.

  7. 시스템을 재시작하세요. 윈도우 비스타는 컴퓨터가 재시작되기 전까지 새로 지정한 환경 변수가 적용되지 않습니다.

윈도우 7:

  1. 바탕 화면에 있는 <code>컴퓨터</code>를 오른쪽 클릭하고, <code>속성</code>을 클릭하시거나,또는 시작 메뉴를 클릭하고 제어판을 선택한 뒤, <code>시스템 및 보안</code>의 <code>시스템</code>을 클릭하세요.화면 왼쪽에 보이는 <code>고급 시스템 설정</code> 항목을 클릭한 뒤,고급 탭을 클릭하세요. 아래쪽에 보이는 <code>시스템 변수</code> 밑에 있는 여러 변수들 중 PATH라는 변수를 찾아 선택한 뒤,편집 버튼을 누르세요.

  2. 이미 있던 문자열의 맨 끝에 <code>;C:\Python27</code> 을 추가하세요.

  3. 만약 원래 있던 문자열이 <code>%SystemRoot%\system32;</code>였다고 한다면,변경된 문자열은 <code>%SystemRoot%\system32;C:\Python27</code> 이어야 합니다.

  4. <code>확인</code> 버튼을 누르면 시스템을 재시작하지 않아도 곧바로 적용됩니다.

5.1.2. 윈도우 환경에서의 파이썬 실행

PATH 환경변수가 제대로 설정되어 있다면,파이썬 인터프리터를 명령 프롬프트 상에서도 실행하실 수 있습니다.

윈도우 환경에서 터미널 창을 열기 위해서는, 시작 메뉴를 누르고 <code>실행</code> 버튼을 클릭하세요.나타나는 대화상자에 <code>cmd</code>를 입력하시고 <kbd>enter</kbd> 키를 입력하세요.

이제, <code>python</code>을 입력하고 파이썬 프롬프트가 잘 실행되는지 확인하세요.

5.2. Mac OS X 에서의 설치

Mac OS X 사용자의 경우, 파이썬이 이미 설치되어 있을 것입니다.

확인하시려면, 먼저 <kbd class="keyseq"><kbd>Command</kbd>+<kbd>Space</kbd></kbd> 키를 입력하여 Spotlight 검색 창을 여세요.그리고 <code>Terminal</code>이라 입력하시고 <kbd>enter</kbd> 키를 누르세요.이제, <code>python</code>을 입력하고 문제가 없는지 확인하세요.

5.3. GNU/Linux 에서의 설치

GNU/Linux 사용자의 경우, 파이썬이 이미 설치되어 있을 것입니다.

확인하시려면, <code>터미널</code> 프로그램을 열거나 혹은 <kbd class="keyseq"><kbd>Alt</kbd>+<kbd>F2</kbd></kbd> 키를 입력한 뒤 <code>gnome-terminal</code>을 입력하여 터미널을 실행하세요.만약 이 두 방법으로 터미널을 실행시킬 수 없으면, 여러분이 설치한 리눅스 배포판의 설명서를 참조하세요.이제, <code>python</code>을 입력하고 문제가 없는지 확인하세요.

다음과 같이 입력하면 시스템에 설치된 파이썬의 버전을 확인할 수 있습니다.

$ python -VPython 2.7.6
Note
<code>$</code> 는 쉘의 프롬프트를 의미합니다. 이것은 여러분의 컴퓨터에 설치된 운영 체제의 설정에 따라 바뀔 수 있습니다만,이 책에서는 <code>$</code> 로 통칭하도록 하겠습니다.
Caution
컴퓨터에 설치된 파이썬 버전에 따라 결과가 조금씩 다를 수 있습니다.

5.4. 요약

이제 여러분의 시스템에 파이썬이 올바르게 설치된 것으로 간주하도록 하겠습니다.

다음 챕터에서, 우리의 첫번째 파이썬 프로그램을 작성해 봅시다.

6. 첫 걸음

이제 유명한 Hello World 프로그램을 파이썬으로 어떻게 실행하는지 배워보도록 하겠습니다.이를 통해 파이썬 프로그램을 어떻게 작성하고, 저장하고, 실행하는지를 배우게 될 것입니다.

파이썬에서 프로그램을 실행하는 방법은 두 가지가 있습니다.첫째는 대화형 인터프리터 프롬프트를 이용하는 방법과, 둘째는 소스 파일을 이용하는 것입니다.지금부터 두 방법 모두 알아보도록 하겠습니다.

6.1. 인터프리터 프롬프트에서의 실행

여러분이 설치한 운영 체제에서 제공되는 터미널을 실행하세요(실행하는 방법은 설치챕터를 참조하세요). 그리고 <code>python</code> 이라 입력한 뒤 <kbd>enter</kbd> 키를 눌러 인터프리터 프롬프트를 엽니다.

파이썬 프롬프트가 시작되면 <code>>>></code> 이라는 문자열이 보이는데 이것은 여러분이 원하는 파이썬 명령을 입력할 수 있는 상태임을 뜻합니다.이것을 우리는 파이썬 인터프리터 프롬프트라 부릅니다.

파이썬 인터프리터 프롬프트에서 다음을 입력하세요:

<code class="python language-python">print "Hello World"</code>

<kbd>enter</kbd> 키를 입력하면, <code>Hello World</code> 라는 문자열이 화면상에 출력됨을 확인하실 수 있을 것입니다.

다음은 여러분이 Mac OS X 컴퓨터를 이용하고 있을 경우 보일 것으로 예상되는 예제 화면입니다.화면에 보이는 파이썬 프로그램에 대한 세부 사항은 컴퓨터에 따라 조금씩 다를 수 있습니다만,프롬프트로부터 보이는 부분 (<code>>>></code> 이후로 보이는 부분)은 여러분이 어떤 운영 체제를 이용하든지 동일할 것입니다.

$ pythonPython 2.7.6 (default, Feb 23 2014, 16:08:15)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> print "hello world"hello world>>>

파이썬은 여러분이 입력한 것에 대한 결과물을 곧바로 출력해준다는 점에 유의하세요!방금 여러분이 입력한 것은 하나의 파이썬 명령 입니다. 우리는 방금 <code>print</code> 를 이용하여 여기에 넘겨준 값을 출력하도록 한 것입니다.다시 말하면 <code>Hello world</code>라는 문자열을 <code>print</code> 에 넘겨 주었고, 이 결과가 곧바로 화면에 출력된 것입니다.

Note
인터프리터 프롬프트를 종료하는 방법

여러분이 현재 GNU/Linux 혹은 Unix 쉘을 이용하는 중이라면,<kbd class="keyseq"><kbd>ctrl</kbd>+<kbd>d</kbd></kbd> 를 누르거나 <code>exit()</code> 를 입력하여 프롬프트를 종료할 수 있습니다.(주의: <kbd>enter</kbd> 키를 입력하기 전에 exit 뒤에 괄호 <code>()</code>를 붙였다는 점을 잊지 마세요)

만약 여러분이 윈도우 명령 프롬프트를 이용하는 중이라면, <kbd class="keyseq"><kbd>ctrl</kbd>+<kbd>z</kbd></kbd> 키를 누르고 <kbd>enter</kbd> 키를 입력하여프롬프트를 종료할 수 있습니다.

6.2. 편집기 선택하기

여러분이 파이썬 프로그램을 실행할 때마다 인터프리터 프롬프트를 실행하고 프로그램을 입력할 수는 없는 노릇입니다.따라서 프로그램을 파일로 저장해 두면, 원하는 만큼 언제든지 실행만 하면 되니 편리하겠죠.

파이썬 소스 코드 파일을 만들기 위해서는, 우선 글자를 입력할 수 있고 저장할 수 있는 편집기 프로그램이 필요합니다.좋은 프로그래머들이 사용하는 편집기에는 소스 파일을 쉽게 작성할 수 있도록 돕는 여러 기능이 갖추어져 있습니다.따라서 좋은 편집기를 고르는 것은 정말로 중요한 일입니다. 편집기를 고르는 것은 마치 여러분이 어떤 자동차를구입할지 고르는 과정과도 같습니다. 좋은 편집기는 파이썬 프로그램을 쉽게 작성할 수 있도록 도와 주고,여러분이 앞으로 떠날 여정을 좀 더 편리하게, 원하는 목적지에 닿을 때까지 (목표를 달성할 때까지) 더 빠르고안전한 길로 안내할 것입니다.

가장 기초적인 필수 기능은 문법 강조 기능입니다. 이 기능은 여러분이 작성한 파이썬 프로그램의 각 부분을여러가지 다른 색깔로 표시해주어 여러분이 프로그램을 쉽게 파악하고 어떻게 실행되는지 알 수 있도록 돕습니다.

만약 어떤 편집기를 선택할 지 잘 모르겠으면, 저는 Light Table 을 이용할 것을추천합니다. 이 소프트웨어는 윈도우, Mac OS X, GNU/Linux에서 모두 사용이 가능합니다.더 자세한 사항은 다음 섹션에서 다루겠습니다.

혹시 여러분이 윈도우 사용자라면, 절대로 메모장을 사용하지 말아 주세요.메모장은 문법 강조 기능을 지원하지 않을 뿐 아니라, 앞으로 중요하게 다루어질 자동 들여쓰기 기능을 지원하지않기 때문에 굉장히 안 좋은 선택입니다. 자동으로 이런 기능들을 지원하는 소프트웨어를 사용해 주세요.

여러분이 숙련된 프로그래머라면 아마도 여러분은 Vim 또는Emacs 에 이미 익숙할 것입니다. 말할 필요도 없이,이 두 편집기는 현존하는 최고의 편집기들이며 파이썬 프로그램을 작성하는데에도 여러 장점이 있습니다.저도 프로그램을 작성할 때 이 두 프로그램을 주로 사용하며,심지어 책 한 권을 Vim으로 작성하기도 했습니다.

혹시 여러분이 Vim 또는 Emacs를 시간을 들여 배우고 싶으신 경우,저는 둘 중 하나라도 그 사용법을 익혀 두기를 추천하며, 이것은 장기간에 걸쳐 큰 도움이 될 것입니다.그러나, 초보자분들의 경우 지금 시점에서는 위에서 언급한 Light Table을 사용하시고, 편집기 사용법을 익히는데시간을 투자하기 보다는 파이썬을 배우는데 초점을 맞추시는 편이 더 나을 수도 있을 것입니다.

다시 한번 말씀드리지만, 제대로 된 편집기를 이용하시기 바랍니다.그러면 파이썬 프로그램을 작성하는 것이 더 재미있고 쉽게 느껴질 것입니다.

6.3. Light Table

Light Table 은 파이썬 프로그램을 작성하는 데 유용하게 사용될 수 있는 자유 소프트웨어입니다.

프로그램 메뉴에서 <code>File</code> → <code>New file</code> 을 찾아 클릭한 뒤, 다음을 입력하세요.

<code class="python language-python">print "hello world"</code>

<code>File</code> → <code>Save</code> 를 클릭하고, <code>hello.py</code> 라는 이름으로 저장하세요.

<code>View</code> → <code>Console</code> 을 클릭합니다.

이제, 상단에 보이는 마지막 칸에 커서를 위치시킨 뒤 <kbd class="keyseq"><kbd>command</kbd>+<kbd>enter</kbd></kbd>를 눌러 그 줄을 실행시키면 console에 결과가 나타날 것입니다.

파이썬을 위한 LightTable 튜토리얼 동영상을 통해Light Table을 사용하는 방법을 익히세요.

Screenshot of Light Table

6.4. Vim

  1. Vim 설치하기

    1. Mac OS X 사용자들은 HomeBrew 를 통해 <code>macvim</code> 패키지를 설치하세요.

    2. Windows 사용자들은 http://www.vim.org/download.php 에서 "self-installing executable"을 내려받아 설치하세요.

    3. GNU/Linux 사용자들은 각 배포판의 소프트웨어 저장소에서 Vim을 내려받아 설치하여야 합니다.예를 들어 데비안 혹은 우분투의 경우 vim 패키지를 설치하세요.

  2. John M Anderson이 쓴 Vim as PythonIDE 를 읽으세요.

  3. 자동완성 기능을 설치하시려면 다음 플러그인을 설치하세요. jedi-vim.

6.5. Emacs

  1. Emacs 24 설치하기

    1. Mac OS X 사용자들은 http://emacsformacosx.com 에서 Emacs를 내려받아 설치하세요.

    2. Windows 사용자들은 http://ftp.gnu.org/gnu/emacs/windows/ 에서 Emacs를 내려받아 설치하세요.

    3. GNU/Linux 사용자들은 각 배포판의 소프트웨어 저장소에서 Emacs를 내려받아 설치하여야 합니다.예를 들어 데비안 혹은 우분투의 경우 emacs24 패키지를 설치하세요.

  2. ELPY 를 설치하세요.

  3. ELPY wiki 를 읽으세요.

  4. 혹은 Emacs Prelude 배포판을 설치하는 것도 추천합니다.

6.6. 소스 파일 사용하기

이제 프로그래밍으로 돌아갑시다. 아마 여러분이 어떤 언어를 배우던지,Hello World 라는 프로그램을 처음 작성하고 실행하게 될 것입니다.이 프로그램이 하는 일은 실행했을 때 단순히 Hello World 라는 문자열을 화면에 출력하는 것입니다.Simon Cozens (Beginning Perl의 저자)은 이에 대해 다음과 같이 말했습니다."Hello World란 프로그래밍 신에게 이 언어를 잘 배울 수 있도록 도와 달라는, 일종의 주문이다."

편집기를 실행하시고, 다음과 같이 프로그램을 작성한 뒤 <code>hello.py</code> 라는 이름으로 저장하세요.

여러분이 Light Table을 사용 중이시라면, <code>File</code> → <code>New file</code> 메뉴를 클릭하고 다음을 입력하세요.

<code class="python language-python">print "hello world"</code>

이제 <code>File</code> → <code>Save</code> 메뉴를 클릭하시고 <code>hello.py</code> 라고 입력해 봅시다.

파일을 어디에 저장해야 할까요? 폴더의 경로를 알고 있다면 어디에든 저장해도 좋습니다.이 말이 무슨 뜻인지 잘 모르시겠다면, 다음과 같이 새 폴더를 만들고 앞으로 작성할 모든 파이썬 프로그램을이곳에 저장하도록 합시다.

  • <code>/tmp/py</code> (Mac OS X 환경)

  • <code>/tmp/py</code> (GNU/Linux 환경)

  • <code>C:\\py</code> (윈도우 환경)

폴더를 만드는 방법은 터미널에서 <code>mkdir</code> 명령을 이용하면 됩니다.예를 들어 Max OS X 혹은 GNU/Linux의 경우 <code>mkdir /tmp/py</code> 라고 입력하면 됩니다.

중요: 파일의 확장자명을 <code>.py</code>로 지정했는지 언제나 다시 한번 확인하세요. <code>foo.py</code>와 같은 형태가 되어야 합니다.

파이썬 프로그램 실행시키기:

  1. 터미널 창을 여세요 (설치 챕터에서 터미널 창을 여는 법을 다루고 있습니다).

  2. cd (Change directory의 약어) 명령으로 파일을 저장한 경로로 이동합니다.예를 들어 Max OS X 혹은 GNU/Linux의 경우 <code>cd /tmp/py</code> 와 같이 입력하세요.

  3. <code>python hello.py</code>라 입력하여 프로그램을 실행합니다. 실행 결과는 아래와 같습니다.

$ python hello.pyhello world
Screenshot of running program in terminal

위와 같은 결과물을 얻으셨나요? 축하합니다! 여러분은 여러분의 첫 파이썬 프로그램을성공적으로 실행시킨 것입니다. 방금 여러분은 프로그래밍을 배울 때 접하는 가장 어려운부분을 지나온 것입니다. 그것은 바로 첫 프로그램을 성공적으로 실행시키는 것입니다!

만약 결과물 대신 오류 메시지가 출력되는 경우에는, 다시한번 프로그램을 정확하게 적혀진그대로 입력한 뒤 프로그램을 다시 실행해 보세요. 파이썬은 대/소문자를 구분합니다.예를 들면 <code>print</code> 는 <code>Print</code>와 같지 않습니다. 전자의 <code>p</code>는 소문자이고, 후자의 <code>P</code>는대문자임에 유의하세요. 또한, 모든 줄의 첫번째 문자 앞에 공백이나 탭이 입력되어 있지는 않은지 확인하세요.곧 왜 이것이 중요한지 다루게 될 것입니다.

동작 원리

파이썬 프로그램은 명령문들로 구성됩니다. 여러분이 작성한 첫 프로그램에서는,단 한 가지의 명령만이 사용되었습니다. 여기서는 <code>print</code>라고 불리우는명령을 불러 "Hello World"라는 문자열을 출력하도록 한 것입니다.

6.7. 도움 받기

여러분이 파이썬이 제공하는 여러 함수나 명령들에 대한 정보를 얻고싶으실 경우, 파이썬에 내장된 <code>help</code> 명령을 사용할 수 있습니다.이 기능은 인터프리터 프롬프트를 이용할 때 특히 유용합니다.예를 들면, <code>help('len')</code>라고 입력해 보세요. 그러면 항목의 개수를 세는 데 사용되는<code>len</code> 함수에 대한 도움말이 화면에 표시됩니다.

Tip
<code>q</code> 를 눌러 도움말을 종료할 수 있습니다.

비슷한 방법으로, 파이썬 내에 있는 거의 모든 항목에 대한 정보를 얻을 수 있습니다.<code>help()</code>를 이용하여 <code>help</code> 라는 명령 자체에 대한 설명도 확인해 보세요!

혹시 여러분이 <code>return</code>과 같은 연산자들에 대한 정보를 얻고 싶은 경우,다음과 같이 좌우에 따옴표를 붙여줄 필요가 있습니다. 즉, <code>help('return')</code>과 같이 해 주어 파이썬이 우리가 어떤 일을 하려고 하는 것인지 혼동하지 않게합니다.

6.8. 요약

이제 여러분은 쉽게 파이썬 프로그램을 작성하고, 저장하고, 실행할 수 있을 것입니다.

이제 여러분은 한 명의 파이썬 사용자입니다. 이제 파이썬의 다른 기능들에 대해서도 배워 봅시다.

7. 기초

화면에 <code>Hello World</code>를 출력하는 것만으로는 부족하지요?여러분은 아마도 더 많은 것을 하고 싶을 것입니다. 뭔가 정보를 입력받고,처리한 뒤 결과물을 출력하는 프로그램을 만들고 싶으실 테죠.파이썬에서는 상수들과 변수들을 이용하여 이러한 일을 할 수 있습니다.물론 이 챕터에서는 이외에 다른 여러 기능들에 대해서도 배우게 될 것입니다.

7.1. 주석

주석 은 <code>#</code> 문자 뒤에 따라오는 짧은 문장입니다.주로 소스 코드를 읽는 사람들을 위해 주석을 남기는 용도로 빈번하게 사용됩니다.

예제:

<code class="python language-python">print 'hello world' # Note that print is a statement</code>

또다른 예제:

<code class="python language-python"># Note that print is a statementprint 'hello world'</code>

여러분의 프로그램을 작성할 때, 주석을 가능한 많이 사용하시기 바랍니다.

  • 미리 가정하고 넘어간 것들에 대한 설명

  • 중요한 결정사항에 대한 설명

  • 중요한 세부사항에 대한 설명

  • 해결하고자 하는 문제에 대한 설명

  • 앞으로 극복하려고 하는 문제들에 대한 설명 등등.

주석은 여러분의 프로그램을 읽는 사람들에게 여러분이 작성한 프로그램이 무엇을 하는 프로그램인지쉽게 파악할 수 있도록 도움을 주는 역할을 합니다. 프로그램을 작성하고 한 6개월쯤 뒤에는 여러분이 작성한 주석에도움을 받는 사람이 여러분 자신이 될 수도 있다는 점을 꼭 기억하세요!

역자 주:

주석을 한글로 남길 경우, 혹은 여러분의 파이썬 프로그램에 한글이 들어갈 경우프로그램의 첫번째 줄 혹은 두 번째 줄에는 반드시 다음과 같이 파일의 인코딩에 대한 정보가주석의 형태로 들어가 있어야 합니다.

<code class="python language-python"># coding=cp949</code>

cp949란 마이크로소프트에서 제정한 한글 표현 방식을 뜻합니다 (codepage 949). 파일이 UTF-8형식으로 저장되는 경우 다음과 같이 작성합니다.

<code class="python language-python"># coding=utf-8</code>

자세한 사항은 PEP 0263 및 뒤에서 다룰 유니코드 섹션을참고하세요.

7.2. 리터럴 상수

리터럴 상수는 <code>5</code>, <code>1.23</code> 과 같은 숫자나, <code>'This is a string'</code> 혹은 <code>"It's a string!"</code>과 같은 문자열 등을 말합니다.

이것들이 리터럴 상수라고 불리우는 이유는 이것들이 프로그램 내에 직접 문자 형태로(literal)지정되는 값들이기 때문입니다. 이러한 값들은 한번 지정되면 변하지 않습니다.예를 들면 숫자 <code>2</code> 는 언제나 자기 자신은 2라는 숫자임을 나타내며 어떤 다른 의미도 갖지 않습니다.이들은 한번 지정되면 그 값을 변경할 수 없기 때문에 상수입니다.그중에서도 특별히 이러한 값들을 리터럴 상수라고 부릅니다.

7.3. 숫자형

숫자형에는 정수형(Integer)과 부동 소수점 숫자형(Float)의 두 가지 종류가 있습니다.

정수형 숫자의 예는 <code>2</code> 입니다. 이것은 단순히 2라는 숫자를 의미하는 것입니다.

부동 소수점 숫자의 예는 <code>3.23</code>, <code>52.3E-4</code>와 같은 값입니다. <code>E</code> 표기법은이 값이 10의 지수임을 나타냅니다. 예를 들어 <code>52.3E-4</code> 는 <code>52.3 * 10-4</code>라는 값을의미합니다.

Note
숙련된 프로그래머들을 위한 주석
파이썬에서는 <code>long</code> 형이 따로 없습니다.대신, <code>int</code> 형에 어떤 크기의 정수든지 담을 수 있습니다.

7.4. 문자열

문자열이란 문자나열을 뜻합니다. 문자열은 간단하게 말하자면 문자들의 집합입니다.여러분은 아마 앞으로 작성하게 될 거의 모든 파이썬 프로그램에서 문자열을 사용하게 될것입니다. 따라서, 아래 항목들을 주의깊게 살펴보세요.

7.4.1. 작은 따옴표

여러분은 작은 따옴표를 이용하여 문자열을 지정할 수 있습니다.예를 들어 <code>'Quote me on this'</code> 와 같이 하면 됩니다.

모든 공백 문자, 즉 띄어쓰기나 탭 등은 입력한 그대로 유지됩니다.

7.4.2. 큰 따옴표

큰 따옴표로 둘러싸인 문자열은 작은 따옴표로 둘러싸인 문자열과 완전히 같게 취급됩니다.예를 들면, <code>"What's your name?"</code> 과 같습니다 (큰 따옴표로 둘러싸인 문자열 안에 작은 따옴표가 포함되어도 됩니다).

7.4.3. 따옴표 세 개

여러 줄에 걸친 문자열은 세 개의 따옴표로 표현할 수 있습니다 - (<code>"""</code> 또는 <code>'''</code>). 세 개의 따옴표로묶여진 문자열 안에서는 작은 따옴표든 큰 따옴표든 마음대로 사용할 수 있습니다. 예를 들면 다음과 같습니다.

<code class="python language-python">'''This is a multi-line string. This is the first line.This is the second line."What's your name?," I asked.He said "Bond, James Bond."'''</code>

7.4.4. 문자열은 수정이 불가

여러분이 문자열을 한번 만들었다면, 그 문자열의 내용은 더이상 변경될 수 없습니다.아마도 뭔가 좋은 것 같지 않아 보일 수 있습니다만, 사실 그렇지 않습니다.책의 뒷부분에서 여러 프로그램 예시를 통해 왜 이것이 큰 제약이 아닌 것인지 살펴볼 것입니다.

Note
C/C++ 프로그래머들을 위한 주석
파이썬에서는 <code>char</code> 형이 따로 구분되어 있지 않습니다. 파이썬에서는 이것이 딱히 필요가 없습니다. 곧 여러분도 <code>char</code> 형을 찾지 않게 될 것입니다.
Note
Perl/PHP 프로그래머들을 위한 주석
작은 따옴표와 큰 따옴표로 둘러싸인 문자열은 동일하게 취급됩니다. 둘 사이에 어떤 차이도 없습니다.

7.4.5. 문자열 포맷팅

문자열을 생성하려고 할 때, 종종 다른 정보들을 포함하여 생성하고 싶을 때가 있습니다.이때 <code>format()</code> 을 이용한 방법이 유용합니다.

다음을 <code>str_format.py</code> 라는 이름으로 저장하세요.

<code class="python language-python">age = 20name = 'Swaroop'print '{0} was {1} years old when he wrote this book'.format(name, age)print 'Why is {0} playing with that python?'.format(name)</code>

실행 결과:

$ python str_format.pySwaroop was 20 years old when he wrote this bookWhy is Swaroop playing with that python?
동작 원리

먼저 중괄호로 표현된 특별한 표시들이 포함된 문자열을 만들고,그 후에 문자열의 <code>format</code> 메소드를 사용하여 이 표시들을 <code>format</code> 메소드에주어진 인자들로 치환한 것입니다.

위 예시에서는 문자열 내에서 첫번째로 <code>{0}</code> 이 사용되었으며이것은 format 메소드에 주어진 첫번째 인자, 즉 변수 <code>name</code> 에 해당됩니다.마찬가지로, 두번째 사용된 표시는 <code>{1}</code> 이며 이것은 format 메소드에 주어진 두번째 인자인<code>age</code> 에 해당됩니다. 파이썬은 개수를 셀 때 항상 0 부터 시작한다는 점을 유의하세요.즉, 첫번째 인자의 인덱스는 0 이며, 두번째는 1 입니다.

또한 다음과 같이 문자열 더하기를 이용하여 동일한 결과를 얻을 수도 있습니다.

<code class="python language-python">name + ' is ' + str(age) + ' years old'</code>

그러나 이것은 깔끔하지 못하며, 따라서 실수하기도 쉽습니다.또한 이 경우 각 변수를 일일이 명시적으로 문자열로 변환해주어야 합니다만,<code>format</code> 메소드를 이용할 경우에는 알아서 자동으로 변환해 줍니다.또한 <code>format</code> 메소드를 이용할 경우 변수들을 신경쓰지 않고 문자열의 내용을 수정하기 쉽고,그 반대로 문자열을 신경쓰지 않고도 변수의 위치나 순서 등을 변경하기가 더 쉽습니다.

또한 중괄호 내에 주어진 숫자는 생략할 수 있습니다. 다음 예제를 확인하세요.

<code class="python language-python">age = 20name = 'Swaroop'print '{} was {} years old when he wrote this book'.format(name, age)print 'Why is {} playing with that python?'.format(name)</code>

위 프로그램 또한 동일한 결과를 출력합니다.

파이썬의 <code>format</code>은 중괄호 표시의 위치에 주어진 인자들의 값을 치환해 넣습니다.이때, 중괄호 표시에 다음과 같이 좀 더 상세히 세부사항을 지정할 수도 있습니다.

<code class="python language-python"># 소수점 이하 셋째 자리까지 부동 소숫점 숫자 표기 (0.333)print '{0:.3f}'.format(1.0/3)# 밑줄(_)로 11칸을 채우고 가운데 정렬(^)하기 (___hello___)print '{0:_^11}'.format('hello')# 사용자 지정 키워드를 이용해 (Swaroop wrote A Byte of Python) 표기print '{name} wrote {book}'.format(name='Swaroop',                                   book='A Byte of Python')</code>

실행 결과:

0.333___hello___Swaroop wrote A Byte of Python

지금까지 포맷팅에 대해 배웠습니다만, <code>print</code> 명령은 언제나 주어진 문자열의 끝에"줄바꿈" 문자 (<code>\n</code>) 을 덧붙인다는 것 또한 기억하세요.따라서 <code>print</code> 명령을 호출할 때마다 인자로 주어진 내용들은 항상 다른 줄에 출력됩니다.이것을 막기 위해서는, <code>print</code> 명령 뒤에 쉼표(,)를 붙여주면 됩니다.

<code class="python language-python">print "a",print "b",</code>

실행 결과:

a b

7.4.6. 이스케이프(Escape) 문자

여러분이 작은 따옴표(<code>'</code>)를 포함하고 있는 문자열 하나를 정의하고 싶다고 해 봅시다.이 경우 어떻게 이 문자열을 정의하면 될까요? 예를 들면 <code>What's your name?</code> 과 같은 문자열을 정의하는 것입니다.물론 <code>"What's your name?"</code>이라고 하면 되겠지만, <code>'What's your name?'</code>과 같은 방식을 사용할수는 없습니다.왜냐면 이 경우 문자열의 시작과 끝이 어디부터 어디까지인지 모호해지기 때문이죠. 따라서 우리는 문자열 안에 포함된 작은 따옴표가문자열의 끝을 의미하는 것이 아니라는 것을 파이썬에게 알려줘야 합니다.이것은 이스케이프 문자라 불리우는 것을 이용하면 해결할 수 있습니다.사용법은 작은 따옴표 앞에 <code>\</code> 문자(<kbd>enter</kbd> 키 위에 있습니다)를 붙여 <code>\'</code> 와 같은 방식으로 표기하면 됩니다.위의 문자열은 <code>'What\'s your name?'</code> 과 같이 표기할 수 있습니다.

위 문자열을 정의하는 또 다른 방법은 큰 따옴표를 사용하여 <code>"What's yourname?"</code> 과 같이 표기하는 것입니다. 큰 따옴표로 지정된 문자열 안에 포함된 큰 따옴표도마찬가지로 이스케이프 문자를 이용하여 표기할 수 있습니다. 또한, 여러분이<code>\</code> 문자를 표기하고 싶을 경우에는 <code>\\</code> 라 표기하면 됩니다.

한편 여러분이 두줄짜리 문자열을 정의하고 싶을 경우 어떻게 하면 될까요?한가지 방법은 위에서 다루었듯이 따옴표 세 개로 문자열을 정의하거나,혹은 이스케이프 문자를 이용하여 줄바꿈 문자 (newline character) <code>\n</code> 을 사용하여 줄바꿈을 표현할 수 있습니다.다음 예제를 확인하세요.

<code class="python language-python">'This is the first line\nThis is the second line'</code>

또 한가지 유용한 이스케이프 문자는 <code>\t</code>로 표현되는 탭 문자입니다.이외에도 여러가지 이스케이프 문자를 이용한 표기들이 많이 있지만,지금은 가장 유용한 것 몇가지를 알려 드리는 것입니다.

한가지 알아두면 좋은 것은 문자열을 정의할 때 한 줄의 끝에 <code>\</code> 문자를 붙이면,줄바꿈 없이 그 다음 줄에 정의된 문자열도 끊김없이 이어 붙여 문자열을 정의하게 됩니다.예를 들면 다음과 같습니다.

<code class="python language-python">"This is the first sentence. \This is the second sentence."</code>

위 예제는 다음 예제와 동일합니다.

<code class="python language-python">"This is the first sentence. This is the second sentence."</code>

7.4.7. Raw 문자열

문자열 내에 포함된 이스케이프 문자 등을 처리하지 않고 그대로 출력하고 싶을 때,문자열 앞에 <code>r</code> 또는 <code>R</code> 문자를 붙여 Raw 문자열임을 표기합니다. 다음 예제를 확인하세요.

<code class="python language-python">r"Newlines are indicated by \n"</code>
Note
정규 표현식 사용자를 위한 주석
정규 표현식을 사용할 때 언제나 Raw 문자열을 사용하세요. 그렇지 않으면 문자열 내에 이스케이프 문자가너무 많아져 알아볼 수 없게 될지도 모릅니다. Raw 문자열을 사용하면, <code>'\\1'</code> 을 <code>r'\1'</code>로 짧게 표기 가능합니다.

7.5. 변수

리터럴 상수만 사용하며 프로그램을 작성할 수는 없습니다.뭔가 정보를 담고, 수정할 수 있는 어떤 공간이 필요할 것입니다.즉, 변수를 이용하는 것이 좋습니다. 변수는 이름 그대로 할 수 있는 공간을 말하며,여기에는 무엇이든 저장할 수 있습니다. 변수들은 단순히 정보를 저장할 때 사용되는 컴퓨터 메모리의한 부분을 가져다 사용하는 것입니다. 리터럴 상수와는 달리, 변수들은 프로그램 내에서 여러 방법을 통해변경되고 사용되기 때문에 알아보기 쉬운 이름을 지어 줍시다.

7.6. 식별자 이름 짓기

변수는 식별자의 한 예입니다. 식별자무언가를 식별하기 위해 주어진 그것의 이름을 말합니다.식별자 이름을 짓는데는 다음과 같은 규칙이 있습니다.

  • 식별자의 첫 문자는 알파벳 문자 (ASCII 대/소문자 혹은 유니코드 문자)이거나 밑줄 (<code>_</code>) 이어야 합니다.

  • 나머지는 문자 (ASCII 대/소문자 혹은 유니코드 문자), 밑줄 (<code>_</code>), 또는 숫자 (0-9)가 될 수 있습니다.

  • 식별자는 대/소문자를 구분합니다. 예를 들어, <code>myname</code> 과 <code>myName</code> 은 다릅니다. 전자의 <code>n</code>은 소문자이고,후자의 <code>N</code>은 대문자입니다.

  • 올바른 식별자 이름은 <code>i</code>, <code>__my_name</code>, <code>name_23</code> 등과 같습니다. 올바르지 않은식별자 이름은 <code>2things</code>, <code>this is spaced out</code>, <code>my-name</code>, <code>>a1b2_c3</code> 등입니다.

7.7. 자료형

변수는 여러 가지 자료형의 값을 담을 수 있습니다. 가장 간단한 자료형의 예는 앞에서 이야기한 숫자형과 문자열입니다.뒷장에서, 클래스를 이용한 사용자 정의 자료형을 만드는 법 또한 배우게 될 것입니다.

7.8. 객체

파이썬에서 사용되는 모든 것은 객체입니다. "그것"'라고 표현하는 대신, "그 객체" 라고 말합니다.

Note
객체 지향 프로그래머들을 위한 주석
파이썬은 강력한 객체 지향 언어로써 숫자, 문자, 함수 등등 모든 것을 객체로 취급합니다.

이제 리터럴 상수들과 함께 변수를 사용하는 방법을 알아보도록 하겠습니다. 다음 예제를 저장한 후 실행하여 봅시다.

7.9. 파이썬 프로그램 작성하기

이제부터, 다음과 같이 파이썬 프로그램을 저장하고 실행하도록 합시다.

  1. Light Table 혹은 여러분이 사용하는 텍스트 편집기를 실행합니다.

  2. 예제 프로그램을 입력합니다.

  3. 적당한 파일명을 짓고 저장합니다.

  4. <code>python program.py</code> 와 같이 실행하여 파이썬 인터프리터를 통해 프로그램을 실행합니다.

7.10. 예제: 변수와 리터럴 상수 사용하기

다음 프로그램을 입력 후 실행하세요.

<code class="python language-python"># Filename : var.pyi = 5print ii = i + 1print is = '''This is a multi-line string.This is the second line.'''print s</code>

실행 결과:

56This is a multi-line string.This is the second line.
동작 원리

위 프로그램의 동작 원리는 다음과 같습니다.먼저, 리터럴 상수 <code>5</code> 라는 값을 변수 <code>i</code> 에 할당 연산자 (<code>=</code>)를 이용하여 할당하였습니다.이러한 한 줄을 명령이라고 부르는데, 이 경우 변수명 <code>i</code> 를 값 <code>5</code> 에 할당하는 행위를 지정해 준 것이기 때문니다.다음으로, <code>i</code> 에 할당된 값을 <code>print</code> 명령을 이용하여 출력합니다. 그러면 변수에 지정된 값이 화면에 나타납니다.

그리고 <code>i</code> 에 할당된 값에 <code>1</code>을 더한 후 그 값을 다시 변수에 할당합니다. 이제 이 값을 출력하면,예상대로, <code>6</code> 이라는 값이 출력됨을 알 수 있습니다.

리터럴 문자열 상수 또한 앞에서 설명한 과정과 동일한 과정을 거쳐 변수 <code>s</code> 에 저장된 후 화면에 출력됩니다.

Note
정적 언어 프로그래들을 위한 주석
파이썬에서는 변수에 값을 할당함으로써 변수가 생성되며 곧바로 사용할 수 있습니다.따로 변수의 자료형을 지정할 필요가 없으며, 심지어 미리 변수를 선언할 필요도 없습니다.

7.11. 논리적/물리적 명령행

물리적 명령행이란 프로그램 코드 내에 직접 표현된 한 줄을 의미하는 반면,논리적 명령행은 파이썬 인터프리터 관점에서의 한 명령 단위를 의미합니다.파이썬은 각각의 물리적 명령행이 곧 논리적 명령행일 것이라고 내부적으로 간주하고 프로그램을 실행합니다.

논리적 명령행이란 예를 들면 <code>print 'hello world'</code> 같은 것입니다.만약 이것이 실제 코드 상으로도 한 줄로 표현되어 있다면 (편집기에서 보이는 그대로를 말합니다),이 한 줄은 물리적 명령행이라고도 말할 수 있을 것입니다.

일반적으로, 파이썬으로 프로그래밍할 경우 한 명령을 한 행에 적도록 하여전체적인 코드를 파악하기 쉽게 작성하는 것을 권합니다.

만약 여러분이 한 물리적 명령행에 둘 이상의 논리적 명령행을 넣고 싶다면,세미콜론 (<code>;</code>)을 이용하여 논리적 명령줄의 끝을 명시적으로 파이썬 인터프리터에게 알려줄 수 있습니다.다음 예제를 확인하세요.

<code class="python language-python">i = 5print i</code>

위 예제는 다음 예제와 같습니다.

<code class="python language-python">i = 5;print i;</code>

이것은 다음 예제와도 같습니다.

<code class="python language-python">i = 5; print i;</code>

또한 다음 예제와도 같습니다.

<code class="python language-python">i = 5; print i</code>

하지만, 저는 여러분이 한 물리적 명령행에 두개 이상의 논리적 명령행을 사용하지 말 것강력히 권합니다.즉, 세미콜론을 사용하지 말아 주세요. 사실, 저는 파이썬 프로그램을 작성할 때 세미콜론을 한번도사용해 본 적이 없고, 또 다른 사람이 사용하는 것을 본 적도 없습니다.

한 명령행이 너무 길어서 보기가 불편한 경우, 백슬래시 문자(<code>\</code>)를 이용하여한 논리적 명령행을 여러 물리적 명령행으로 나눌 수 있습니다. 이를 명시적 행간 합치기라 부릅니다.

<code class="python language-python">s = 'This is a string. \This continues the string.'print s</code>

실행 결과:

This is a string. This continues the string.

다음과 같이 쓸 수도 있습니다.

<code class="python language-python">print \i</code>

위 예제는 다음과 같습니다.

<code class="python language-python">print i</code>

가끔, 백슬래시 없이 행간을 합칠 수 있는 경우도 있습니다. 이것은 명령행의 중간에 괄호가 있을 때,즉 대괄호나 중괄호를 열었을 경우 괄호를 닫을 때까지 백슬래시 없이도 모두 같은 명령행으로 간주됩니다.이것은 암시적 행간 합치기라고 부릅니다. 뒷장에서 리스트를 사용하여 프로그램을 작성할 때이런 경우를 보게 될 것입니다.

7.12. 들여쓰기

파이썬에서 공백은 중요한 역할을 합니다. 사실, 한 행의 앞에 붙어있는 공백이 정말로 중요합니다.이것을 들여쓰기라 부릅니다. 한 논리적 명령행의 앞에 붙어있는 공백 (빈 칸 혹은 탭)은논리적 명령행의 들여쓰기 단계를 의미하며, 이것은 한 명령의 범위를 구분하는 데 사용됩니다.

이것은 같은 단계에 있는 명령들은 반드시 같은 들여쓰기를 사용해야 함을 의미합니다.이러한 같은 들여쓰기를 사용하고 있는 명령들의 집합을 블록(block) 이라고 부릅니다.뒷장에서 예제를 통해 블록에 대해 다루게 될 것입니다.

지금 여러분이 기억하셔야 할 것은 잘못된 들여쓰기는 오류를 일으킨다는 것입니다. 다음 예제를 봅시다.

<code class="python language-python">i = 5# 다음 행에서 오류가 발생합니다! 행 앞에 잘못된 공백이 한 칸 있습니다. print 'Value is ', iprint 'I repeat, the value is ', i</code>

위 예제를 실행하면 다음과 같이 오류가 발생합니다.

  File "whitespace.py", line 5    print 'Value is ', i    ^IndentationError: unexpected indent

두번째 행 앞에 공백이 한칸 있다는 점을 확인하세요. 위와 같은 오류는 파이썬이 우리에게 프로그램의 문법이 잘못되었음을,즉 프로그램이 뭔가 잘못 작성되었다는 것을 알려 주는 것입니다. 이 오류가 의미하는 것은 여러분이 임의로 새 블록을 시작할 수 없음을 의미합니다. 새 블록을 시작할 수 있는 경우에 대해 흐름 제어 챕터에서 다루게 될 것입니다.

들여쓰기 하는 법

들여쓰기를 할 때에는 공백 4개를 이용하세요. 이것은 파이썬 언어에서 공식적으로 추천하는 방법입니다.좋은 편집기들은 이 사항을 자동으로 준수합니다. 또, 들여쓰기를 할 때에는 항상 같은 개수의 공백을 사용해야 한다는 점에 유의하시기 바랍니다.

Note
정적 언어 프로그래머들을 위한 주석
파이썬은 블록 구분을 위해 들여쓰기를 사용하며, 중괄호를 사용하지 않습니다.파이썬에서 <code>from __future__ import braces</code> 명령을 실행하여 자세한 사항을 확인하세요.

7.13. 요약

지금까지 파이썬의 여러 기본적인 특징에 대해 배워보았습니다. 이제 흐름 제어와 같이 좀 더 재미있는 부분에 대해 배워 보도록 하겠습니다.다음 챕터로 넘어가기 전, 이 챕터에서 배운 내용에 대해 미리 익숙해져 두기를 바랍니다.

8. 연산자와 수식

여러분이 앞으로 작성하게 될 모든 명령문 (논리적 명령행)은 수식을 포함하게 될 것입니다.아주 간단한 수식의 한 예는 <code>2 + 3</code> 입니다. 수식은 연산자와 피연산자로 나눌 수 있습니다.

연산자란 무언가를 계산할 때 쓰이는 한 기능을 뜻하며, <code>+</code>와 같이 기호로 나타내어지거나 또는 특별한 키워드로 나타내어집니다.또 연산자는 계산에 사용될 데이터를 필요로 하는데, 이들을 피연산자라고 부릅니다. 이 경우, 피연산자는 <code>2</code> 와 <code>3</code> 이 됩니다.

8.1. 연산자

이제 연산자의 사용법에 대해 알아보도록 하겠습니다.

파이썬 인터프리터 프롬프트 상에서도 수식을 계산할 수 있습니다.다음과 같이 파이썬 인터프리터 프롬프트 상에서 <code>2 + 3</code>이라는 수식을 입력해 봅시다.

<code class="python language-python">>>> 2 + 35>>> 3 * 515>>></code>

이제 파이썬에서 사용 가능한 연산자들의 종류에 대해 간단히 알아봅시다.

<code>+</code> (덧셈 연산자)

두 객체를 더합니다.

<code>3 + 5</code> 는 <code>8</code> 을 반환합니다. <code>'a' + 'b'</code> 는 <code>'ab'</code> 를 반환합니다.

<code>-</code> (뺄셈 연산자)

한 숫자에서 다른 숫자를 뺍니다. 첫 번째 피연산자가 주어지지 않으면, 0으로 간주됩니다.

<code>-5.2</code> 는 음수를 표현합니다. <code>50 - 24</code> 는 <code>26</code> 을 반환합니다.

<code>*</code> (곱셈 연산자)

두 숫자의 곱 혹은 지정된 숫자만큼 반복된 문자열을 반환합니다.

<code>2 * 3</code> 은 <code>6</code> 을 반환합니다. <code>'la' * 3</code> 은 <code>'lalala'</code> 를 반환합니다.

<code>**</code> (거듭제곱 연산자)

x 의 y제곱을 반환합니다.

<code>3 ** 4</code> 는 <code>81</code> 을 반환합니다 (이 값은 <code>3 * 3 * 3 * 3</code> 과 같습니다).

<code>/</code> (나눗셈 연산자)

x를 y로 나눈 몫을 반환합니다.

<code>13 / 3</code> 은 <code>4</code> 를 반환합니다.<code>13.0 / 3</code> 은 <code>4.333333333333333</code> 을 반환합니다.

<code>%</code> (나머지 연산자)

x를 y로 나눈 나머지를 반환합니다.

<code>13 % 3</code> 은 <code>1</code> 을 반환합니다. <code>-25.5 % 2.25</code> 는 <code>1.5</code> 를 반환합니다.

<code><<</code> (왼쪽 시프트 연산자)

지정된 숫자에 대해 지정된 비트 수 만큼 왼쪽 시프트 연산합니다 (모든 숫자는 메모리상에서 0 또는 1 의 비트로구성된 이진수로 표현됩니다).

<code>2 << 2</code> 는 <code>8</code> 을 반환합니다. <code>2</code> 는 이진수로 <code>10</code> 으로 표현됩니다.

이것을 왼쪽으로 2비트 시프트 연산하면 이진수 <code>1000</code> 이 되고, 이것을 정수로 표현하면 <code>8</code> 이 됩니다.

<code>>></code> (오른쪽 시프트 연산자)

지정된 숫자에 대해 지정된 비트 수 만큼 오른쪽 시프트 연산합니다.

<code>11 >> 1</code> 은 <code>5</code> 를 반환합니다.

<code>11</code> 은 이진수로 <code>1011</code> 로 표현됩니다. 이것으로 오른쪽으로 1비트 시프트 연산하면 이진수 <code>101</code> 이 되고,이것을 정수로 표현하면 <code>5</code> 가 됩니다.

<code>&</code> (비트 AND 연산자)

비트 AND 연산값을 반환합니다.

<code>5 & 3</code> 은 <code>1</code> 을 반환합니다.

<code>|</code> (비트 OR 연산자)

비트 OR 연산값을 반환합니다.

<code>5 | 3</code> 은 <code>7</code> 을 반환합니다.

<code>^</code> (비트 XOR 연산자)

비트 XOR 연산값을 반환합니다.

<code>5 ^ 3</code> 은 <code>6</code> 을 반환합니다.

<code>~</code> (비트 반전 연산자)

숫자 x의 비트 반전 연산값 -(x+1) 을 반환합니다.

<code>~5</code> 는 <code>-6</code> 을 반환합니다. 자세한 사항은 http://stackoverflow.com/a/11810203 을 읽어 보시기 바랍니다.

<code><</code> (작음)

x가 y보다 작은지 여부를 반환합니다. 모든 비교 연산자는 <code>True (참)</code> 또는 <code>False (거짓)</code>을 반환합니다.각 반환값의 첫글자는 대문자라는 점에 유의하세요.

<code>5 < 3</code> 는 <code>False</code> 를 반환합니다. <code>3 < 5</code> 는 <code>True</code> 를 반환합니다.

다음과 같이 여러 숫자에 대해 한꺼번에 비교 연산을 수행할 수 있습니다. <code>3 < 5 < 7</code> 은 <code>True</code> 를 반환합니다.

<code>></code> (큼)

x 가 y 보다 큰지 여부를 반환합니다.

<code>5 > 3</code> 은 <code>True</code> 를 반환합니다. 만약 두 피연산자가 모두 숫자라면, 같은 숫자형으로 변환된 후 크기를 비교합니다.피연산자가 숫자형이 아닐 경우, 항상 <code>False</code> 를 반환합니다.

<code><=</code> (작거나 같음)

x 가 y 보다 작거나 같은지 여부를 반환합니다.

<code>x = 3; y = 6; x <= y</code> 는 <code>True</code> 를 반환합니다.

<code>>=</code> (크거나 같음)

x 가 y 보다 크거나 같은지 여부를 반환합니다.

<code>x = 4; y = 3; x >= 3</code> 는 <code>True</code> 를 반환합니다.

<code>==</code> (같음)

두 객체가 같은지 여부를 반환합니다.

<code>x = 2; y = 2; x == y</code> 는 <code>True</code> 를 반환합니다.

<code>x = 'str'; y = 'stR'; x == y</code> 는 <code>False</code> 를 반환합니다.

<code>x = 'str'; y = 'str'; x == y</code> 는 <code>True</code> 를 반환합니다.

<code>!=</code> (같지 않음)

두 객체가 같지 않은지 여부를 반환합니다.

<code>x = 2; y = 3; x != y</code> 는 <code>True</code> 를 반환합니다.

<code>not</code> (불리언 NOT 연산자)

x 가 <code>True</code> 라면, <code>False</code> 를 반환합니다. x 가 <code>False</code> 라면, <code>True</code> 를 반환합니다.

<code>x = True; not x</code> 는 <code>False</code> 를 반환합니다.

<code>and</code> (불리언 AND 연산자)

<code>x and y</code>를 계산할 경우, x 가 <code>False</code> 이면 <code>False</code>를 반환하며 <code>True</code> 이면 y 와의 and 연산값을 반환합니다.

<code>x = False; y = True; x and y</code>를 계산할 경우, x 가 <code>False</code> 이므로 y값에 관계없이 <code>x and y</code> 의 값은<code>False</code> 임이 자명하므로, x의 값이 <code>False</code>임이 확인되는 즉시 곧바로 결과값 <code>False</code> 가 반환되며 이때y의 값은 계산되지 않습니다. 이것을 단축 계산(short-circuit evalulation)이라고 부릅니다.

<code>or</code> (불리언 OR 연산자)

x 가 <code>True</code> 이면 <code>True</code> 가 반환되며, <code>False</code>이면 y 와의 or 연산값을 반환합니다.

<code>x = True; y = False; x or y</code> 는 <code>True</code>가 반환됩니다. 여기서도 위와 같이 단축 계산이 적용됩니다.

8.2. 연산 및 할당 연산자

아래 예제와 같이, 변수의 값에 어떤 연산을 한 뒤 다시 그 변수에 연산값을 할당하는 경우가 자주 발생합니다.

<code class="python language-python">a = 2a = a * 3</code>

이런 경우, 아래와 같이 연산과 할당을 한번에 줄여 쓸 수 있습니다.

<code class="python language-python">a = 2a *= 3</code>

즉 <code>(변수) = (변수) (연산자) (수식)</code> 이 <code>(변수) (연산자)= (수식)</code> 의 형태가 됩니다.

8.3. 연산 순서

<code>2 + 3 * 4</code>와 같은 수식을 계산한다고 합시다. 덧셈이 먼저일까요, 곱셈이 먼저일까요? 초등학교 시절에이미 배우셨겠지만, 곱셈을 먼저 계산해야 합니다. 이것은 곱셈 연산이 덧셈 연산보다 연산 순서에서 우위에있기 때문입니다.

아래 표는 파이썬에서의 연산 순서를 나타내고 있습니다. 맨 위부터 가장 늦게 계산되는 순서대로 나열한 것입니다.이것은 특정한 수식이 주어졌을 때, 파이썬은 이 표의 가장 아래에 위치한 연산부터 차례대로 계산하게 된다는것을 의미합니다.

아래 표는 파이썬 레퍼런스 매뉴얼에서 가져온 것입니다. 연산 순서를 적절히 조절하기 위해서는 괄호를 적당한 위치에 사용하는 것이 좋습니다.또, 적절한 괄호의 사용은 프로그램을 좀 더 읽기 쉽게 해 줍니다. 아래의 연산 순서 변경 항목을 통해 이에 대해 좀 더 자세히 알아보시기 바랍니다.

<code>lambda</code>

람다 수식

<code>if - else</code>

조건 수식

<code>or</code>

불리언 OR

<code>and</code>

불리언 AND

<code>not x</code>

불리언 NOT

<code>in, not in, is, is not, <, <=, >, >=, !=, ==</code>

비교 연산, 요소 연산, 관계 연산

<code>|</code>

비트 OR

<code>^</code>

비트 XOR

<code>&</code>

비트 AND

<code><<, >></code>

시프트 연산

<code>+, -</code>

덧셈 및 뺄셈

<code>*, /, //, %</code>

곱셈, 나눗셈, 나눗셈 후 내림 연산, 나머지 연산

<code>+x, -x, ~x</code>

양수 표현, 음수 표현, 비트 NOT 연산

<code>**</code>

거듭제곱

<code>x[index], x[index:index], x(arguments...), x.attribute</code>

원소 접근, 슬라이스, 함수 호출, 속성 참조

<code>(expressions...), [expressions...], {key: value...}, {expressions...}</code>

괄호 또는 튜플, 리스트, 사전, 집합

아직 이 연산자들에 대해 모두 다루지 않았지만, 곧 다루게 될 것입니다.

같은 연산 순서를 갖는 연산자들은 위 표에서 같은 행에 위치하고 있습니다.예를 들어, <code>+</code> 연산자와 <code>-</code> 연산자는 같은 연산 순서를 가지고 있습니다.

8.4. 연산 순서 변경

괄호를 사용하여 수식을 좀 더 읽기 쉽게 할 수 있습니다. 예를 들어, <code>2 + (3 * 4)</code> 라고 쓰면<code>2 + 3 * 4</code> 로 쓰는 것에 비해 연산자 순서를 잘 모르는 사람도 쉽게 읽을 수 있을 것입니다.그렇지만, 괄호를 적당히 사용하는 것도 중요합니다. <code>(2 + (3 * 4))</code> 와 같이 괄호를 너무 많이사용하는 것은 피하세요.

또 괄호를 사용하면 연산의 순서를 바꿀 수 있습니다. 예를 들어 위 수식에서 덧셈을 곱셈보다 먼저계산하고 싶을 경우 <code>(2 + 3) * 4</code> 라고 적을 수 있습니다.

8.5. 같은 연산 순서를 가질 경우

기본적으로 연산자는 왼쪽에서 오른쪽으로 차례대로 계산됩니다. 즉, 같은 연산 순서를 가진 연산자들의경우 왼쪽에서 오른쪽으로 순서대로 계산됨을 의미합니다. 예를 들어, <code>2 + 3 + 4</code> 는 <code>(2 + 3) + 4</code>와 같이 계산됩니다. 다만, 할당 연산자와 같은 몇몇 특별한 연산자들은 오른쪽에서 왼쪽으로 계산됩니다.예를 들어 <code>a = b = c</code> 는 <code>a = (b = c)</code> 와 같이 계산됩니다.

8.6. 수식 예제

에제 (<code>expression.py</code> 로 저장하세요):

<code class="python language-python">length = 5breadth = 2area = length * breadthprint 'Area is', areaprint 'Perimeter is', 2 * (length + breadth)</code>

출력 결과:

$ python expression.pyArea is 10Perimeter is 14
동작 원리

먼저 직사각형의 높이와 너비가 각각 length와 breadth라는 변수에 저장됩니다.이제 앞서 배운 수식을 이용하여, 두 변수를 이용해 직사각형의 면적과 둘레를 계산합니다.첫번째로 <code>area</code> 라는 변수에 <code>length * breadth</code> 라는 수식의 결과가 저장되며,이 값은 <code>print</code> 명령에 의해 화면에 출력됩니다.두번째로는 <code>print</code> 명령에 곧바로 <code>2 * (length + breadth)</code> 라는 수식을 직접 입력하고,그 결과를 화면에 출력합니다.

파이썬이 얼마나 예쁘게 결과를 보여주는지 확인하세요. 우리가 <code>'Area is'</code>라는 문자열이나<code>area</code>라는 변수에 공백을 지정하지 않았음에도, 파이썬이 그 둘 사이에 자동으로 공백을 넣어 줌으로결과물이 깔끔하고 멋지게 출력될 수 있도록 해 주기 때문에 프로그램을 좀 더 읽기 쉽게 작성할 수 있습니다.이것은 파이썬이 프로그래머의 삶을 좀 더 쉽게 만들어주는 하나의 좋은 예라고도 할 수 있겠습니다.

8.7. 요약

지금까지 연산자, 피연산자, 수식에 대해 알아보았습니다. 이들은 여러분이 앞으로 작성할 프로그램의기본적인 골격이 되어 줄 것입니다. 다음으로는, 여러분의 프로그램에서 명령문을 이용하여 지금까지배운 것들을 응용하는 방법에 대해 알아보겠습니다.

9. 흐름 제어

지금까지 우리가 본 파이썬 프로그램들은 전부 맨 윗줄부터 차례대로 실행되기만 하는 것들 뿐이었습니다.이러한 실행 흐름을 바꿀 수 있다면 어떨까요? 예를 들어, 프로그램이 현재 시간에 따라 Good Morning혹은 Good Evening을 출력하는 결정을 내리도록 할 수 있게 하면 좋지 않을까요?

예상하셨겠지만, 흐름 제어문을 이용하면 이러한 프로그램을 제작할 수 있습니다. 파이썬에서는<code>if</code>, <code>for</code>, <code>while</code> 이라는 세 종류의 흐름 제어문을 사용할 수 있습니다.

9.1. <code>if</code> 문

<code>if</code> 문은 조건을 판별할 때 사용됩니다. if (만약) 조건이 참이라면, if 블록의명령문을 실행하며 else (아니면) else 블록의 명령문을 실행합니다.이 때 else 조건절은 생략이 가능합니다.

예제 (<code>if.py</code> 로 저장하세요):

<code class="python language-python">number = 23guess = int(raw_input('Enter an integer : '))if guess == number:    # New block starts here    print 'Congratulations, you guessed it.'    print '(but you do not win any prizes!)'    # New block ends hereelif guess < number:    # Another block    print 'No, it is a little higher than that'    # You can do whatever you want in a block ...else:    print 'No, it is a little lower than that'    # you must have guessed > number to reach hereprint 'Done'# This last statement is always executed,# after the if statement is executed.</code>

실행 결과:

$ python if.pyEnter an integer : 50No, it is a little lower than thatDone$ python if.pyEnter an integer : 22No, it is a little higher than thatDone$ python if.pyEnter an integer : 23Congratulations, you guessed it.(but you do not win any prizes!)Done
동작 원리

이 프로그램에서는, 사용자로부터 숫자를 입력받아 그 숫자가 프로그램에 지정된 숫자와 같은지 확인합니다.먼저 <code>number</code> 변수에 원하는 숫자를 넣습니다. 여기서는 <code>23</code> 입니다. 그리고, <code>raw_input()</code> 함수를 통해사용자로부터 입력을 받습니다. 여기서 함수란 재사용 가능한 프로그램 조각을 의미합니다. 다음 장에서,함수에 대해 좀 더 자세히 배울 것입니다.

파이썬에 내장된 <code>raw_input</code> 함수에 문자열을 넣어 주면 화면에 이 문자열이 출력되며, 또 사용자의 입력을기다리게 됩니다. 이제 사용자가 무엇인가를 입력하고 <kbd>enter</kbd> 키를 누르면, <code>raw_input()</code> 함수는사용자가 입력한 것을 문자열의 형태로 반환해 줍니다. 이제 <code>int</code> 를 이용하여 이것을 정수형으로 변환한 뒤,그 값을 변수 <code>guess</code>에 대입합니다. 사실 여기에서 사용된 <code>int</code>는 클래스라고 불리우는 것입니다만,일단 여기서는 이것이 문자열을 숫자형으로 변환해 준다는 것만 기억하셔도 됩니다 (다만 이 때 사용된문자열은 올바른 숫자를 포함하고 있어야 합니다).

다음으로, 사용자가 입력한 숫자와 우리가 고른 숫자를 비교합니다. 만약 이 두 숫자가 같으면, 성공했다는 메시지를화면에 출력합니다. 이때 들여쓰기를 이용하여 어디부터 어디까지가 이 블록에 해당하는지를 표시했다는 것을 확인하세요.이러한 이유로 파이썬에서 들여쓰기는 굉장히 중요합니다. 앞서 말씀드렸듯이 여러분이 "일관성 있게 들여쓰는" 습관에익숙해져 있었으면 좋겠네요. 이미 그렇게 하고 계시지요?

또한 <code>if</code> 문의 뒷부분에 콜론(<code>:</code>)이 붙어 있는 것을 확인하세요.콜론은 그 다음 줄부터 새로운 블록이 시작된다는 것을 의미합니다.

이제, 사용자가 입력한 숫자가 우리가 고른 숫자에 비해 작다면, 사용자에게 좀 더 큰 숫자를 입력하라고 알려 줍니다.여기에 사용된 것은 <code>elif</code> 절인데, 이것은 두 개의 if 문을 중첩해서 사용해야 할 경우 (즉 <code>if else</code>를 쓰고 <code>else</code>밑에 또 다시 <code>if else</code>를 써야 될 경우) 이것을 <code>if-elif-else</code>로 한번에 줄여서 쓸 수 있게 해 주는 것입니다.즉 <code>elif</code>는 프로그래밍을 좀 더 쉽게 해 주고 더 많은 들여쓰기를 해야 하는 수고도 줄여 줍니다.

<code>elif</code> 와 <code>else</code> 문을 사용할 경우, 논리적 명령행의 마지막에는 항상 콜론이 붙어 있어야 하며그 다음 줄에는 다른 들여쓰기 단계로 시작되는 새로운 명령문 블록이 시작되어야 합니다.

또한 <code>if</code>문의 if-block안에 또다른 <code>if</code>문을 넣고, 또 넣고 하는 식으로 작성할 수도 있습니다. 이 경우 이것을중첩된 <code>if</code> 문이라 부릅니다.

<code>elif</code> 와 <code>else</code> 절은 생략이 가능합니다. 최소한의 올바른 <code>if</code> 문 사용법은 다음과 같습니다.

<code class="python language-python">if True:    print 'Yes, it is true'</code>

<code>if</code> - <code>elif</code> - <code>else</code> 문의 실행이 끝나면, 파이썬은 <code>if</code> 문을 담고 있는 블록의 다음 줄부터 실행을 재개합니다.위 예제의 경우 그 블록은 최상위 블록 (프로그램이 실행된 시점의 블록)이 되며, 따라서 그 다음에 실행될 명령문은<code>print 'Done'</code> 이 됩니다. 그 이후는 프로그램의 끝이므로 실행이 종료되게 됩니다.

지금 여러분이 본 것은 굉장히 간단한 프로그램이지만, 이를 통해서도 충분히 많은 것들에 대해 이야기했습니다.하지만 이 모든 내용은 상당히 직관적입니다 (만약 여러분이 C/C++ 경험이 있다면 훨씬 더 쉽다고 느껴지기까지 할 것입니다).지금 당장은 여러분이 이 모든 내용을 익혀야 하겠지만, 몇번 연습을 해보고 나면 아마 좀 더 편하게 받아들여질 것이며곧 자연스럽게 여기게 될 것입니다.

Note
C/C++ 프로그래머를 위한 주석
파이썬에는 <code>switch</code> 문이 없습니다. 대신 <code>if..elif..else</code> 문을 이용하여야 합니다.(몇몇 상황에서는 사전을 이용하는 것이 편리합니다)

9.2. while 문

<code>while</code> 문은 특정 조건이 참일 경우 계속해서 블록의 명령문들을 반복하여 실행할 수 있도록 합니다.<code>while</code> 문은 반복문의 한 예입니다. 또한 <code>while</code> 문에는 <code>else</code> 절이 따라올 수 있습니다.

예제 (<code>while.py</code>로 저장하세요):

<code class="python language-python">number = 23running = Truewhile running:    guess = int(raw_input('Enter an integer : '))    if guess == number:        print 'Congratulations, you guessed it.'        # this causes the while loop to stop        running = False    elif guess < number:        print 'No, it is a little higher than that.'    else:        print 'No, it is a little lower than that.'else:    print 'The while loop is over.'    # Do anything else you want to do hereprint 'Done'</code>

실행 결과:

$ python while.pyEnter an integer : 50No, it is a little lower than that.Enter an integer : 22No, it is a little higher than that.Enter an integer : 23Congratulations, you guessed it.The while loop is over.Done
동작 원리

이 프로그램 또한 숫자 알아맞히기 게임입니다만, 더 나은 점은 사용자가 답을 맞출 때까지계속 숫자를 입력할 수 있다는 것입니다. 즉, 이전 섹션에서 작성한 프로그램처럼 다른 숫자를 입력해 보기 위해프로그램을 또 실행시킬 필요가 없습니다. 이 예제는 <code>while</code>문의 사용법을 잘 보여줍니다.

먼저 <code>while</code> 루프가 실행되기 전 변수 <code>running</code>이 <code>True</code>로 설정되어 있으므로, while 문에 딸려 있는while 블록이 실행되며 <code>raw_input</code>과 <code>if</code>문이 실행됩니다. 이 블록의 실행이 끝나면, <code>while</code> 문은변수 <code>running</code> 의 값을 다시 한번 확인합니다. 이 값이 참인 경우 while 블록을 다시 한번 실행하며,거짓인 경우 else 블록을 실행한 뒤 루프를 빠져나와 다음 명령문이 실행됩니다.

<code>else</code> 블록은 <code>while</code> 루프 조건이 <code>False</code> 인 경우 실행됩니다. 물론 루프 조건을 처음으로 확인했을 경우에도이 블록이 실행될 수 있습니다. <code>while</code> 루프에 <code>else</code> 절이 딸려있는 경우, <code>break</code> 명령으로 루프를강제로 빠져나오지 않는 이상 이 블록은 항상 실행되게 됩니다.

여기서 <code>True</code> 와 <code>False</code> 라는 값들은 불리언 형식이라고 불리우며,각각은 숫자 <code>1</code> 과 <code>0</code> 로 간주됩니다.

Note
C/C++ 프로그래머를 위한 주석
<code>while</code> 루프에 <code>else</code> 절이 사용될 수 있음을 기억하세요.

9.3. <code>for</code> 루프

<code>for..in</code> 문은 객체의 열거형(Sequence)을 따라서 반복하여 실행할 때 사용되는파이썬에 내장된 또 하나의 반복문으로, 열거형에 포함된 각 항목을 하나씩 거쳐가며실행합니다.열거형에 대해서는 이후에 좀 더 자세히 다룰 것입니다.일단 여기서는, 열거형이란 여러 항목이 나열된 어떤 목록을 의미한다고 생각하시기 바랍니다.

예제 (<code>for.py</code>로 저장하세요):

<code class="python language-python">for i in range(1, 5):    print ielse:    print 'The for loop is over'</code>

실행 결과:

$ python for.py1234The for loop is over
동작 원리

이 프로그램은 화면상에 숫자의 나열을 출력합니다. 파이썬에 내장된 <code>range</code> 함수를 통해 이러한 숫자의 나열을생성합니다.

여기서는 <code>range</code> 함수에 두 개의 숫자를 넣어 주었으며, 그러면 이 함수는 첫 번째 숫자 이상, 그리고 두 번째숫자 미만의 숫자 리스트를 반환합니다. 예를 들어, <code>range(1,5)</code> 는 리스트 <code>[1, 2, 3, 4]</code> 를 반환합니다.기본적으로, <code>range</code> 는 1씩 증가하는 숫자의 리스트를 반환합니다. 그러나 <code>range</code>에 세 번째 숫자를 입력하면,이 세 번째 숫자만큼씩 증가하는 숫자들의 리스트를 얻을 수 있습니다. 예를 들어, <code>range(1,5,2)</code> 는 <code>[1,3]</code> 을반환합니다. 반환되는 리스트는 두번째 숫자 미만 까지 반환되며, 이하까지 반환되는 것이 아니라는 점을꼭 기억하세요.

파이썬 3의 <code>range()</code> 는 숫자의 열거형을 생성해 주긴 하지만, for 루프에서 다음 숫자를 요청하기 전까지는 다음 숫자가생성되지 않습니다. 이 경우 리스트 내의 모든 숫자를 한번에 생성하려면, <code>list(range())</code> 를 이용하세요. 리스트(List)는 자료 구조 챕터에서 설명할 것입니다.

따라서 <code>for</code> 루프는 <code>range</code> 함수에서 반환된 리스트를 따라 반복하여 실행됩니다.즉, <code>for i in range(1,5)</code> 는 <code>for i in [1, 2, 3, 4]</code> 와 같습니다.이것은 리스트에 들어 있는 각각의 숫자 (각 숫자는 곧 객체이기도 합니다) 를 한번에 하나씩 i 에 대입하고,이렇게 대입된 각 <code>i</code> 값을 이용하여 for 에 딸린 블록을 실행합니다. 이 경우, for 블록에서 하는 일은단순히 <code>i</code> 값을 화면에 출력해 주는 것입니다.

또한, 추가로 <code>else</code> 절을 포함시켜 줄 수 있습니다. 이것이 포함되면, break 문으로루프를 강제로 빠져나오지 않는 한 루프를 다 돌고 난 뒤에는 이 절이 항상 실행되게 됩니다.

<code>for..in</code> 루프는 어떤 종류의 열거형 자료형과도 함께 사용될 수 있습니다.여기서는 <code>range</code> 라는 내장 함수를 통해 숫자 리스트를 생성하여 사용하였습니다만,일반적으로는 아무 종류의 객체를 담고 있는 아무 열거형이나 사용이 가능합니다! 추후에 이에 대해 좀 더 자세히 다뤄보겠습니다.

Note
C/C++/Java/C# 프로그래머를 위한 주석

파이썬의 <code>for</code> 루프는 C/C++ 에서 제공하는 <code>for</code> 루프와는 근본적으로 다릅니다. 파이썬의<code>for</code> 는 차라리 C# 의 <code>foreach</code> 루프와 비슷하며, Java 1.5의 <code>for (int i : IntArray)</code>와 비슷합니다.

C/C++ 처럼 <code>for (int i = 0; i < 5; i++)</code> 와 같이 사용하고 싶은 경우, 파이썬에서는 단순히 <code>for iin range(0,5)</code>라고 입력하기만 하면 됩니다. 보시다시피, 파이썬의 <code>for</code> 루프는 더 단순하며,더 보기 좋고 오류가 발생하기도 어렵습니다.

9.4. break 문

<code>break</code> 문은 루프 문을 강제로 빠져나올 때, 즉 아직 루프 조건이 <code>False</code>가 되지 않았거나열거형의 끝까지 루프가 도달하지 않았을 경우에 루프 문의 실행을 강제로 정지시키고 싶을 때 사용됩니다.

중요한 점은 만약 여러분이 <code>break</code> 문을 써서 <code>for</code> 루프나 <code>while</code> 루프를 빠져나왔을 경우,루프에 딸린 <code>else</code> 블록은 실행되지 않습니다.

예제 (<code>break.py</code>로 저장하세요):

<code class="python language-python">while True:    s = raw_input('Enter something : ')    if s == 'quit':        break    print 'Length of the string is', len(s)print 'Done'</code>

실행 결과:

$ python break.pyEnter something : Programming is funLength of the string is 18Enter something : When the work is doneLength of the string is 21Enter something : if you wanna make your work also fun:Length of the string is 37Enter something : use Python!Length of the string is 11Enter something : quitDone
동작 원리

이 프로그램에서는 사용자의 입력을 반복해서 받고, 입력받은 문자열의 길이를 출력합니다.다만 사용자가 입력한 문자열이 <code>'quit'</code> 일 경우, <code>break</code>문으로 루프를 빠져나와프로그램을 정지하도록 특별한 조건을 넣어 주었습니다.

입력받은 문자열의 길이는 내장함수 <code>len</code> 을 이용하여 계산할 수 있습니다.

<code>break</code> 문은 <code>for</code> 루프 내에서도 이용될 수 있음을 기억하세요.

Swaroop의 파이썬 시

예제에서 입력한 것은 이 책의 저자가 작성한 작은 시입니다.

Programming is funWhen the work is doneif you wanna make your work also fun:    use Python!

9.5. <code>continue</code> 문

<code>continue</code> 문은 현재 실행중인 루프 블록의 나머지 명령문들을 실행하지 않고 곧바로다음 루프로 넘어가도록 합니다.

예제 (<code>continue.py</code> 로 저장하세요):

<code class="python language-python">while True:    s = raw_input('Enter something : ')    if s == 'quit':        break    if len(s) < 3:        print 'Too small'        continue    print 'Input is of sufficient length'    # Do other kinds of processing here...</code>

실행 결과:

$ python continue.pyEnter something : aToo smallEnter something : 12Too smallEnter something : abcInput is of sufficient lengthEnter something : quit
동작 원리

이 프로그램에서는 사용자로부터 입력을 받습니다만, 입력받은 문자열의 길이가 적어도 3 이상인 경우에만 문자열을 처리합니다.즉, 내장함수 <code>len</code> 을 통해 입력받은 문자열의 길이를 알아낸 후 그 길이가 3보다 작으면,<code>continue</code> 문을 이용하여 그 이하의 명령문을 실행하지 않고 다음 루프로 넘어가도록 합니다.입력받은 문자열의 길이가 3 이상일 경우에만 그 이하의 명령문이 실행되고, 지정된 작업이 실행됩니다.

<code>continue</code> 문은 <code>for</code> 루프 내에서도 이용될 수 있음을 기억하세요.

9.6. 요약

이 챕터에서는 <code>if</code>, <code>while</code>, <code>for</code> 세 종류의 흐름 제어문에 대해 배워 보았습니다. 또한 그와 같이 이용할 수 있는<code>break</code> 과 <code>continue</code>문에 대해서도 배웠습니다. 이 명령문들은 파이썬에서 가장 많이 사용되는 명령문들에 속해 있으며,따라서 이 명령문들에 친숙해지는 것은 필수입니다.

다음으로, 함수를 만들고 사용하는 방법에 대해 배워 보겠습니다.

10. 함수

함수는 재사용 가능한 프로그램의 조각을 말합니다. 이것은 특정 블록의 명령어 덩어리를묶어 이름을 짓고, 그 이름을 프로그램 어디에서건 사용함으로써 그 블록에 포함된 명령어들을몇번이고 다시 실행할 수 있게 하는 것입니다. 이를 보고 함수를 호출한다 라고 합니다.사실 우리는 이미 앞에서 <code>len</code> 이나 <code>range</code> 와 같은 많은 내장 함수들을 사용해 왔습니다.

이러한 함수라는 것은 프로그램을 작성할 때 아마도 가장 중요한 단위가 될 것입니다 (어떤프로그래밍 언어에서라도). 따라서 이 챕터에서는 함수라는 것을 다양한 관점에서 살펴보도록하겠습니다.

함수는 <code>def</code> 키워드를 통해 정의됩니다. <code>def</code> 뒤에는 함수의 식별자 이름을 입력하고,괄호로 감싸여진 함수에서 사용될 인자(arguments)의 목록을 입력하며 마지막으로 콜론을 입력하면함수의 정의가 끝납니다. 새로운 블록이 시작되는 다음 줄부터는 이 함수에서 사용될 명령어들을입력해 줍니다. 복잡해 보이지만, 아래 예제를 통해 함수를 정의하는 것이 얼마나 간단한지 알아봅시다.

예제 (<code>function1.py</code> 로 저장합니다):

<code class="python language-python">def say_hello():    # block belonging to the function    print 'hello world'# End of functionsay_hello() # call the functionsay_hello() # call the function again</code>

실행 결과:

$ python function1.pyhello worldhello world
동작 원리

여기에서는 위에서 설명한 문법을 이용하여 <code>say_hello</code> 라는 함수를 정의하였습니다.이 함수는 어떤 인자도 넘겨받지 않으므로, 괄호 내에 매개 변수를 정의하지 않습니다.함수의 인수란 함수로 넘겨지는 입력값들을 말하며, 함수는 이 값을 처리하여 결과를 넘겨줍니다.

함수를 두 번 호출하는 것은 같은 코드를 두 번 작성하는 것과 같은 효과를 가진다는 것을 알아두세요.

10.1. 함수와 매개 변수

함수를 정의할 때 매개 변수를 지정할 수 있습니다. 매개 변수란 함수로 넘겨지는 값들의 이름을 말하며,함수는 이 값들을 이용해 무언가를 수 있습니다. 매개 변수는 변수와 거의 같이 취급되지만,매개 변수의 값들은 함수가 호출되어질때 넘겨받은 값들로 채워지며 함수가 실행되는 시점에서는 이미할당이 완료되어 있다는 점이 다릅니다.

매개 변수는 함수를 정의할 때 괄호 안에 쉼표로 구분하여 지정합니다. 함수를 호출할 때에는, 동일한방법으로 함수에 값을 넘겨 줍니다. 이 때 함수를 정의할 때 주어진 이름을 매개 변수 라 부르고,함수에 넘겨준 값들을 인자 라 부릅니다.

예제 (<code>function_param.py</code> 로 저장하세요):

<code class="python language-python">def print_max(a, b):    if a > b:        print a, 'is maximum'    elif a == b:        print a, 'is equal to', b    else:        print b, 'is maximum'# directly pass literal valuesprint_max(3, 4)x = 5y = 7# pass variables as argumentsprint_max(x, y)</code>

실행 결과:

$ python function_param.py4 is maximum7 is maximum
동작 원리

여기서는 두 매개 변수 <code>a</code> 와 <code>b</code> 를 사용하는 <code>print_max</code> 라는 함수를 정의합니다. 그리고 간단한<code>if...else</code> 문을 이용하여 크기를 비교하고 둘 중에 더 큰 값을 출력합니다.

<code>print_max</code> 함수를 처음 호출할 때에는 값을 직접 인자로 입력하여 넘겨주었습니다. 반면 두 번째호출시에는 변수를 인자로 입력하여 주었습니다. 이것은 <code>print_max(x, y)</code> 는 변수 <code>x</code> 에 지정된값을 변수 <code>a</code> 에 입력해 주고 변수 <code>y</code> 의 값을 변수 <code>b</code> 에 입력해 주는 것을 의미합니다. 따라서이 함수는 두 경우 모두 동일하게 동작하게 됩니다.

10.2. 지역 변수

여러분이 정의한 함수 안에서 변수를 선언하고 사용할 경우, 함수 밖에 있는 같은 이름의 변수들과함수 안에 있는 변수들과는 서로 연관이 없습니다. 이러한 변수들을 함수의 지역(local) 변수라고하며, 그 범위를 변수의 스코프(scope) 라고 부릅니다. 모든 변수들은 변수가 정의되는 시점에서의블록을 스코프로 가지게 됩니다.

예제 (<code>function_local.py</code> 로 저장하세요):

<code class="python language-python">x = 50def func(x):    print 'x is', x    x = 2    print 'Changed local x to', xfunc(x)print 'x is still', x</code>

실행 결과:

$ python function_local.pyx is 50Changed local x to 2x is still 50
동작 원리

먼저 함수의 첫번째 줄에서 x 라는 이름을 가진 변수에 담긴 을 출력합니다. 이 때 함수 정의위에 정의된 변수의 값을 함수의 매개 변수 x로 넘겨받은 값이 출력됩니다.

다음으로, <code>x</code> 에 값 <code>2</code> 를 대입합니다. 그러나 <code>x</code> 는 함수의 지역 변수이므로, 함수 안에서 <code>x</code> 의값이 대입된 값으로 변하는 반면 메인 블록의 <code>x</code> 는 변하지 않고 그대로 남아 있습니다.

프로그램에서 사용된 마지막 <code>print</code> 문을 통해 메인 블록의 <code>x</code> 값을 출력해 보면, 그 이전에 호출된함수 안에서 시행된 지역 변수값의 변화가 적용되지 않았음을 확인할 수 있습니다.

10.3. <code>global</code> 문

함수나 클래스 내부에서 상위 블록에서 선언된 변수의 값을 변경하고 싶을 경우, 파이썬에게 이 변수를앞으로 지역 변수가 아닌 전역(global) 변수로 사용할 것임을 알려 주어야 합니다. 이때 <code>global</code> 문을이용합니다. <code>global</code> 문을 사용하지 않으면, 함수 외부에서 선언된 변수의 값을 함수 내부에서 변경할수 없습니다.

함수 안에서 동일한 이름으로 선언된 변수가 없을 경우, 함수 밖의 변수값을 함수 안에서 읽고 변경할 수도있습니다. 그러나, 이것은 프로그램을 읽을 때 변수가 어디서 어떻게 선언되었는지 파악하기 힘들게 만들기때문에 추천할만한 방법이 아니며, 가능한 이런 경우를 피하시기 바랍니다. <code>global</code> 문을 사용하면 그 블록의밖에서 그 변수가 선언되어 있음을 알려 주므로 좀 더 프로그램이 좀 더 명확해집니다.

예제 (<code>function_global.py</code> 로 저장하세요):

<code class="python language-python">x = 50def func():    global x    print 'x is', x    x = 2    print 'Changed global x to', xfunc()print 'Value of x is', x</code>

실행 결과:

$ python function_global.pyx is 50Changed global x to 2Value of x is 2
동작 원리

<code>global</code> 문을 통해 <code>x</code> 가 전역 변수임을 파이썬에게 알려 줍니다. 따라서, 이후로 <code>x</code> 에 값을 대입하면메인 블록의 <code>x</code> 값 또한 변경됩니다.

하나의 <code>global</code> 문으로 여러 개의 전역 변수를 동시에 지정해 줄 수도 있습니다. <code>global x, y, z</code>와 같이 하면 됩니다.

10.4. 기본 인수값

어떤 특별한 경우, 함수를 호출할 때 인수를 선택적으로 넘겨주게 하여 사용자가 값을 넘겨주지않으면 자동으로 기본값을 사용하도록 하는 것이 편할 때가 있습니다. 이런 경우, 기본 인수값을지정하면 됩니다. 함수를 선언할 때 원하는 매개 변수 뒤에 대입 연산자 (<code>=</code>)와 기본값을입력하여 기본 인수값을 지정합니다.

이 때, 기본 인수값은 반드시 상수이어야 합니다. 좀 더 정확히 말하자면, 불변값이어야 합니다.불변값에 대해서는 뒤 챕터에서 다룰 것입니다. 일단 지금은, 그래야 한다는 것만 기억해 두기 바랍니다.

예제 (<code>function_default.py</code> 로 저장하세요):

<code class="python language-python">def say(message, times=1):    print message * timessay('Hello')say('World', 5)</code>

실행 결과:

$ python function_default.pyHelloWorldWorldWorldWorldWorld
동작 원리

함수 <code>say</code> 는 지정된 숫자 만큼 문자열을 반복하여 출력하는 합수입니다. 숫자를 지정하지 않으면,기본값이 적용되어, 문자열이 한 번 출력됩니다. 이 결과는 매개 변수 <code>times</code> 의 기본 인수값을 <code>1</code> 로지정해 줌으로써 얻어집니다.

프로그램에서 처음 <code>say</code> 를 호출할 때에는 함수에 문자열만 넘겨 주어 한번 출력하게 합니다. 두 번째호출에서는 문자열과 인수 <code>5</code> 를 넘겨 주어 함수가 문자열을 5번 반복하여 말(say)하게 합니다.

[주의]

매개 변수 목록에서 마지막에 있는 매개 변수들에만 기본 인수값을 지정해 줄 수 있습니다. 즉,기본 인수값을 지정하지 않은 매개 변수의 앞에 위치한 매개 변수에만 기본 인수값을 지정할 수 없습니다.

이것은 함수 를 호출할 때 매개 변수의 위치에 맞춰서 값이 지정되기 때문입니다. 예를 들어, <code>def func(a,b=5)</code> 는 옳은 함수 정의이지만 <code>def func(a=5, b)</code> 는 옳지 않습니다.

10.5. 키워드 인수

여러 개의 매개 변수를 가지고 있는 함수를 호출할 때, 그 중 몇 개만 인수를 넘겨주고 싶을 때가있습니다. 이때 매개 변수의 이름을 지정하여 직접 값을 넘겨줄 수 있는데 이것을 키워드 인수 라 부릅니다.함수 선언시 지정된 매개 변수의 순서대로 값을 넘겨주는 것 대신, 매개 변수의 이름 (키워드) 를 사용하여각각의 매개 변수에 인수를 넘겨 주도록 지정해 줍니다.

키워드 인수를 사용하는 데 두가지 장점이 있습니다. 첫째로, 인수의 순서를 신경쓰지 않고도 함수를쉽게 호출할 수 있는 점입니다. 둘째로는, 특정한 매개 변수에만 값을 넘기도록 하여 나머지는 자동으로기본 인수값으로 채워지게 할 수 있습니다.

예제 (<code>function_keyword.py</code> 로 저장하세요):

<code class="python language-python">def func(a, b=5, c=10):    print 'a is', a, 'and b is', b, 'and c is', cfunc(3, 7)func(25, c=24)func(c=50, a=100)</code>

실행 결과:

$ python function_keyword.pya is 3 and b is 7 and c is 10a is 25 and b is 5 and c is 24a is 100 and b is 5 and c is 50
동작 원리

위의 <code>func</code> 라 이름 지어진 함수는 기본 인수값이 지정되지 않은 한 개의 매개 변수와, 기본 인수값이지정된 두 개의 매개 변수, 총 세 개의 매개 변수를 가지고 있습니다.

첫 번째 호출 <code>func(3, 7)</code> 에서, 매개 변수 <code>a</code> 는 값 <code>3</code>, 매개 변수 <code>b</code> 는 <code>7</code> 을 넘겨 받으며,<code>c</code> 에는 기본 인수값 <code>10</code> 이 주어집니다.

두 번째 호출 <code>func(25, c=24)</code> 에서는, 첫 번째 인수인 25가 변수 <code>a</code> 에 넘겨집니다. 그리고매개 변수 <code>c</code> 는 키워드 인수를 통해 값 <code>24</code> 가 지정되며, 변수 <code>b</code> 에는 기본값 <code>5</code> 가 주어집니다.

세 번째 호출 <code>func(c=50, a=100)</code> 에서는, 모든 값을 지정하는 데 키워드 인수가 사용됩니다. 함수 정의에는<code>a</code> 다음에 <code>c</code> 가 정의되어 있지만, 키워드 인수를 사용하면 그 순서에 상관없이 <code>c</code> 를 먼저 지정하고<code>a</code> 를 나중에 지정할 수도 있다는 점을 기억하세요.

10.6. VarArgs 매개 변수

가끔 함수에 임의의 개수의 매개 변수를 지정해주고 싶을 때가 있습니다. 이때 VarArgs 매개 변수를사용합니다. 아래 예제와 같이 별 기호를 사용하여 임의의(Variable) 개수의 인수(Arguments)를 표현합니다.

예제 (<code>function_varargs.py</code> 로 저장하세요):

<code class="python language-python">def total(initial=5, *numbers, **keywords):    count = initial    for number in numbers:        count += number    for key in keywords:        count += keywords[key]    return countprint total(10, 1, 2, 3, vegetables=50, fruits=100)</code>

실행 결과:

$ python function_varargs.py166
동작 원리

앞에 별 기호가 달린 매개 변수, 예를 들어 <code>*param</code> 과 같이 매개 변수를 지정해 주면함수에 넘겨진 모든 위치 기반 인수들이 param 이라는 이름의 튜플로 묶여서 넘어옵니다.

비슷하지만 조금 다르게, 앞에 별 두 개가 달린 매개 변수, 예를 들어 <code>**param</code> 과 같이매개 변수를 지정해 주면 함수에 넘겨진 모든 키워드 인수들이 사전의 param 이라는 이름의사전으로 묶에서 넘어옵니다.

튜플과 사전에 대해서는 뒤 챕터에서 좀 더 자세히 다뤄보도록 하곘습니다.

10.7. <code>return</code> 문

<code>return</code> 문은 함수로부터 되돌아(return) 나올 때, 즉 함수를 빠져 나올 때 사용됩니다. 이 때<code>return 값</code> 처럼 값을 지정해 주면, 함수가 종료될 때 그 값을 반환하도록 할 수 있습니다.

예제 (<code>function_return.py</code> 로 저장하세요):

<code class="python language-python">def maximum(x, y):    if x > y:        return x    elif x == y:        return 'The numbers are equal'    else:        return yprint maximum(2, 3)</code>

실행 결과:

$ python function_return.py3
동작 원리

여기에서 사용된 <code>maximum</code> 함수는 매개 변수들 중 최대 값을 반환합니다. 위 경우에는 함수에 넘겨진숫자들 중 최대값을 반환합니다. 간단한 <code>if..else</code> 구문을 통해 더 큰 값을 찾고, 최종 값을 반환(return)합니다.

<code>return</code> 문 뒤에 아무 값도 지정하지 않는 경우, <code>return None</code> 을 실행하는 것과 같습니다. <code>None</code> 이란파이썬에서 사용되는 특별한 형식으로 아무것도 없음을 의미합니다. 예를 들면, 어떤 변수의 값이 <code>None</code> 이라는것은 변수에 할당된 값이 없다는 것을 의미합니다.

여러분이 <code>return</code> 문을 함수에 지정하지 않으면, 함수는 끝날 때 자동으로 <code>return None</code> 구문을 암시적으로호출합니다. 아래 예제에서 <code>return</code> 문이 지정되지 않은 <code>some_function</code> 이라는 함수를 선언하고<code>print some_function()</code> 을 실행하여 그 결과를 확인해 보시기 바랍니다.

<code class="python language-python">def some_function():    pass</code>

<code>pass</code> 문은 아무 기능이 없는 구문입니다. 이것은 빈 블록을 지정해 줄 때 사용됩니다.

Tip
사실 파이썬에는 최대값을 찾는 내장 함수 <code>max</code> 가 이미 포함되어 있습니다.따라서 가능하면 이 내장 함수를 사용하시기 바랍니다.

10.8. DocString

파이썬은 설명(Documentation) 문자열(String) 이라고 불리우는, 짧게 줄여서 DocStrings라 불리우는편리한 기능을 가지고 있습니다. DocString은 여러분이 만든 프로그램을 알아보기 쉽게 해 주고,또 후에 프로그램에 대한 설명서를 작성할 때 유용하게 사용될 수 있는 중요한 도구입니다.아래 예제와 같이, DocString은 프로그램이 실행중일 때도 읽어올 수 있습니다.

예제 (<code>function_docstring.py</code> 로 저장하세요):

<code class="python language-python">def print_max(x, y):    '''Prints the maximum of two numbers.    The two values must be integers.'''    # convert to integers, if possible    x = int(x)    y = int(y)    if x > y:        print x, 'is maximum'    else:        print y, 'is maximum'print_max(3, 5)print print_max.__doc__</code>

실행 결과:

$ python function_docstring.py5 is maximumPrints the maximum of two numbers.    The two values must be integers.
동작 원리

함수에 포함된 첫 논리적 명령행에 적어둔 문자열은 함수의 DocString 이라고 불리우는 것입니다.여기에서 설명하는 DocString은 모듈클래스 에도 똑같이 적용됩니다.각각에 대해서는 각 챕터에서 좀 더 자세히 알아보도록 하겠습니다.

DocString은 일반적으로 첫째줄의 첫문자는 대문자로, 마지막 문자는 마침표로 끝나도록작성합니다. 그리고 두번째 줄은 비워 두고, 세번째 줄부터는 이것이 어떤 기능을 하는지에 대해상세하게 작성합니다. 저는 앞으로 여러분이 함수의 DocString를 작성할 때 이 규칙을 따르기를강력히 권합니다.

<code>print_max</code> 함수의 DocString은 함수의 <code>__doc__</code> 속성을 통해 접근할 수 있습니다 (밑줄이 두 개임을 다시한번 확인하세요). <code>__doc__</code> 은 함수 객체가 갖고 있는 기본 속성입니다. 파이썬에서는함수를 포함한 모든 것이 객체로 다루어진다는 점을 기억하세요. 이에 대해서는 클래스챕터에서 좀 더 자세히 알아볼 것입니다.

파이썬에서 <code>help()</code> 를 이용해 보셨다면, 여러분은 이미 DocString을 본 적이 있는 것입니다!<code>help()</code> 가 하는 일은 주어진 대상의 <code>__doc__</code> 속성을 가져와 화면에 보여주는 것 뿐입니다.따라서 위에서 만든 함수에 대해서도 마찬가지로 동작합니다. 여러분의 프로그램에 <code>help(print_max)</code>라고 한 줄 추가해 보시기 바랍니다. <code>help</code> 창을 닫으려면 <code>q</code> 키를 누르세요.

이를 이용하여 여러분의 프로그램에 대한 명세서를 자동으로 만들어주는 프로그램들이 있습니다.따라서, 저는 여러분이 어떤 함수를 작성하시던지 DocString을 작성할 것을 강력히 권합니다.파이썬과 함께 설치되는 <code>pydoc</code> 또한 <code>help()</code> 와 비슷한 방법으로 DocString을 이용하여 동작합니다.

10.9. 요약

지금까지 함수에 대해 많은 것들을 알아 보았습니다만, 사실 아직 모든 기능을 다 알아본 것은 아닙니다.그러나, 실제적으로 사용되는 기능에 대해서는 거의 모든 것을 설명해 드렸기 때문에 아마 앞으로매일매일 프로그램을 작성할 때는 별 무리가 없을 것입니다.

다음으로는, 모듈을 작성하고 사용하는 방법에 대해 알아보도록 하겠습니다.

11. 모듈

앞에서 함수를 통해 여러분의 프로그램 안에서 코드를 재사용하는 방법에 대해서 배워 보았습니다. 그러면여러 함수들을 한꺼번에 불러들여 재사용하는 방법은 없을까요? 네, 이럴 때 모듈을 이용합니다.

모듈을 작성하는 데에는 여러가지 방법이 있습니다만, 가장 간단한 방법은 <code>.py</code> 확장자를 가진 파일을하나 만들고 그 안에 함수들과 변수들을 정의해 두는 것입니다.

모듈을 작성하는 또 한 가지 방법은 여러분이 현재 사용중인 파이썬 인터프리터를 만드는데 사용되는프로그래밍 언어로 모듈을 작성하는 것입니다. 예를 들어, 표준 파이썬 인터프리터를 사용 중인 경우C 언어를 이용하여 모듈을 작성하고 컴파일하면 파이썬에서 이것을불러와 사용할 수 있습니다.

다른 프로그램에서 import 명령을 통해 모듈을 불러와 사용할 수 있습니다. 파이썬 표준 라이브러리 또한동일한 방법을 통해 이용이 가능합니다. 일단, 표준 라이브러리를 불러와 사용하는 방법을 알아보도록하겠습니다.

예제 (<code>module_using_sys.py</code> 로 저장하세요):

<code class="python language-python">import sysprint('The command line arguments are:')for i in sys.argv:    print iprint '\n\nThe PYTHONPATH is', sys.path, '\n'</code>

실행 결과:

$ python module_using_sys.py we are argumentsThe command line arguments are:module_using_sys.pyweareargumentsThe PYTHONPATH is ['/tmp/py',# many entries here, not shown here'/Library/Python/2.7/site-packages','/usr/local/lib/python2.7/site-packages']
동작 원리

먼저, 표준 라이브러리 중 하나인 <code>sys</code> 모듈을 <code>import</code> 문을 통해 불러왔습니다. 이것은 단순히 파이썬에게이 모듈을 앞으로 사용할 것이라고 알려주는 과정이라고 생각하시면 편합니다. 여기서 사용된 <code>sys</code> 모듈은파이썬 인터프리터와 인터프리터가 실행중인 환경, 즉 시스템(system)에 관련된 기능들이 담겨 있습니다.

파이썬이 <code>import sys</code> 문을 실행하는 시점에서, 파이썬은 <code>sys</code> 모듈을 찾습니다. 이 경우에는 내장 모듈을불러오는 것이므로, 파이썬이 이미 어디서 이것을 불러와야 하는지 알고 있습니다.

만약 그렇지 않은 경우, 예를 들어 파이썬으로 여러분이 직접 작성한 모듈인 경우 파이썬 인터프리터는<code>sys.path</code> 변수 에 정의된 디렉토리들에 해당 모듈이 있는지 검색합니다. 그리고 나서 모듈을 찾아내면,그 모듈 내부에 적혀있는 명령들이 읽어들여지게 되며 그 다음부터 모듈이 사용가능하게 됩니다. 이러한초기화 과정은 첫번째로 모듈을 불러올 때만 이루어진다는 것을 기억하세요.

<code>sys</code> 모듈의 <code>argv</code> 변수를 불러올 때, 마침표를 이용하여 <code>sys.argv</code> 와 같이 접근합니다. 이와 같이마침표를 이용함으로써 뒤에 온 이름이 <code>sys</code> 모듈에 존재한다는 것을 명시적으로 알려 주고, 또한 여러분의프로그램에 사용될지 모를 <code>argv</code> 라는 이름을 가진 다른 변수와 충돌이 일어나지 않도록 합니다.

<code>sys.argv</code> 변수는 문자열의 리스트 입니다 (리스트에 대해서는 뒤 챕터에서 좀 더자세히 다룰 것입니다). 좀 더 구체적으로 <code>sys.argv</code> 가 담고 있는 것은 명령줄 인수들의 리스트인데,이것은 명령줄로부터 프로그램을 실행시킬 때 함께 넘어온 인수들을 담고 있는 것입니다.

여러분이 프로그램을 작성하고 실행할 때 IDE(Integrated Development Environment, 통합 개발 환경를이용하시는 경우, IDE 상에서 프로그램을 실행할 때 명령줄 인수를 지정하는 방법에 대해 알아보시기 바랍니다.

여기서는 명령줄에서 직접 <code>python module_using_sys.py we are arguments</code> 명령을 통해 실행하였습니다.이것은 <code>python</code> 명령을 통해 <code>module_using_sys.py</code> 모듈을 실행시키고 함께 적어준 명령줄 인수들을실행될 프로그램에 넘겨준 것입니다. 그러면 파이썬은 <code>sys.argv</code> 변수에 이것을 저장해 주며 프로그램에서사용할 수 있도록 합니다.

이 때, 여러분이 실행한 스크립트의 이름이 <code>sys.argv</code> 리스트의 첫번째 항목이 됨을 기억하세요. 즉,이 경우 <code>'module_using_sys.py'</code> 가 <code>sys.argv[0]</code> 에 해당하며, <code>'we'</code> 는 <code>sys.argv[1]</code> 에,<code>'are'</code> 는 <code>sys.argv[2]</code> 에, <code>'arguments'</code> 는 <code>sys.argv[3]</code> 에 해당합니다. 파이선은 숫자를 0부터센다는 점을 기억하세요 (1이 아닙니다!).

<code>sys.path</code> 변수에는 모듈을 불러올 때 찾게 되는 디렉토리들의 리스트가 담겨 있습니다. <code>sys.path</code> 변수의첫 번째 항목이 공백 문자열임을 확인하세요. 공백 문자열은 현재 디렉토리를 의미하는데, 따라서 이것은현재 디렉토리 또한 <code>sys.path</code> 의 일부임을 의미하며 이것은 <code>PYTHONPATH</code> 환경변수의 경우와도 같습니다.즉, 여러분은 현재 디렉토리에 들어 있는 파이썬 모듈을 불러와 사용할 수 있는 것입니다. 그렇지 않은 경우,<code>sys.path</code> 에 지정된 디렉토리들 중 하나에 해당 모듈이 들어 있어야 합니다.

이때 현재 디렉토리란 프로그램을 실행할 때 위치하고 있는 디렉토리를 말합니다. <code>import os; printos.getcwd()</code> 를 실행하여 여러분의 프로그램에서 현재 디렉토리가 어디인지 확인할 수 있습니다.

11.1. 바이트 컴파일된 .pyc 파일

모듈을 불러오는 것은 상대적으로 무거운 작업이기 때문에, 파이썬은 약간의 트릭을 사용해서 좀 더이 과정을 빠르게 수행할 수 있게 합니다. 그것은 바로 <code>.pyc</code>의 확장자를 가지는 바이트 컴파일된,일종의 중간 단계의 파일을 만들어 두는 것입니다 (입문 섹션에서 파이썬의 인터프리터환경에 대해 설명했었죠?). 이러한 <code>.pyc</code> 파일은 다른 프로그램에서 그 모듈을 다시 필요로 할 때사용되며, 이 경우 모듈을 읽어들이는 데 필요한 몇가지 선행 작업을 수행하지 않아도 되게 되어더 빨리 모듈을 불러올 수 있습니다. 또한, 이렇게 바이트 컴파일된 파일은 플랫폼에 구애받지 않습니다.

Note
<code>.pyc</code> 파일은 <code>.py</code> 파일이 저장되어 있는 디렉토리에 새롭게 생성됩니다. 파이썬이 이 디렉토리에쓰기 권한을 가지고 있지 못한 경우, <code>.pyc</code> 파일은 생성되지 않을 것입니다.

11.2. from … import 문

매번 <code>sys.</code> 를 입력하지 않고서도 <code>argv</code> 변수를 프로그램에서 곧바로 불러와서 사용할 수도 있습니다.이런 경우, <code>from sys import argv</code> 와 같은 구문을 이용합니다.

하지만 식별자 이름간의 충돌을 피하고 프로그램을 좀 더 읽기 쉽게 작성하기 위해서, 가능하면이렇게 사용하는 경우를 피하고 <code>import</code> 문을 사용하기를 권합니다.

예제:

<code class="python language-python">from math import sqrtprint "Square root of 16 is", sqrt(16)</code>

11.3. 모듈의 <code>__name__</code> 속성

모든 모듈은 이름을 갖고 있으며, 모듈 내에 포함된 명령을 통해 모듈의 이름을 알아올 수 있습니다.이 속성은 현재 모듈이 불러들여져서 사용되고 있는지 아니면 인터프리터에서 곧바로 실행된 것인지를구문하는데 편리하게 사용될 수 있습니다. 이전에 알아보았지만, 모듈 내부의 코드는 모듈이 첫번째로불러들여졌을 때 실행되게 됩니다. 이러한 속성을 통해 모듈이 외부로부터 불러들여졌을 때와 곧바로실행되었을 때에 각각 다르게 처리하도록 할 수 있습니다. 이를 위해 <code>__name__</code> 속성을 사용합니다.

예제 (<code>module_using_name.py</code> 로 저장하세요):

<code class="python language-python">if __name__ == '__main__':    print 'This program is being run by itself'else:    print 'I am being imported from another module'</code>

실행 결과:

$ python module_using_name.pyThis program is being run by itself$ python>>> import module_using_nameI am being imported from another module>>>
동작 원리

모든 파이썬 모듈은 <code>__name__</code> 속성을 가지고 있습니다. 만약 그 이름이 <code>'__main__'</code>일 경우, 이것은모듈이 사용자로부터 직접 실행된 것임을 의미하며 따라서 이에 맞는 적절한 처리를 해 줄 수 있습니다.

11.4. 새로운 모듈 작성하기

모듈을 작성하는 것은 쉽습니다. 사실은 여러분이 지금까지 해 왔던 것과 별 다를게 없습니다! 왜냐하면모든 파이썬 프로그램은 곧 모듈이기 때문입니다. 즉 <code>.py</code> 확장자를 가진 이름으로 저장되기만 하면됩니다. 아래 예제를 통해 이에 대해 좀 더 분명하게 알 수 있을 것입니다.

예제 (<code>mymodule.py</code> 로 저장하세요):

<code class="python language-python">def say_hi():    print 'Hi, this is mymodule speaking.'__version__ = '0.1'</code>

위 예제는 모듈 예시입니다. 보시는 바와 같이, 지금까지 작성해왔던 파이썬 프로그램들에 비해 별다른특별한 것이 없습니다. 다음으로는 다른 파이썬 프로그램으로부터 이 모듈을 불러와서 사용하는 방법을알아보겠습니다.

아래 예제를 실행시키기 전에, 위 예제 프로그램 파일이 아래 예제 프로그램과 같은 디렉토리에 있거나혹은 <code>sys.path</code> 중 하나에 있어야 제대로 불러올 수 있음을 기억하세요.

모듈 불러오기 예제 (<code>mymodule_demo.py</code> 로 저장하세요):

<code class="python language-python">import mymodulemymodule.say_hi()print 'Version', mymodule.__version__</code>

실행 결과:

$ python mymodule_demo.pyHi, this is mymodule speaking.Version 0.1
동작 원리

모듈의 구성 요소에 접근하는 데에도 앞서 알아보았던 것과 동일하게 마침표를 이용하여 접근합니다.파이썬은 같은 일을 하는 데 같은 표기법을 사용합니다. 따라서 뭔가 새로운 일을 하기 위해 새로운것을 또 배울 필요가 없습니다. 프로그래머들은 이런 것들이 파이썬 특유의 파이썬스러운 느낌을주게 한다고 말합니다.

아래는 <code>from..import</code> 구문을 사용하는 예제입니다 (<code>mymodule_demo2.py</code>로 저장하세요):

<code class="python language-python">from mymodule import say_hi, __version__say_hi()print 'Version', __version__</code>

<code>mymodule_demo2.py</code> 를 실행한 결과는 <code>mymodule_demo.py</code> 의 결과와 같습니다.

만약 mymodule을 불러올 때 <code>__version__</code> 이라는 이름이 이미 모듈에 선언되어 있었다면, 충돌이 일어날것입니다. 사실 이 경우는 각 모듈의 버전을 이 이름으로 주로 선언해 두기 때문에 실제로 자주 일어나는일이기도 합니다. 따라서, 프로그램이 조금 길어지는 한이 있더라도 왠만하면 <code>import</code> 문을 이용하여프로그램을 작성하기를 권합니다.

아래와 같이 사용할 수도 있습니다:

<code class="python language-python">from mymodule import *</code>

이것은 <code>say_hi'와 같이 모듈에 포함된 모든 공개된 이름들을 불러옵니다. 그러나 밑줄 두 개로 시작하는`__version__</code> 과 같은 이름들은 불러오지 않습니다.

주의: 가능하면 <code>from mymodule import *</code> 처럼 사용하는 것을 피하시기 바랍니다.

Zen of Python (파이썬 정신)

파이썬의 여러 지향점 중 하나는 "명시적인 것이 암시적인 것 보다 낫다 (Explicit is better thanImplicit)" 입니다. 파이썬에서 <code>import this</code> 를 실행하여 다른 지향점들에 대해 알아보세요. 또한 이StackOverflow 에서의 토론을 통해 각각의규칙에 해당하는 예제들을 확인해 보시기 바랍니다.

11.5. <code>dir</code> 내장 함수

<code>dir</code> 내장 함수를 이용하여 객체에 정의되어 있는 식별자들의 목록을 불러올 수 있습니다.예를 들어, 모듈의 경우 함수와 클래스 및 변수들의 식별자 이름이 정의되어 있을 것입니다.

<code>dir()</code> 함수에 모듈 이름을 넘겨 주면, 모듈 안에 선언된 식별자 이름들의 목록을 반환해 줍니다.아무것도 넘겨주지 않는 경우, 현재 모듈에 선언된 식별자 이름들의 목록이 반환됩니다.

예제:

$ python>>> import sys# sys 모듈 내에 선언된 속성들의 식별자 이름 목록>>> dir(sys)['__displayhook__', '__doc__','argv', 'builtin_module_names','version', 'version_info']# 실제로는 너무 길어 여기에는 몇 개만 적었음# 현재 모듈에 선언된 속성들의 식별자 이름 목록>>> dir()['__builtins__', '__doc__','__name__', '__package__']# 새로운 변수 'a' 생성>>> a = 5>>> dir()['__builtins__', '__doc__', '__name__', '__package__', 'a']# 식별자 이름 제거>>> del a>>> dir()['__builtins__', '__doc__', '__name__', '__package__']
동작 원리

먼저 <code>dir</code> 함수를 통해 앞서 불러온 <code>sys</code> 모듈의 식별자 정보를 읽어옵니다. 그러면 내부에 포함된긴 식별자 이름 목록이 나타나는 것을 확인할 수 있습니다.

다음으로, <code>dir</code> 함수를 아무 인수도 넘기지 않고 실행시킵니다. 그러면 기본값으로, 현재 모듈에 선언된식별자 목록이 나타납니다. 이 때 앞서 불러온 모듈의 이름도 이 목록에 포함되어 있음을 확인하세요.

이제 <code>dir</code> 가 잘 작동하는지 확인하기 위해, 새로운 변수 <code>a</code> 를 선언하고 값을 할당해 준 뒤<code>dir</code> 함수를 실행시켜 반환되는 목록에 새로 생성된 변수가 포함되어 있는지 확인합니다. <code>del</code> 문을이용하여 현재 모듈에 선언된 변수 혹은 속성을 제거하면 <code>dir</code> 함수의 출력에 그 결과가 반영됨을 또한알 수 있습니다.

<code>del</code> 문은 변수 혹은 이름을 삭제(delete)하는데 사용되며 이 구문이 실행된 이후에는, 즉 위 예제의경우에는 <code>del a</code> 를 실행한 이후에는, 더 이상 변수 <code>a</code> 에 접근할 수 없습니다. 마치 처음부터 이러한변수가 존재하지 않았던 것처럼 말입니다.

<code>dir()</code> 함수는 어떤 객체에도 사용될 수 있습니다. <code>dir('print')</code> 를 실행하면 print 함수의 속성에대해 알아볼 수 있으며, <code>dir(str)</code> 를 실행하면 str 클래스의 속성에 대해서도 알아볼 수 있습니다.

파이썬에는 정의된 속성과 그 값을 읽어오는 데 사용될 수 있는<code>vars()</code> 함수 또한 존재합니다만,이 함수는 모든 경우에서 동작하지는 않습니다.

11.6. 패키지

지금까지 여러분은 파이썬 프로그램의 계층 구조에 대해 어느정도 파악이 되셨을 것입니다.변수는 함수 내부에 존재하며, 함수와 전역 변수는 모듈 안에 존재합니다. 그렇다면 모듈은어디에 포함되는 것일까요? 파이썬에서는 패키지라는 단위가 이에 해당됩니다.

패키지란 그냥 단순한 폴더입니다만, 파이썬에게 이 폴더는 파이썬 모듈을 담고 있다는 것을알려 주는 역할을 하는 <code>__init__.py</code> 라는 특별한 파일을 한 개 포함하고 있습니다.

여러분이 asia, africa라는 하위 패키지를 포함하고 있는 world 라는 패키지를 만들고싶다고 가정해 봅시다. 또한 각각의 하위 패키지는 india, madagascar 등등의 하위 패키지를하나씩 더 갖고 있습니다.

이 경우, 아래와 같이 폴더 구조를 만들어 주면 됩니다:

- <some folder="" present="" in="" the="" sys.path="">/    - world/        - __init__.py        - asia/            - __init__.py            - india/                - __init__.py                - foo.py        - africa/            - __init__.py            - madagascar/                - __init__.py                - bar.py</some>

패키지는 계층적으로 모듈을 관리할 수 있게 편의상 구성하는 것입니다. 표준 라이브러리에서이러한 계층 구조를 많이 확인하실 수 있을 것입니다.

11.7. 요약

함수가 재사용 가능한 프로그램의 한 부분인 것과 같이 모듈은 재사용 가능한 프로그램을 말하며,패키지는 모듈을 구성하는 계층 구조를 말합니다. 파이썬과 함께 설치되는 표준 라이브러리는 이러한패키지와 모듈로 이루어진 한 예제입니다.

지금까지 모듈을 사용하고 작성하는 방법에 대해 알아보았습니다.

다음으로, 자료 구조라고 불리우는 개념에 대해 알아보도록 합시다.

12. 자료 구조

자료 구조란 간단하게, 어떤 자료를 담는 구조를 말합니다. 다른 말로 하면, 서로 연관있는 어떤자료들의 집합을 저장하는 데 사용됩니다.

파이썬에는 네 종류의 자료 구조가 있는데, 각각 리스트, 튜플, 사전, 집합입니다. 이제 앞으로각각의 사용법에 대해 알아보고 또 각각이 얼마나 편리한지 확인해보도록 하겠습니다.

12.1. 리스트

리스트란 순서대로 정리된 항목들을 담고 있는 자료 구조입니다. 즉, 리스트에는 항목의 목록을저장할 수 있습니다. 이것은 쉽게 말하자면 장 보러 갈 때 적는 일종의 장바구니 목록 같은 것인데,아마도 여러분은 각 품목들을 한줄 한줄 적겠지만 파이썬에서는 쉼표로 각 항목을 구분한다는 것만다릅니다.

리스트를 정의할 때는 대괄호 <code>[]</code> 를 이용해서 파이썬에게 이것이 리스트를 의미한다는 것을 알려 줍니다.한번 리스트를 만들어 두면 여기에 새로운 항목을 추가하거나 삭제할 수 있으며, 특정 항목이 존재하는지검색할 수도 있습니다. 이 때 항목을 추가 및 삭제가 가능하다는 것을 비정적(mutable)이라고 하며,리스트는 비정적 자료구조로 내부 항목을 변경할 수 있습니다.

12.2. 객체와 클래스에 대한 간단한 소개

객체와 클래스에 대해서는 좀 더 나중에 다룰 예정이지만, 여기서 여러분이 리스트에 대해 좀 더 잘이해하실 수 있도록 이에 대한 간단한 소개를 하도록 하겠습니다. 이들에 대해서는 뒤 챕터에서좀 더 자세하게 다루겠습니다.

리스트는 객체와 클래스가 사용된 한 예입니다. 변수 <code>i</code> 를 선언하고 예를 들어 <code>5</code> 라는 값을 할당해주는 것은, <code>int</code> 라는 클래스(또는 타입)의 객체(또는 인스턴스) <code>i</code> 를 만드는 것입니다.이에 대해 좀 더 자세히 알아보시려면 <code>help(int)</code> 를 읽어보시기 바랍니다.

클래스는 메소드를 가질 수 있는데, 여기서 메소드란 그 클래스 내에 정의된 고유의 내장 함수들을말합니다. 또 이러한 내장 함수들은 클래스로 객체를 생성했을 때에야 비로소 사용할 수 있습니다. 예를 들어,파이썬은 <code>list</code> 클래스에 <code>append</code> 라는 메소드를 제공하며 이는 리스트의 마지막에 항목을 한 개 추가할때 사용되는 메소드입니다. 즉 <code>mylist.append('an item')</code> 라 하면 리스트 <code>mylist</code> 의 마지막에 해당문자열을 추가해 줍니다. 이 때 객체의 메소드에 접근할 때에도 마침표를 이용한다는 점을 기억하세요.

또 클래스는 필드를 가질 수 있는데 이것은 단순히 그 클래스 내에 정의된 변수들을 의미합니다.메소드와 마찬가지로 이러한 변수들은 클래스로 객체를 생성했을 때에야 비로소 사용할 수 있습니다.필드도 메소드와 마찬가지로 마침표를 이용하여 접근합니다. 예를 들면 <code>mylist.field</code> 와 같습니다.

예제 (<code>ds_using_list.py</code> 로 저장하세요):

<code class="python language-python"># This is my shopping listshoplist = ['apple', 'mango', 'carrot', 'banana']print 'I have', len(shoplist), 'items to purchase.'print 'These items are:',for item in shoplist:    print item,print '\nI also have to buy rice.'shoplist.append('rice')print 'My shopping list is now', shoplistprint 'I will sort my list now'shoplist.sort()print 'Sorted shopping list is', shoplistprint 'The first item I will buy is', shoplist[0]olditem = shoplist[0]del shoplist[0]print 'I bought the', olditemprint 'My shopping list is now', shoplist</code>

실행 결과:

$ python ds_using_list.pyI have 4 items to purchase.These items are: apple mango carrot bananaI also have to buy rice.My shopping list is now ['apple', 'mango', 'carrot', 'banana', 'rice']I will sort my list nowSorted shopping list is ['apple', 'banana', 'carrot', 'mango', 'rice']The first item I will buy is appleI bought the appleMy shopping list is now ['banana', 'carrot', 'mango', 'rice']
동작 원리

여러분이 장 보러 갈 때 장바구니 목록을 변수 <code>shoplist</code> 에 담아 두었다고 합시다. <code>shoplist</code> 에는,구매할 항목들의 이름 문자열들만이 담겨 있습니다만 사실 리스트에는 어떤 종류의 객체든지 담을 수있으며 숫자라던지 심지어는 리스트 안에 리스트도 담을 수 있습니다.

여기서는 <code>for..in</code> 반복문을 사용하여 리스트 안에 담겨 있는 항목들을 하나씩 반복하여 읽어왔습니다.지금쯤 여러분은 리스트가 하나의 열거 형식의 예가 됨을 알게 되셨을 것입니다. 열거 형식의 특수성에대해서는 뒤 섹션에서 다루겠습니다.

<code>print</code> 문 맨 뒤에 추가한 쉼표는 출력될 내용 뒤에 줄바꿈 기호 대신 공백을 출력하도록 지정해 준것입니다. 쉼표는 파이썬에게 앞으로 출력될 내용을 같은 줄에 이어서 출력하라고 알려 주는 것이라고생각하시기 바랍니다.

다음으로, 앞서 설명했던 리스트 객체의 <code>append</code> 메소드를 이용해서 리스트에 항목을 한 개 추가합니다.그리고, 추가된 항목이 제대로 추가되었는지 확인하기 위해 <code>print</code> 문에 리스트를 넘겨 주어 리스트의내용을 화면에 예쁘게 출력하게 해 줍니다.

이제 리스트의 <code>sort</code> 메소드를 이용하여 리스트의 내용을 정렬해 줍니다. 여기서 이 메소드는 해당리스트 자체를 변화시키며 수정된 리스트를 또 반환해주지 않는데 이 점을 이해하는 것이 중요합니다.즉 정적인 문자열과 달리 리스트는 변화될 수 있는 성질을 지녔으며 이것을 비정적이라 합니다.

다음으로 시장에서 물건을 구매하면 이제 장바구니 목록에서 해당 항목을 지워야 할 것입니다. 이 때<code>del</code> 문을 사용하여 항목을 삭제합니다. 항목을 삭제할 때는 어떤 항목을 지울지 <code>del</code> 문에 알려 주면리스트로부터 해당 항목이 삭제됩니다. 여기서는 <code>del shoplist[0]</code> 이라고 입력하여 첫 번째 항목을삭제할 것임을 알려 주었습니다 (파이썬은 숫자를 0부터 센다는 점을 기억하시기 바랍니다).

리스트 객체가 갖고 있는 모든 메소드에 대해 알고 싶으시면, <code>help(list)</code> 를 입력해 보시기 바랍니다.

12.3. 튜플

튜플은 여러 개의 객체를 모아 담는 데 사용됩니다. 튜플은 리스트와 비슷하지만, 리스트 클래스에 있는여러가지 기능이 없습니다. 또 튜플은 수정이 불가능하며, 그래서 주로 문자열과 같이 비정적인객체들을 담을 때 사용됩니다.

튜플은 생략할 수 있는 괄호로 묶인 쉼표로 구분된 여러 개의 항목으로 정의됩니다.

튜플에 저장된 값들은 수정이 불가능하기 때문에, 단순 값들의 목록을 다루는 구문이나 사용자 정의함수에서 주로 사용됩니다.

예제 (<code>ds_using_tuple.py</code> 로 저장하세요):

<code class="python language-python"># I would recommend always using parentheses# to indicate start and end of tuple# even though parentheses are optional.# Explicit is better than implicit.zoo = ('python', 'elephant', 'penguin')print 'Number of animals in the zoo is', len(zoo)new_zoo = 'monkey', 'camel', zooprint 'Number of cages in the new zoo is', len(new_zoo)print 'All animals in new zoo are', new_zooprint 'Animals brought from old zoo are', new_zoo[2]print 'Last animal brought from old zoo is', new_zoo[2][2]print 'Number of animals in the new zoo is', \    len(new_zoo)-1+len(new_zoo[2])</code>

실행 결과:

$ python ds_using_tuple.pyNumber of animals in the zoo is 3Number of cages in the new zoo is 3All animals in new zoo are ('monkey', 'camel', ('python', 'elephant', 'penguin'))Animals brought from old zoo are ('python', 'elephant', 'penguin')Last animal brought from old zoo is penguinNumber of animals in the new zoo is 5
동작 원리

변수 <code>zoo</code> 는 여러 항목들을 담고 있는 튜플입니다. 보시는 바와 같이 <code>len</code> 함수를 통해 튜플의 길이를알아올 수 있습니다. 튜플은 열거형 의 한 예 입니다.

이제 동물원(zoo) 안의 동물들을 새로운 동물원으로 옮겨야 한다고 해 봅시다. 이를 위해 새로운 동물원<code>new_zoo</code> 튜플에 원래 있던 동물들과 함께 기존의 동물원에 있던 동물들을 옮겨 옵니다. 다시 파이썬으로돌아와서, 이와 같이 튜플 안에 튜플을 담아도 튜플의 성질을 잃지 않습니다.

리스트에서 했던 것과 같이, 튜플 안에 있는 항목의 위치를 대괄호로 묶어 지정해주면 각 항목에 접근할수 있습니다. 이를 인덱싱 연산자라고 부릅니다. <code>new_zoo</code> 의 세 번째 항목에 접근하려면 <code>new_zoo[2]</code>와 같이 하며, 이 세 번째 항목은 튜플이므로 이것의 세 번째 항목에 접근하려면 <code>new_zoo[2][2]</code> 와 같이합니다. 익숙해지면 쉽게 느껴질 것입니다.

Note
빈 튜플과 한 개짜리 튜플
빈 튜플은 괄호 안에 아무것도 적지 않고 <code>myempty = ()</code> 와 같이 생성할 수 있습니다. 그러나, 항목한 개만 담고 있는 튜플을 정의할 때는 주의해야 합니다. 이 경우 첫 번째 항목의 뒤에 쉼표를 붙여 주어파이썬에게 이것이 숫자 연산에 사용되는 괄호가 아니라 객체를 담는 튜플을 의미하는 것이라는 것을구분할 수 있도록 단서를 주어야 합니다. 예를 들어, 항목 <code>2</code> 를 담고 있는 튜플을 정의하려면<code>singleton = (2 , )</code> 와 같이 합니다.
Note
펄 프로그래머를 위한 주석
리스트 안의 리스트는 리스트의 성질을 잃지 않습니다. 리스트는 펄에서처럼 flatten되지 않습니다.이 성질은 튜플 안의 튜플이나 리스트 안의 튜플 혹은 튜프 안의 리스트의 경우 모두에 적용됩니다.파이썬에서는 이들은 단지 다른 객체 안에 저장된 객체들일 뿐입니다.

12.4. 사전

사전은 이를테면 전화번호부 같은 것인데, 누군가의 이름을 찾으면 그 사람의 주소와 연락처를 알 수 있는것과 같습니다. 이 때 그 사람의 이름에 해당하는 것을 라 부르고, 주소와 연락처 등에 해당하는 것을 이라 부릅니다. 전화번호부에 동명이인이 있을 경우 어떤 정보가 맞는 정보인지 알아낼 수 없듯이,사전의 키는 사전에서 유일한 값이어야 합니다.

사전의 키는 문자열과 같이 비정적 객체이어야 하지만, 값으로는 정적/비정적 객체 모두 사용할 수 있습니다.이것을 간단하게 다시 말하면 사전의 키로는 단순 객체만 사용할 수 있다고 표현합니다.

사전을 정의할 때 키와 값의 쌍은 <code>d = {key1 : value1, key2 : value2 }</code> 와 같이 지정해 줍니다. 이 때키와 값은 콜론으로 구분하며 각 키-값 쌍은 쉼표로 구분하고 이 모든 것을 중괄호 <code>{}</code>로 묶어 준다는 것을기억하시기 바랍니다.

여기서 사전의 키-값 쌍은 자동으로 정렬되지 않습니다. 이를 위해서는 사용하기 전에 먼저 직접정렬을 해 주어야 합니다.

앞으로 여러분이 사용하게 될 사전은 <code>dict</code> 클래스의 인스턴스/객체입니다.

예제 (<code>ds_using_dict.py</code> 로 저장하세요):

<code class="python language-python"># 'ab' is short for 'a'ddress'b'ookab = {  'Swaroop'   : 'swaroop@swaroopch.com',        'Larry'     : 'larry@wall.org',        'Matsumoto' : 'matz@ruby-lang.org',        'Spammer'   : 'spammer@hotmail.com'    }print "Swaroop's address is", ab['Swaroop']# Deleting a key-value pairdel ab['Spammer']print '\nThere are {} contacts in the address-book\n'.format(len(ab))for name, address in ab.items():    print 'Contact {} at {}'.format(name, address)# Adding a key-value pairab['Guido'] = 'guido@python.org'if 'Guido' in ab:    print "\nGuido's address is", ab['Guido']</code>

실행 결과:

$ python ds_using_dict.pySwaroop's address is swaroop@swaroopch.comThere are 3 contacts in the address-bookContact Swaroop at swaroop@swaroopch.comContact Matsumoto at matz@ruby-lang.orgContact Larry at larry@wall.orgGuido's address is guido@python.org
동작 원리

먼저 설명한 표기법을 이용하여 사전 <code>ab</code> 를 생성합니다. 그러면 앞서 리스트와 튜플을 설명할 때 언급했던인덱싱 연산자에 키를 지정해 주어 사전의 키-값 쌍에 접근할 수 있습니다. 간단하지요?

키-값 쌍 또한 <code>del</code> 문으로 삭제할 수 있습니다. <code>del</code> 문에 인덱싱 연산자에 해당 키를 지정해 준 사전을넘겨 주기만 하면 됩니다. 이 때 그 키에 해당하는 값은 알 필요가 없습니다.

다음으로, 사전의 <code>items</code> 메소드를 사용하여 각 키-값 쌍에 접근합니다. 이 메소드는 키와 값 순으로 구성된튜플들을 묶은 튜플 하나를 반환해 줍니다. 그 후 <code>for..in</code> 문을 사용하여 각각을 변수 <code>name</code> 과 <code>address</code>에 반복하여 지정해 주게 하고 그 값을 출력합니다.

위 예제의 Guido 와 같이 인덱싱 연산자를 사용하여 새 키-값 쌍을 추가할 수도 있습니다.

또, 사전 안에 키-값 쌍이 존재하는지 <code>in</code> 연산자를 통해 확인할 수 있습니다.

<code>dict</code> 클래스의 모든 메소드 목록을 확인하시려면 <code>help(dict)</code> 를 입력하시기 바랍니다.

Tip
키워드 인수와 사전의 관계
함수를 호출할 때 키워드 인수를 사용해 보셨다면, 이미 사전을 사용해 보신 것입니다! 여기서 여러분이지정해준 키-값 쌍은 각각 함수를 정의할 때 지정해준 매개 변수들의 이름과 각 매개 변수에 넘겨줄 값에대응하는 하나의 사전에 접근하는 것입니다 (이것을 심볼 테이블이라고 부릅니다).

12.5. 열거형

열거형들은 리스트, 튜플, 문자열 같은 것입니다. 그러면 열거형이란 무엇이고 열거형에서는 무엇이중요할까요?

열거형의 주요한 두 가지 기능은 멤버십 테스트 (<code>in</code> 과 <code>not in</code> 연산)와 열거형의 특정 항목을얻어올 수 있는 인덱싱 연산입니다.

또한 리스트, 튜플, 문자열의 세 가지 열거형은 슬라이스 연산 기능을 가지고 있는데, 이것은열거형의 일부분을 잘라낸(slice) 것을 반환하는 연산, 즉 부분 집합을 반환해 주는 연산입니다.

예제 (<code>ds_seq.py</code> 로 저장하세요):

<code class="python language-python">shoplist = ['apple', 'mango', 'carrot', 'banana']name = 'swaroop'# Indexing or 'Subscription' operation #print 'Item 0 is', shoplist[0]print 'Item 1 is', shoplist[1]print 'Item 2 is', shoplist[2]print 'Item 3 is', shoplist[3]print 'Item -1 is', shoplist[-1]print 'Item -2 is', shoplist[-2]print 'Character 0 is', name[0]# Slicing on a list #print 'Item 1 to 3 is', shoplist[1:3]print 'Item 2 to end is', shoplist[2:]print 'Item 1 to -1 is', shoplist[1:-1]print 'Item start to end is', shoplist[:]# Slicing on a string #print 'characters 1 to 3 is', name[1:3]print 'characters 2 to end is', name[2:]print 'characters 1 to -1 is', name[1:-1]print 'characters start to end is', name[:]</code>

실행 결과:

$ python ds_seq.pyItem 0 is appleItem 1 is mangoItem 2 is carrotItem 3 is bananaItem -1 is bananaItem -2 is carrotCharacter 0 is sItem 1 to 3 is ['mango', 'carrot']Item 2 to end is ['carrot', 'banana']Item 1 to -1 is ['mango', 'carrot']Item start to end is ['apple', 'mango', 'carrot', 'banana']characters 1 to 3 is wacharacters 2 to end is aroopcharacters 1 to -1 is waroocharacters start to end is swaroop
동작 원리

먼저, 열거형의 각 항목을 얻어오기 위해 어떻게 인덱스를 사용하는지 보겠습니다. 이를 다른 말로서브스크립션 연산 이라고도 합니다. 위 예제에서 보인 것과 같이 대괄호 내에 특정 숫자를 지정해 주면,파이썬은 열거형에서 해당 숫자의 위치에 있는 항목을 얻어옵니다. 이 때 파이썬은 숫자를 0부터 센다는 점을기억하시기 바랍니다. 따라서 <code>shoplist[0]</code> 과 <code>shoplist[3]</code> 은 각각 열거형 <code>shoplist</code> 의 첫 번째와네 번째 항목을 읽어오는 연산을 의미합니다.

인덱스에는 음수가 지정될 수도 있습니다. 이 경우, 열거형의 마지막부터 위치가 계산됩니다. 따라서,<code>shoplist[-1]</code> 은 열거형의 마지막 항목을 의미하며 <code>shoplist[-2]</code> 는 열거형의 마지막 항목 바로 뒤의항목을 의미합니다.

슬라이스 연산은 대괄호 안에 콜론으로 구분한 숫자들을 입력해 주는 것입니다. 슬라이스 연산은 앞서 설명한인덱싱 연산과 굉장히 비슷합니다. 이 경우 숫자는 반드시 지정해 줄 필요는 없지만 콜론은 반드시들어가야 합니다.

슬라이스 연산에서 콜론 앞의 첫 번째 숫자는 슬라이스를 시작할 위치를 의미하며 콜론 뒤의 두 번째 숫자는슬라이스를 멈출 위치를 지정합니다. 만약 첫 번째 숫자가 지정되지 않았을 경우, 파이썬은 열거형의 맨처음부터 슬라이스를 시작합니다. 두 번째 숫자가 지정되지 않았을 경우, 파이썬은 열거형의 맨 끝에서슬라이스를 멈춥니다. 이 때 슬라이스는 시작 위치부터 슬라이스를 시작하며 위치의 직전까지수행됩니다. 즉, 시작 위치에 해당하는 항목은 슬라이스에 포함되나 마지막 위치에 해당하는 항목은포함되지 않습니다.

따라서, <code>shoplist[1:3]</code> 은 위치 1 에 해당하는 항목부터 시작하여 위치 2 에 해당하는 항목을 포함하지만,위치 3 에 해당하는 항목은 포함하지 않습니다. 따라서 두 개의 항목의 슬라이스 가 반환됩니다. 이와 비슷하게,<code>shoplist[:]</code> 는 전체 열거형의 복사본이 반환됩니다.

슬라이스 숫자로도 음의 위치를 지정해 줄 수 있습니다. 음수는 열거형의 마지막부터 위치를 계산하는 것을의미합니다. 예를 들어, <code>shoplist[:-1]</code> 은 마지막 항목을 제외한 모든 항목을 포함하고 있는 슬라이스를반환해 줍니다.

슬라이스 숫자에 세 번째 인수를 지정해 줄 수 있는데, 이것은 슬라이스 스텝에 해당합니다 (기본값은1 입니다):

<code class="python language-python">>>> shoplist = ['apple', 'mango', 'carrot', 'banana']>>> shoplist[::1]['apple', 'mango', 'carrot', 'banana']>>> shoplist[::2]['apple', 'carrot']>>> shoplist[::3]['apple', 'banana']>>> shoplist[::-1]['banana', 'carrot', 'mango', 'apple']</code>

보시는 바와 같이 스텝이 2일 경우 위치 0, 2, … 에 해당되는 항목들이 반환되며 스텝이 3일 경우0, 3, … 에 해당되는 항목들이 반환됩니다.

파이썬 인터프리터에서 여러 가능한 슬라이스 숫자의 조합들을 시험해 보시면 그 결과를 곧바로 확인해보실 수 있습니다. 이 모든 사항은 모든 열겨형에 적용되므로, 튜플, 리스트, 문자열의 경우 모두동일한 방법을 사용할 수 있습니다!

12.6. 집합

집합은 정렬되지 않은 단순 객체의 묶음입니다. 집합은 포함된 객체들의 순서나 중복에 상관없이객체를 묶음 자체를 필요로 할 때 주로 사용합니다.

집합끼리는 멤버십 테스트를 통해 한 집합이 다른 집합의 부분집합인지 확인할 수 있으며,두 집합의 교집합 등을 알아낼 수도 있습니다.

<code class="python language-python">>>> bri = set(['brazil', 'russia', 'india'])>>> 'india' in briTrue>>> 'usa' in briFalse>>> bric = bri.copy()>>> bric.add('china')>>> bric.issuperset(bri)True>>> bri.remove('russia')>>> bri & bric # OR bri.intersection(bric){'brazil', 'india'}</code>
동작 원리

이 책을 읽는 여러분들은 아마도 학교에서 기초 집합론에 대해 이미 배우셨을 것이므로 위 예제에 대해서는딱히 설명할 것이 없습니다.

12.7. 참조

객체를 생성하고 변수에 할당해 줄 때, 사실 실제 객체가 변수에 할당되는 것은 아닙니다! 변수에는 객체의참조 가 할당됩니다. 참조란, 그 변수의 이름이 여러분의 컴퓨터 메모리 어딘가에 저장되어 있는 실제객체의 위치를 가리키는 것을 말합니다. 이를 객체에 이름을 바인딩 한다고 말합니다.

일반적으로는 이에 대해 크게 신경 쓸 필요가 없습니다만, 참조로 인해 발생하는 몇 가지 현상에 대해알고 계실 필요가 있습니다.

예제 (<code>ds_reference.py</code> 로 저장하세요):

<code class="python language-python">print 'Simple Assignment'shoplist = ['apple', 'mango', 'carrot', 'banana']# mylist is just another name pointing to the same object!mylist = shoplist# I purchased the first item, so I remove it from the listdel shoplist[0]print 'shoplist is', shoplistprint 'mylist is', mylist# Notice that both shoplist and mylist both print# the same list without the 'apple' confirming that# they point to the same objectprint 'Copy by making a full slice'# Make a copy by doing a full slicemylist = shoplist[:]# Remove first itemdel mylist[0]print 'shoplist is', shoplistprint 'mylist is', mylist# Notice that now the two lists are different</code>

실행 결과:

$ python ds_reference.pySimple Assignmentshoplist is ['mango', 'carrot', 'banana']mylist is ['mango', 'carrot', 'banana']Copy by making a full sliceshoplist is ['mango', 'carrot', 'banana']mylist is ['carrot', 'banana']
동작 원리

주석에 거의 모든 설명을 달아 두었습니다.

리스트와 같은 어떤 열거형이나 복잡한 객체 (정수형과 같이 단순 객체 를 제외하고)의 복사본을생성하고 싶을 때에는, 슬라이스 연산자를 이용하여 복사본을 생성해야 합니다. 단순히 한 변수를다른 변수에 할당하게 되면 두 변수는 같은 객체를 '참조' 하게 되며 실제 복사본이 생성되지 않습니다.따라서 이것을 조심하지 않으면 문제가 발생할 수 있습니다.

Note
펄 프로그래머를 위한 주석
이미 존재하는 리스트를 다른 변수에 할당하는 구문은 복사본을 만드는 것이 아닙니다. 열거형의복사본을 만들려면 반드시 슬라이스 연산자를 사용하시기 바랍니다.

12.8. 문자열에 대한 좀 더 자세한 설명

앞서 문자열에 대해 이미 상세히 다루었지만, 몇 가지 더 알아두면 좋을 것들이 있습니다.문자열도 객체이므로 여러 메소드를 가지고 있는데 이를 통해 문자열의 앞 뒤 공백을 제거한다거나하는 일들을 할 수 있습니다!

파이썬에서 사용되는 모든 문자열은 <code>str</code> 클래스의 객체입니다. 다음 예제에 이 객체가 제공하는몇가지 유용한 메소드들의 용례가 나타나 있습니다. <code>str</code> 클래스의 모든 메소드의 목록을 확인하시려면<code>help(str)</code> 을 실행해 보시기 바랍니다.

예제 (<code>ds_str_methods.py</code> 로 저장하세요):

<code class="python language-python"># This is a string objectname = 'Swaroop'if name.startswith('Swa'):    print 'Yes, the string starts with "Swa"'if 'a' in name:    print 'Yes, it contains the string "a"'if name.find('war') != -1:    print 'Yes, it contains the string "war"'delimiter = '_*_'mylist = ['Brazil', 'Russia', 'India', 'China']print delimiter.join(mylist)</code>

실행 결과:

$ python ds_str_methods.pyYes, the string starts with "Swa"Yes, it contains the string "a"Yes, it contains the string "war"Brazil_*_Russia_*_India_*_China
동작 원리

여기서는 문자열이 제공하는 여러 메소드에 대해 알아보았습니다. <code>startswith</code> 메소드는 문자열이주어진 문자열로 시작하는지 여부를 반환합니다. <code>in</code> 연산자는 문자열에 주어진 문자열이 포함되어있는지 확인하는데 사용합니다.

<code>find</code> 메소드는 문자열 내에 포함된 특정 문자열의 위치를 반환합니다. 이 때 주어진 문자열을 찾지못한 경우 <code>find</code> 는 -1 을 반환합니다. 또 <code>str</code> 클래스는 <code>join</code> 이라는 좋은 메소드를 가지고 있는데,이것은 주어진 문자열들을 해당 문자열을 구분자로 하여 결합한 하나의 큰 문자열을 만들어 반환해 주는메소드입니다.

12.9. 요약

이 챕터에서는 파이썬의 여러 내장 자료구조들에 대해 상세히 알아보았습니다. 이 자료 구조들은 프로그램을짧고 보기 쉽게 작성하는데 꼭 필요한 구성 요소들입니다.

이제 여러분은 파이썬의 여러 기본적인 문법에 익숙해졋을 것입니다. 이 다음부터는 실제 파이썬 프로그램을설계하고 작성해 보도록 하겠습니다.

13. 실생활 문제 해결

지금까지 파이썬이라는 언어의 여러 가지 구성 요소에 대해 배워 보았습니다. 이제는 지금까지 배운것들을 토대로, 뭔가 유용한 것을 하는 프로그램을 만들어 보도록 합시다. 이 챕터의 목표는여러분이 직접 파이썬 스크립트를 만들고 사용하는 법을 배우는 것입니다.

13.1. 문제

다음과 같은 문제를 해결해 봅시다:

내 중요한 파일들을 백업해두는 프로그램을 만들고 싶어요.

이것은 간단한 문제이지만, 아직 어떻게 접근하면 좋을지 정보가 부족합니다. 따라서 약간 분석을 해보도록 합시다. 예를 들어, 어떤 파일을 백업할지 어떻게 지정해 줄까요? 파일들은 어떻게저장되어야 하며 또 어디에 저장되어야 할까요?

문제에 대해 분석한 이후에는, 프로그램을 설계해야 합니다. 이를 위해 우리가 만들 프로그램이 어떻게동작하면 좋을지 그 목록을 만들어 봅시다. 저는 아래와 같이 저의 방식대로 목록을 만들었습니다.그러나 모든 사람이 서로 다른 생각을 가지고 있는 것이 당연하므로, 여러분이 목록을 만들어도 저와 같은항목들로 구성되어 있지 않을 수 있겠죠. 달라도 아무 상관 없습니다.

  • 백업할 파일과 디렉토리들은 리스트의 형태로 지정해 둔다.

  • 주 백업 디렉토리를 두고, 백업은 그 안에 저장되어야 한다.

  • 백업된 파일들은 zip파일로 압축해 둔다.

  • zip 파일의 이름은 현재 날짜와 시간으로 한다.

  • GNU/Linux 환경이나 Unix 환경에서 기본으로 제공되는 <code>zip</code> 명령을 이용한다.(참고: 명령줄 인터페이스에서 사용할 수 있는 어떤 압축 유틸리티든지 사용이 가능합니다)

Note
윈도우 사용자를 위한 주석
윈도우 사용자는 GnuWin32 프로젝트 홈페이지 에서<code>zip</code> 명령을 내려받아 설치 할 수 있습니다.또한 설치한 후 파이썬 명령을 어디서든 실행할 수 있도록 해 주었던 것 처럼<code>C:\Program Files\GnuWin32\bin</code> 디렉토리를 시스템의 <code>PATH</code> 환경변수에 추가해 주면 어디서든<code>zip</code> 명령을 사용할 수 있습니다.

13.2. 첫번째 프로그램

일단은 프로그램을 안정적이게 설계한 것 같으므로, 코드를 입력하여 프로그램으로 구현 해 보도록합시다.

<code>backup_ver1.py</code> 로 저장하세요:

<code class="python language-python">import osimport time# 1. The files and directories to be backed up are# specified in a list.# Example on Windows:# source = ['"C:\\My Documents"', 'C:\\Code']# Example on Mac OS X and Linux:source = ['/Users/swa/notes']# Notice we had to use double quotes inside the string# for names with spaces in it.# 2. The backup must be stored in a# main backup directory# Example on Windows:# target_dir = 'E:\\Backup'# Example on Mac OS X and Linux:target_dir = '/Users/swa/backup'# Remember to change this to which folder you will be using# 3. The files are backed up into a zip file.# 4. The name of the zip archive is the current date and timetarget = target_dir + os.sep + \         time.strftime('%Y%m%d%H%M%S') + '.zip'# Create target directory if it is not presentif not os.path.exists(target_dir):    os.mkdir(target_dir) # make directory# 5. We use the zip command to put the files in a zip archivezip_command = "zip -r {0} {1}".format(target,                                      ' '.join(source))# Run the backupprint "Zip command is:"print zip_commandprint "Running:"if os.system(zip_command) == 0:    print 'Successful backup to', targetelse:    print 'Backup FAILED'</code>

실행 결과:

$ python backup_ver1.pyZip command is:zip -r /Users/swa/backup/20140328084844.zip /Users/swa/notesRunning:  adding: Users/swa/notes/ (stored 0%)  adding: Users/swa/notes/blah1.txt (stored 0%)  adding: Users/swa/notes/blah2.txt (stored 0%)  adding: Users/swa/notes/blah3.txt (stored 0%)Successful backup to /Users/swa/backup/20140328084844.zip

이제 테스트 단계로 넘어와서 프로그램이 잘 동작하는지 확인 해보아야 합니다. 만약 예상대로 프로그램이동작하지 않으면, 프로그램의 버그(bug)를 제거하는 디버그(debug) 과정을 거쳐야 합니다.

예시 프로그램이 잘 동작하지 않는 경우, 실행 결과의 <code>Zip command is</code> 줄 뒤의 내용을 복사한 후쉘 (GNU/Linux 나 Mac OS X) 혹은 <code>cmd</code> (윈도우 환경) 에 입력해본 뒤 무엇이 문제인지 확인하고고쳐 보도록 합시다. 또 무엇이 잘못되었는지 확인하기 위해 zip 명령 설명서 또한 확인해 보시기 바랍니다.만약 위 명령이 올바르게 실행된다면, 문제는 파이썬 프로그램 자체에 있는 것으로 추정되므로프로그램을 올바르게 정확히 작성했는지 다시 한번 확인해 보시기 바랍니다.

동작 원리

아래에서 단계별로 어떻게 우리의 설계코드 로 바꾸었는지에 대해 설명할 것입니다.

먼저 <code>os</code> 와 <code>time</code> 모듈을 불러왔습니다. 그리고, 백업할 파일들과 디렉토리들을 <code>source</code> 라는 리스트에담아 두었고, 또 백업을 저장해 둘 대상 디렉토리는 <code>target_dir</code> 변수에 지정해 주었습니다. zip 파일의이름은 현재 날짜와 시간으로 할 것이므로 <code>time.strftime()</code> 함수를 사용하여 현재 날짜와 시간을얻어온 후 <code>.zip</code> 확장자를 붙여 <code>target_dir</code> 디렉토리에 저장하도록 했습니다.

여기서 <code>os.sep</code> 변수를 주목하시기 바랍니다. 이것은 여러분의 운영 체제에 다른 디렉토리 구분자를나타내는 것으로 GNU/Linux 와 Unix 환경에서는 <code>'/'</code> 일 것이고, 윈도우 환경에서는 <code>'\\'</code> 일 것이며,Mac OS 에서는 <code>':'</code> 일 것입니다. 이러한 문자들을 직접 사용하지 않고 <code>os.sep</code> 을 사용하는 것은여러분의 프로그램에 범용성을 제공하며, 따라서 여러 운영체제에서 수정 없이 사용할 수 있게 됩니다.

위 프로그램에서 사용한 것처럼 <code>time.strftime()</code> 함수는 특별한 형식을 인수로 넘겨 받습니다.<code>%Y</code> 는 네 자리의 연도로 치환되며, <code>%m</code> 은 두 자리의 달 즉 <code>01</code> 과 <code>12</code> 사이의 숫자를의미합니다. 날짜 형식에 대해서는파이썬 레퍼런스 매뉴얼 을참고하시기 바랍니다.

이제 대상 zip 파일의 이름을 생성하기 위해 문자열 결합 연산자인 더하기 연산자를 사용하여두 문자열을 합쳐서 하나의 문자열로 만듭니다. 그리고, <code>zip_command</code> 라는 문자열을 만들어실제로 실행하게 될 문자열을 만듭니다. GNU/Linux 터미널이나 DOS 프롬프트에서 이 문자열을실행시켜 보고 잘 동작하는지 확인해 볼 수 있을 것입니다.

앞으로 우리가 사용할 <code>zip</code> 명령은 몇 가지 옵션과 매개 변수를 필요로 합니다. <code>-r</code> 옵션은zip 명령이 주어진 디렉토리에 대해 회귀적(recursive)으로, 즉 해당 디렉토리가 포함하고 있는모든 하위 디렉토리와 파일들을 포함하도록 하는 명령입니다. 여기서는 두 가지 옵션을 결합하여하나의 축약 옵션 <code>-qr</code> 을 지정해 주었습니다. zip 명령 뒤에는 차례로 이 옵션이 지정되고, 그 뒤에는생성될 zip 파일의 이름이, 마지막으로는 압축될 대상 디렉토리들과 파일들이 지정됩니다. 이를 위해<code>source</code> 리스트를 앞서 설명한 <code>join</code> 메소드를 통해 문자열로 바꿔서 넘겨 주었습니다.

그러면, 최종적으로 <code>os.system</code> 함수를 통해 이 명령을 실제 시스템(system) 의 쉘에서 실행시킵니다.그러면 프로그램이 성공적으로 실행된 경우 <code>0</code> 이 반환되며 그렇지 않으면 오류 코드가 반환됩니다.

이제 명령의 실행 결과에 따라, 적절한 메시지를 출력해 주고 백업이 성공했는지 실패했는지를화면에 출력해 줍니다.

여기까지입니다. 이제 우리는 중요한 파일을 백업하는 스크립트를 성공적으로 만들었습니다!

Note
윈도우 사용자를 위한 주석
이스케이프 문자 백슬래시를 두 번씩 입력하는 것보다 raw 문자열을 이용할 수도 있습니다.예를 들어, <code>'C:\\Documents'</code> 는 <code>r'C:\Documents'</code> 로도 쓸 수 있습니다. 그러나,<code>'C:\Documents'</code> 와 같이 사용하지 마시기 바랍니다. 이것은 <code>\D</code> 라는 알 수 없는이스케이프 문자를 의미하는 것으로 오류가 발생합니다.

이제 잘 동작하는 백업 스크립트를 만들었으므로, 이 스크립트를 언제든지 사용하여 중요한 파일들을백업할 수 있습니다. 이 단계를 소프트웨어의 활용(Operation) 단계 혹은 배포(Deployment) 단계라고 합니다.

위 프로그램은 잘 동작하지만, 첫번째로 만든 프로그램은 (종종) 예상한 대로만은 실행되지 않습니다.예를 들어 프로그램 설계를 잘못했다든지 코드를 입력할 때 실수를 했다던지 할 수 있습니다.이런 경우 상황에 맞춰서 설계 단계로 돌아가거나 프로글매을 디버깅해야 합니다.

13.3. 두 번째 프로그램

첫 번째로 만든 프로그램은 일단 잘 동작합니다. 그러나, 프로그램을 매일매일 잘 쓰기 위해좀 더 개선의 여지가 있습니다. 이 단계를 소프트웨어의 유지보수(maintenance) 단계라고 합니다.

제가 이 프로그램을 쓰다가 느낀 한가지 개선점은 파일에 이름을 짓는 부분에 대한 것인데, 주 백업디렉토리에 날짜로 된 하위 디렉토리를 만들고 시간으로 된 압축 파일들을 그 안에 넣는 것입니다.이렇게 하면 백업된 파일들이 계층적으로 저장되므로 좀 더 쉽게 관리할 수 있을 것입니다. 또한,파일명도 좀 더 짧아집니다. 마지막으로 각각 디렉토리에 백업 파일이 나뉘어 저장되므로 어떤 날에백업을 했는지 여부를 그 날짜에 해당하는 디렉토리가 있는지 여부만으로 쉽게 확인할 수 있을것입니다.

<code>backup_ver2.py</code> 로 저장하세요:

<code class="python language-python">import osimport time# 1. The files and directories to be backed up are# specified in a list.# Example on Windows:# source = ['"C:\\My Documents"', 'C:\\Code']# Example on Mac OS X and Linux:source = ['/Users/swa/notes']# Notice we had to use double quotes inside the string# for names with spaces in it.# 2. The backup must be stored in a# main backup directory# Example on Windows:# target_dir = 'E:\\Backup'# Example on Mac OS X and Linux:target_dir = '/Users/swa/backup'# Remember to change this to which folder you will be using# Create target directory if it is not presentif not os.path.exists(target_dir):    os.mkdir(target_dir) # make directory# 3. The files are backed up into a zip file.# 4. The current day is the name of the subdirectory# in the main directory.today = target_dir + os.sep + time.strftime('%Y%m%d')# The current time is the name of the zip archive.now = time.strftime('%H%M%S')# The name of the zip filetarget = today + os.sep + now + '.zip'# Create the subdirectory if it isn't already thereif not os.path.exists(today):    os.mkdir(today)    print 'Successfully created directory', today# 5. We use the zip command to put the files in a zip archivezip_command = "zip -r {0} {1}".format(target,                                      ' '.join(source))# Run the backupprint "Zip command is:"print zip_commandprint "Running:"if os.system(zip_command) == 0:    print 'Successful backup to', targetelse:    print 'Backup FAILED'</code>

실행 결과:

$ python backup_ver2.pySuccessfully created directory /Users/swa/backup/20140329Zip command is:zip -r /Users/swa/backup/20140329/073201.zip /Users/swa/notesRunning:  adding: Users/swa/notes/ (stored 0%)  adding: Users/swa/notes/blah1.txt (stored 0%)  adding: Users/swa/notes/blah2.txt (stored 0%)  adding: Users/swa/notes/blah3.txt (stored 0%)Successful backup to /Users/swa/backup/20140329/073201.zip
동작 원리

많은 부분은 이전과 그대로입니다. 변경된 부분은 주 백업 디렉토리 안에 그 날짜에 해당하는디렉토리가 있는지 여부를 <code>os.path.exists</code> 함수로 확인하는 부분입니다. 해당 디렉토리가 없으면,<code>os.mkdir</code> 함수를 통해 디렉토리를 새로 만듭니다.

13.4. 세 번째 프로그램

두 번째 프로그램도 잘 동작했지만, 백업을 많이 하고 싶을 때, 많은 백업 파일이 생성되므로 어떤파일이 어떤 것의 백업인지 구분하기가 너무 어려웠습니다! 예를 들어, 어떤 문서나 프로그램에 큰변화를 주었을 때 그 내용을 zip 파일의 이름에 추가로 달아 주면 좋을 것 같습니다. 이 문제는zip 파일을 생성할 때 뒤에 사용자 정의 꼬리말을 달아 주는 기능을 추가하면 쉽게 해결될 것입니다.

Warning
아래 프로그램은 동작하지 않으니 놀라지 마시고 쭉 따라오시기 바랍니다.이를 통해 뭔가를 배울 것입니다.

<code>backup_ver3.py</code> 로 저장하세요:

<code class="python language-python">import osimport time# 1. The files and directories to be backed up are# specified in a list.# Example on Windows:# source = ['"C:\\My Documents"', 'C:\\Code']# Example on Mac OS X and Linux:source = ['/Users/swa/notes']# Notice we had to use double quotes inside the string# for names with spaces in it.# 2. The backup must be stored in a# main backup directory# Example on Windows:# target_dir = 'E:\\Backup'# Example on Mac OS X and Linux:target_dir = '/Users/swa/backup'# Remember to change this to which folder you will be using# Create target directory if it is not presentif not os.path.exists(target_dir):    os.mkdir(target_dir) # make directory# 3. The files are backed up into a zip file.# 4. The current day is the name of the subdirectory# in the main directory.today = target_dir + os.sep + time.strftime('%Y%m%d')# The current time is the name of the zip archive.now = time.strftime('%H%M%S')# Take a comment from the user to# create the name of the zip filecomment = raw_input('Enter a comment --> ')# Check if a comment was enteredif len(comment) == 0:    target = today + os.sep + now + '.zip'else:    target = today + os.sep + now + '_' +        comment.replace(' ', '_') + '.zip'# Create the subdirectory if it isn't already thereif not os.path.exists(today):    os.mkdir(today)    print 'Successfully created directory', today# 5. We use the zip command to put the files in a zip archivezip_command = "zip -r {0} {1}".format(target,                                      ' '.join(source))# Run the backupprint "Zip command is:"print zip_commandprint "Running:"if os.system(zip_command) == 0:    print 'Successful backup to', targetelse:    print 'Backup FAILED'</code>

실행 결과:

$ python backup_ver3.py  File "backup_ver3.py", line 39    target = today + os.sep + now + '_' +                                        ^SyntaxError: invalid syntax
동작(하지 않는) 원리

이 프로그램은 동작하지 않습니다! 실행시켜보면 구문 오류가 있다는 메시지가 출력되며, 이것은위 스크립트가 파이썬의 문법 규칙을 만족하지 않는다는 것을 의미합니다. 파이썬이 출력해준오류 메시지를 확인해 보면 어디에서 이 오류가 발생했는지를 알려 줍니다. 따라서 그 줄부터디버깅을 시작해 봅시다.

자세히 살펴보면, 한 개의 논리적 명령줄이 두개의 물리적 명령줄로 나뉘어 있지만두 개의 물리적 명령줄이 사실 하나의 명령줄이라는 것을 파이썬에게 알려줄만한 뭔가가 누락되어있습니다. 여기서 파이썬은 더하기 연산자 (<code>+</code>)를 발견했으나 그 논리적 명령줄에 피연산자가없음을 발견하고는 어떻게 해야 할지 모르는 상황에 처하게 된 것입니다. 이 경우, 두 물리적명령줄을 하나로 연결해 주기 위해서는 맨 뒤에 백슬래시를 추가해 주어야 한다고 배웠으므로누락된 백슬래시를 추가해 줍니다. 프로그램에서 문재를 찾고 수정 하는 이러한 과정을 버그 수정이라고 합니다.

13.5. 네 번째 프로그램

<code>backup_ver4.py</code> 로 저장하세요:

<code class="python language-python">import osimport time# 1. The files and directories to be backed up are# specified in a list.# Example on Windows:# source = ['"C:\\My Documents"', 'C:\\Code']# Example on Mac OS X and Linux:source = ['/Users/swa/notes']# Notice we had to use double quotes inside the string# for names with spaces in it.# 2. The backup must be stored in a# main backup directory# Example on Windows:# target_dir = 'E:\\Backup'# Example on Mac OS X and Linux:target_dir = '/Users/swa/backup'# Remember to change this to which folder you will be using# Create target directory if it is not presentif not os.path.exists(target_dir):    os.mkdir(target_dir) # make directory# 3. The files are backed up into a zip file.# 4. The current day is the name of the subdirectory# in the main directory.today = target_dir + os.sep + time.strftime('%Y%m%d')# The current time is the name of the zip archive.now = time.strftime('%H%M%S')# Take a comment from the user to# create the name of the zip filecomment = raw_input('Enter a comment --> ')# Check if a comment was enteredif len(comment) == 0:    target = today + os.sep + now + '.zip'else:    target = today + os.sep + now + '_' + \        comment.replace(' ', '_') + '.zip'# Create the subdirectory if it isn't already thereif not os.path.exists(today):    os.mkdir(today)    print 'Successfully created directory', today# 5. We use the zip command to put the files in a zip archivezip_command = "zip -r {0} {1}".format(target,                                      ' '.join(source))# Run the backupprint "Zip command is:"print zip_commandprint "Running:"if os.system(zip_command) == 0:    print 'Successful backup to', targetelse:    print 'Backup FAILED'</code>

실행 결과:

$ python backup_ver4.pyEnter a comment --> added new examplesZip command is:zip -r /Users/swa/backup/20140329/074122_added_new_examples.zip /Users/swa/notesRunning:  adding: Users/swa/notes/ (stored 0%)  adding: Users/swa/notes/blah1.txt (stored 0%)  adding: Users/swa/notes/blah2.txt (stored 0%)  adding: Users/swa/notes/blah3.txt (stored 0%)Successful backup to /Users/swa/backup/20140329/074122_added_new_examples.zip
동작 원리

이제 프로그램이 잘 동작합니다! 이제 세 번째 프로그램을 작성할 때 추가했던 사항들에 대해 살펴보도록합시다. 먼저 <code>input</code> 함수를 통해 사용자의 꼬릿말을 입력받은 후, 사용자가 뭔가를 입력했는지 여부를<code>len</code> 함수를 통해 확인합니다. 만약 사용자가 아무것도 입력하지 않고 <code>enter</code> 키를 입력한 경우 (아마도특별한 꼬릿말이 필요 없는 일상적인 백업을 할 경우에 해당될 것입니다), 이전과 동일하게 처리합니다.

그러나 사용자가 꼬릿말을 입력한 경우에는, zip 파일명을 생성할 때 뒤에 이 꼬릿말을 붙여 주고<code>.zip</code> 확장자를 붙여 줍니다. 여기서 사용자가 입력한 꼬릿말에 포함된 공백 문자를 모두 밑줄로치환하였는데, 이것은 나중에 파일들을 관리할 때 공백 문자가 없는 편이 관리가 더 쉽기 때문입니다.

13.6. 더 많은 개선점

아마 네 번째 프로그램은 많은 경우에 만족스럽게 사용될 수 있겠지만, 언제나 개선할 사항은 넘쳐납니다.예를 들면, 사용자가 <code>-v</code> 옵션을 통해 출력(verbosity) 단계를 지정하게 하여 프로그램이 실행될 때단계별로 처리되는 사항을 화면에 출력해주도록 할 수도 있고, <code>-q</code> 옵션을 통해 아무 출력 없이(quiet)프로그램이 실행되도록 할 수도 있습니다.

또 다른 가능한 개선사항은 추가로 백업할 파일들이나 디렉토리들을 명령줄로부터 넘겨받아 함께백업하게 하는 것을 생각해 볼 수 있습니다. 이러한 추가 파일들의 이름은 <code>sys.argv</code> 리스트를 이용하면넘겨받을 수 있을 것이고, 이것을 리스트 클래스의 <code>extend</code> 메소드를 이용하여 <code>source</code> 리스트 뒤에추가해 줄 수 있을 것입니다.

생각해볼 수 있는 가장 중요한 개선사항은 <code>os.system</code> 을 사용하지 않고 파이썬에서 제공되는내장 모듈인 zipfile 이나tarfile 을 이용하여 압축 파일을 생성하는 것입니다.이들은 표준 라이브러리에 포함되어 있으며 zip 프로그램과 같은 추가 프로그램 등을 설치하지 않고서도프로그램이 잘 동작하게 해 줍니다.

그러나 여기서는 순전히 교육적인 목적에서 <code>os.system</code> 을 이용하여 백업 파일을 생성하였으며,이를 사용하면 누구나 알아볼 수 있을 만큼 프로그램이 간단해지고 또 이렇게 만든 프로그램을 실제로사용하기에 당장 무리가 없기 때문에 사용한 것입니다.

자, 이제 <code>os.system</code> 을 호출하지 않고 zipfile모듈을 사용하여 다섯번째 프로그램을 만들어 보시지 않겠습니까?

13.7. 소프트웨어 개발 단계

지금까지 소프트웨어를 개발하면서 여러 단계 들을 거쳐 왔습니다. 이 단계들은 다음과 같이축약하여 설명할 수 있습니다:

  1. 무엇을 만들 것인가? (분석 단계)

  2. 어떻게 만들 것인가? (설계 단계)

  3. 만들기 (구현 단계)

  4. 테스트 하기 (테스트와 디버깅 단계)

  5. 실제로 사용하기 (활용 또는 배포 단계)

  6. 유지 및 보수하기 (개선 단계)

앞으로 프로그램을 작성할 때 지금까지 여러분이 백업 스크립트를 만들면서 거쳐 왔던과정을 그대로 따라 하기를 추천합니다. 문제를 분석하고 프로그램을 설계하세요.구현은 가장 단순한 프로그램으로 시작하세요. 테스트하고 디버그하세요.한번 사용해보고 제대로 동작하는지 확인해보세요. 이제, 원하는 기능을 추가하고,만들어보고 테스트해보고 사용해보는 일련의 과정들을 반복하며 프로그램을 개선해나가세요.

기억하세요:

소프트웨어는 성장하는 것이며, 만들어지는 것이 아니다.(Software is grown, not built.)

13.8. 요약

지금까지 여러분이 직접 파이썬 프로그램/스크립트를 만드는 법과 이러한 프로그램을 만들기 위해거쳐 와야 했던 여러가지 단계들에 대해 배워 보았습니다. 이 챕터에서 배운 것들을 통해이 챕터에서 배웠던 것들을 떠올리면 유용할 것이며, 또 실제 문제를 해결하는 데 파이썬을 사용하는것에 좀 더 익숙해질 수 있을 것입니다.

다음으로는, 객체 지향 프로그래밍에 대해 다루어 보겠습니다.

14. 객체 지향 프로그래밍

지금까지 프로그램을 작성할 때, 우리는 데이터를 다루는 명령들의 블록인 함수들의 조합으로 프로그램을구성하였습니다. 이러한 설계 방식을 절차 지향 프로그래밍 기법이라고 부릅니다. 이와 달리데이터와 기능을 객체라고 불리우는 것으로 묶어서 프로그램을 구성하는 또 다른 기법이 있습니다.이것을 객체 지향 프로그래밍 기법이라고 부릅니다. 아마도 여러분의 대부분의 시간 동안 절차 지향프로그래밍 기법을 통해 프로그램을 작성하게 되겠지만, 큰 프로그램을 작성할 때나 이 기법을이용하는 것이 더 편리한 문제를 해결해야 할 경우 객체 지향 프로그래밍 기법을 활용할 수 있습니다.

객체 지향 프로그래밍에서는 클래스와 객체라는 두 가지 주인공이 있습니다. 클래스는 새로운 형식을 정의하는 것이며, 객체는 클래스의 인스턴스 를 의미하는 것입니다. 이것을 다시 표현하면여러분이 <code>int</code> 라는 형식의 변수를 만들 수 있다는 것으로, 이것은 곧 정수형을 저장하는 변수는<code>int</code> 클래스의 인스턴스(객체)를 변수에 할당하는 것이라고도 말할 수 있습니다.

Note
정적 언어 프로그래머들을 위한 주석

파이썬에서는 정수형조차도 객체로 다루어집니다 (<code>int</code> 클래스의 객체입니다). C++이나 Java(버전 1.5 미만)처럼 정수형이 자체 기본 형식들 중 하나로 다루어지는 것과는 다릅니다.

<code>help(int)</code> 를 입력하여 정수형 클래스에 대해 좀 더 자세히 알아보시기 바랍니다.

C# 이나 Java 1.5 프로그래머들은 아마 이것이 boxing 과 unboxing 과 비슷하다는 것을눈치채셨을 것입니다.

객체는 그 객체에 내장된 일반적인 변수들을 사용하여 데이터를 저장할 수 있습니다. 이 때 객체 혹은클래스에 소속된 변수들을 필드(field) 라고 부릅니다. 객체는 또한 내장된 함수를 이용하여 어떤기능을 갖도록 할 수 있는데 이것을 클래스의 메소드(method) 라고 부릅니다. 이러한 명칭을구별하여 부르는 것은 중요한데, 이는 일반적인 변수와 함수와 달리 이들은 클래스나 객체에 소속되어있는 대상들이기 때문입니다. 또, 이러한 필드와 메소드들을 통틀어 클래스의 속성(attribute) 이라부릅니다.

필드는 두 가지 종류가 있습니다. 하나는 클래스의 인스턴스/객체에 내장되어 있는 것이고, 또 하나는클래스 자체에 내장되어 있는 것입니다. 각각을 인스턴스 변수클래스 변수 라 부릅니다.

클래스는 <code>class</code> 키워드를 통해 생성됩니다. 클래스의 필드와 메소드는 그 아래 들여쓰기 된 블록에차례로 정의됩니다.

14.1. <code>self</code> 에 대하여

클래스 메소드는 일반적인 함수와 딱 한 가지 다른 점이 있는데, 그것은 메소드의 경우 매개 변수의목록에 항상 추가로 한 개의 변수가 맨 앞에 추가되어야 한다는 점입니다. 또한 메소드를 호출할 때이 변수에는 우리가 직접 값을 넘겨주지 않으며, 대신 파이썬이 자동으로 값을 할당합니다.이 변수에는 현재 객체 자신의 참조가 할당되며, 일반적으로 <code>self</code> 라 이름을 짓습니다.

이 변수의 이름은 마음대로 지을 수 있지만, <code>self</code> 라는 이름을 사용할 것을 강력히 권합니다.이것은 어떤 약속으로, 다른 이름을 사용하는 것은 다른 프로그래머들에게 좀 눈살을 찌푸려지게 하는일이 될 수 있기 때문입니다. <code>self</code>라는 표준적인 이름을 사용하면 여러분의 프로그램을 읽는사람들로부터 이것이 그것을 의마함을 쉽게 알아보게 할 수 있고, 심지어 특별한 IDE (IntegratedDevelopment Environment)를 사용하는 사람들도 이를 쉽게 알아볼 수 있는 등 여러 장점이 있습니다.

Note
C++/Java/C# 프로그래머를 위한 주석
파이썬의 <code>self</code> 는 C++ 의 <code>this</code> 포인터와 같은 것이며, Java와 C# 의 <code>this</code> 참조와 같습니다.

아마 여러분은 파이썬이 <code>self</code> 에 어떻게 값을 할당하는 것인지 그리고 정말 값을 직접 할당할 필요가없는지 궁금할 것입니다. 이해를 돕기 위해 예를 하나 들어 보겠습니다. 여러분이 <code>MyClass</code> 라는클래스를 생성했고, 이 클래스의 객체를 <code>myobject</code> 라는 이름으로 생성했다고 해 봅시다. 이제 이객체의 메소드를 호출할 때는 <code>myobject.method(arg1, arg2)</code> 와 같이 하며, 이것은 파이썬에 의해자동적으로 <code>MyClass.method(myobject, arg1, arg2)</code> 의 형태로 바뀌게 됩니다. 이것이 <code>self</code>에 대한 모든 것입니다.

또한 이것은 아무런 인수도 넘겨받지 않는 메소드를 정의할 때에도, <code>self</code> 라는 하나의 인수를추가해 주어야 한다는 것을 의미합니다.

14.2. 클래스

가장 단순한 클래스의 예시가 아래 예제에 나타나 있습니다(<code>oop_simplestclass.py</code> 로 저장하세요).

<code class="python language-python">class Person:    pass # An empty blockp = Person()print(p)</code>

실행 결과:

$ python oop_simplestclass.py<__main__.Person instance at 0x10171f518>
동작 원리

먼저 <code>class</code> 문을 사용하여 새로운 클래스를 생성하였고 적당한 이름을 지어 주었습니다. 그 아래로는들여쓰기 된 새로운 블록이 시작되며 이 블록은 클래스의 몸체를 구성합니다. 위 예제의 경우에는<code>pass</code> 문으로 해당 블록이 빈 블록임을 나타내 주었습니다.

다음으로, 이 클래스의 이름 뒤에 괄호를 열고 닫아 주어 클래스의 객체/인스턴스를 만들었습니다(다음 섹션에서 객체 초기화 에 대해 좀 더 자세히 배울 것입니다). 객체가 잘 생성되었는지확인해 보기 위해, 정의한 변수명을 입력하여 결과를 확인해 봅니다. 그러면 이 객체는 <code>__main__</code> 모듈의<code>Person</code> 클래스의 인스턴스임을 알 수 있습니다.

또 객체가 실제로 저장된 컴퓨터 메모리의 위치가 함께 반환되는 것을 확인하시기 바랍니다. 컴퓨터마다그 객체를 저장하기 위한 빈 공간이 위치한 곳이 다를 것이므로 컴퓨터마다 이 값은 다르게 출력될것입니다.

14.3. 메소드

앞서 클래스/객체는 메소드를 가질 수 있으며, 메소드는 추가된 <code>self</code> 변수를 제외하고 함수와 똑같다는것에 대해 이야기했습니다. 아래는 예제입니다(<code>oop_method.py</code> 로 저장하세요).

<code class="python language-python">class Person:    def say_hi(self):        print('Hello, how are you?')p = Person()p.say_hi()# The previous 2 lines can also be written as# Person().say_hi()</code>

실행 결과:

$ python oop_method.pyHello, how are you?
동작 원리

위 예제는 <code>self</code> 가 어떻게 동작하는지 보여줍니다. 여기서 <code>say_hi</code> 메소드는 아무 매개 변수도넘겨받지 않지만 함수 정의에 <code>self</code> 를 가지고 있음을 확인하시기 바랍니다.

14.4. <code>__init__</code> 메소드

파이썬의 클래스에는 여러가지 특별한 메소드 이름이 존재합니다. 우선 그 중 <code>__init__</code> 메소드의중요성에 대해 알아보겠습니다.

<code>__init__</code> 메소드는 클래스가 인스턴스화 될 때 호출됩니다. 따라서 이 메소드는 객체가 생성될 때여러가지 초기화 명령들이 필요할 때 유용하게 사용됩니다. 여기서 init의 앞과 뒤에 있는 밑줄은두 번씩 입력해야 한다는 점을 기억하시기 바랍니다.

예제 (<code>oop_init.py</code> 로 저장하세요):

<code class="python language-python">class Person:    def __init__(self, name):        self.name = name    def say_hi(self):        print 'Hello, my name is', self.namep = Person('Swaroop')p.say_hi()# The previous 2 lines can also be written as# Person('Swaroop').say_hi()</code>

실행 결과:

$ python oop_init.pyHello, my name is Swaroop
동작 원리

먼저 매개 변수 <code>name</code> 을 넘겨 받는 <code>__init__</code> 메소드를 정의합니다(물론 <code>self</code>를 포함하여 정의합니다).그리고, <code>name</code> 이라는 필드를 생성합니다. 이 때 두 다른 변수의 이름으로 name 이라는 동일한이름을 지정해 주었다는 점에 주목하시기 바랍니다. 이것이 문제가 되지 않는 이유는 하나는"self" 라 칭해지는 객체에 내장된 것으로써 <code>self.name</code> 의 형태로 사용되며 또 하나인 <code>name</code> 은지역 변수를 의미하는 것으로 사용되기 때문입니다. 프로그램 상에서 각각을 완전하게 구분할수 있으므로, 혼란이 일어나지 않습니다.

위 예제에서 가장 중요한 것은, 우리가 <code>__init__</code> 메소드를 직접 호출해 주지 않고 클래스로부터인스턴스를 생성할 때 괄호 안에 인수를 함께 넘겨 주었다는 점입니다. 이 점이 이 메소드가 좀특별하게 다뤄지는 이유입니다.

이제, <code>sayHi</code> 메소드에서처럼 객체 내부에서 <code>self.name</code> 필드를 사용할 수 있습니다.

14.5. 클래스 변수와 객체 변수

앞서 클래스와 객체가 어떤 기능을 갖도록 하는 방법, 즉 메소드에 대해 설명했습니다. 이제 데이터의경우 어떻게 하는지 배워봅시다. 데이터, 즉 필드는 일반적인 변수와 다를 것이 없으나 딱 한 가지,그 클래스 혹은 객체의 네임스페이스묶여 있다는 점이 다릅니다. 이것은 필드의 이름은 그클래스 혹은 객체 내부에서만 의미가 있음을 의미합니다. 그래서 이것을 이름이 통용되는 공간이라고 하여 네임스페이스 라고 부릅니다.

필드 에는 두 종류가 있는데, 클래스 변수와 객체 변수입니다. 각각은 그것을 소유하고 있는 대상이클래스인지 객체인지에 따라 구분됩니다.

클래스 변수 는 공유됩니다. 즉, 그 클래스로부터 생성된 모든 인스턴스들이 접근할 수 있습니다.클래스 변수는 한 개만 존재하며 어떤 객체가 클래스 변수를 변경하면 모든 다른 인스턴스들에 변경 사항이반영됩니다.

객체 변수 는 클래스로부터 생성된 각각의 객체/인스턴스에 속해 있는 변수입니다. 이 경우에는, 각각의객체별로 객체 변수를 하나씩 따로 가지고 있으며, 서로 공유되지 않고 각 인스턴스에 존재하는 같은 이름의필드끼리 서로 어떤 방식으로든 간섭되지 않습니다. 아래 예제를 통해 좀 더 자세히 알아봅시다.(<code>oop_objvar.py</code> 로 저장하세요):

<code class="python language-python">class Robot:    """Represents a robot, with a name."""    # A class variable, counting the number of robots    population = 0    def __init__(self, name):        """Initializes the data."""        self.name = name        print "(Initializing {})".format(self.name)        # When this person is created, the robot        # adds to the population        Robot.population += 1    def die(self):        """I am dying."""        print "{} is being destroyed!".format(self.name)        Robot.population -= 1        if Robot.population == 0:            print "{} was the last one.".format(self.name)        else:            print "There are still {:d} robots working.".format(                Robot.population)    def say_hi(self):        """Greeting by the robot.        Yeah, they can do that."""        print "Greetings, my masters call me {}.".format(self.name)    @classmethod    def how_many(cls):        """Prints the current population."""        print "We have {:d} robots.".format(cls.population)droid1 = Robot("R2-D2")droid1.say_hi()Robot.how_many()droid2 = Robot("C-3PO")droid2.say_hi()Robot.how_many()print "\nRobots can do some work here.\n"print "Robots have finished their work. So let's destroy them."droid1.die()droid2.die()Robot.how_many()</code>

실행 결과:

$ python oop_objvar.py(Initializing R2-D2)Greetings, my masters call me R2-D2.We have 1 robots.(Initializing C-3PO)Greetings, my masters call me C-3PO.We have 2 robots.Robots can do some work here.Robots have finished their work. So let's destroy them.R2-D2 is being destroyed!There are still 1 robots working.C-3PO is being destroyed!C-3PO was the last one.We have 0 robots.
동작 원리

예제가 좀 길지만, 클래스/객체 변수의 이해를 돕도록 만들어져 있습니다. 여기서 <code>population</code> 은<code>Robot</code> 클래스에 속해 있는 클래스 변수입니다. 또, <code>name</code> 변수는 객체에 소속되어 있는 (즉<code>self</code> 를 이용하여 사용되는) 객체 변수입니다.

또한, <code>population</code> 클래스 변수는 <code>Robot.population</code> 과 같이 사용하며 <code>self.population</code> 과 같이사용하지 않습니다. 반면 객체 변수 <code>name</code> 은 그 객체 안에서 <code>self.name</code> 과 같이 사용됩니다.이러한 클래스 변수와 객체 변수의 작은 차이점에 유의하시기 바랍니다. 또, 클래스 변수와 같은이름을 가진 객체 변수는 클래스 변수를 감춘다는 점을 기억하세요!

<code>Ropot.population</code> 대신에 <code>self.__class__.population</code> 라고도 사용할 수 있는데 이것은 모든객체는 그 객체를 생성하는 데 사용되었던 클래스를 <code>self.__class__</code> 속성을 통해 참조하고 있기때문입니다.

메소드 <code>how_many</code> 는 객체에 소속되어 있지 않고 클래스에 소속되어 있는 메소드입니다. 여기서우리가 해당 클래스의 어떤 부분까지 알아야 할 지에 따라 메소드를 <code>클래스 메소드(class mathod)</code>로 정의할지 <code>스태틱 메소드(static method)</code> 로 정의할지 결정할 수 있습니다. 여기서는 클래스변수를 사용할 것이므로, <code>클래스 메소드</code> 를 사용합시다.

여기서는 <code>how_many</code> 메소드를 클래스 메소드로 만들어 주기 위해 데코레이터 를이용하였습니다.

데코레이터는 어떤 일을 추가로 해 주는 더 큰 함수로 해당 부분을 감싸주는 것이라고 생각하면됩니다. 즉, <code>@classmethod</code> 데코레이터는 아래처럼 호출하는 것과 같습니다:

<code class="python language-python">how_many = classmethod(how_many)</code>

<code>__init__</code> 메소드는 <code>Robot</code> 의 인스턴스를 초기화시킬 때 사용됩니다. 이 메소드를 통해 로봇이 하나추가될 때마다 로봇의 개수를 의미하는 변수 <code>population</code> 을 1 씩 증가시켜 줍니다. 또한 각 생성된객체별로 객체 변수 <code>self.name</code> 의 값을 따로따로 지정해 주었습니다.

객체에 속해 있는 변수와 메소드에 접근하기 위해서는 반드시 <code>self</code> 를 사용해야 한다는 점을기억하시기 바랍니다. 이것을 다른 말로 속성 참조(attribute reference) 라 부릅니다.

프로그램을 살펴보면 메소드에 정의된 것 처럼 클래스에도 DocString 이 정의되어 있는 것을 보실 수있습니다. 마찬가지로 이 DocString에도 <code>Robot.__doc__</code> 을 통해 접근할 수 있고, 또 메소드의 DocString은 <code>Robot.say_hi.__doc__</code> 과 같이 접근할 수 있습니다.

<code>die</code> 메소드가 실행되면, 간단히 <code>Robot.population</code> 을 하나 줄여 줍니다.

모든 클래스 멤버는 클래스 외부에 공개되어 있습니다. 한가지 예외가 있는데, 여러분이 밑줄 두 개로 시작하는 데이터 멤버를 정의할 때, 즉 예를 들어 <code>__privatevar</code> 와 같이 하면, 파이썬이이것을 클래스 외부로 드러나지 않도록 숨겨 줍니다.

이것은 클래스나 객체에 속해 있는 어떤 변수에나 적용됩니다. 클래스와 객체에 정의된 모든 이름은밑줄로 시작하지 않는 이상 외부로 공개하고 다른 클래스나 객체에서 불러와 사용할 수 있도록 하는 규칙을따르는 것이 좋습니다. 그러나 이것은 파이썬에서 강제하는 것이 아니며 (밑줄 두 개로 시작하는 경우를제외하고) 프로그래머들끼리의 약속입니다.

Note
C++/Java/C# 프로그래머를 위한 주석
모든 클래스 멤버는 (데이터 멤버를 포함하여) public 이며 따라서 파이썬의 모든 메소드는 virtual입니다.

14.6. 상속

객체 지향 프로그래밍의 또 다른 큰 장점은 코드를 재사용 할 수 있다는 것인데 이를 위한 한 가지방법으로 상속 이 사용됩니다. 상속은 클래스 간의 형식과 세부 형식 을 구현하는 것이라고 생각해볼수 있습니다.

어러분이 어떤 대학의 교수들과 학생들의 명부를 작성하는 프로그램을 작성한다고 해 봅시다.이 때 교수와 학생 모두 공통적으로 이름, 나이, 주소 등의 성질을 가지고 있을 것이며, 교수에만적용되는 성질로는 연봉, 과목, 휴가 등이 있을 것이고, 학생에만 적용되는 성질로는 성적, 등록금등이 있을 것입니다.

따라서 여러분은 각각의 경우에 두 독립적인 클래스를 만들 수 있겠지만, 이 경우 각각의 공통적인 성질또한 각각의 클래스에 두 번씩 반복해서 정의해 주어야 할 것입니다. 매우 불편합니다.

더 나은 방법은 <code>SchoolMember</code> 라는 이름으로 공통 클래스를 생성한 뒤 교수와 학생 클래스를 이 클래스로부터상속 받아 생성하는 것입니다. 이 경우 상속받은 클래스들은 이를테면 상위 형식(클래스) 의 세부 형식이되는 것이고, 따라서 이 세부 형식에 각 상황에 맞는 세부적인 성질들을 추가해 줄 수 있는 것입니다.

이러한 접근 방식에는 많은 장점이 있습니다. 그 중 한 장점은 우리가 <code>SchoolMember</code> 에 새로운 기능을추가하거나 혹은 있던 기능을 수정하게 되면, 그 하위 클래스인 교수와 학생 클래스에도 이러한 변경사항이 자동으로 추가된다는 점입니다. 예를 들어 교수와 학생들에게 새로 출입증을 발급해야 할 경우SchoolMember 클래스에 이를 적용해 주기만 하면 되는 것이죠. 반대로 하위 클래스에 적용된 변경 사항은다른 하위 클래스에 적용되지 않습니다. 또 다른 장점은 여러분이 예를 들어 대학에 소속된 사람들의모든 숫자를 파악해야 한다고 할 경우 교수와 학생 객체를 <code>SchoolMember</code> 객체로써 참조하여 사용할수 있다는 점입니다. 이것을 다형성 이라고 부르는데, 하위 형식이 부모 형식을 필요로 하는 어떤상황에서건 이를 대신하여 사용될 수 있다는 것을 의미합니다. 즉, 자식 클래스의 객체를 부모 클래스의인스턴스인 것처럼 다루어질 수 있습니다.

따라서 상속을 이용하면 부모 클래스의 코드를 재사용할 수 있고 서로 완전히 독립적인 클래스들을 정의했을때처럼 각각 다른 클래스에 이를 또 반복해서 써 줄 필요가 없다는 것입니다.

이 상황에서의 <code>SchoolMember</code> 클래스를 기본 클래스 혹은 슈퍼 클래스 라고 부릅니다. 또 <code>Teacher</code>와 <code>Student</code> 클래스는 파생 클래스 혹은 서브 클래스 라고 부릅니다.

다음 프로그램을 예제로 살펴 보겠습니다(<code>oop_subclass.py</code> 로 저장하세요):

<code class="python language-python">class SchoolMember:    '''Represents any school member.'''    def __init__(self, name, age):        self.name = name        self.age = age        print '(Initialized SchoolMember: {})'.format(self.name)    def tell(self):        '''Tell my details.'''        print 'Name:"{}" Age:"{}"'.format(self.name, self.age),class Teacher(SchoolMember):    '''Represents a teacher.'''    def __init__(self, name, age, salary):        SchoolMember.__init__(self, name, age)        self.salary = salary        print '(Initialized Teacher: {})'.format(self.name)    def tell(self):        SchoolMember.tell(self)        print 'Salary: "{:d}"'.format(self.salary)class Student(SchoolMember):    '''Represents a student.'''    def __init__(self, name, age, marks):        SchoolMember.__init__(self, name, age)        self.marks = marks        print '(Initialized Student: {})'.format(self.name)    def tell(self):        SchoolMember.tell(self)        print 'Marks: "{:d}"'.format(self.marks)t = Teacher('Mrs. Shrividya', 40, 30000)s = Student('Swaroop', 25, 75)# prints a blank lineprintmembers = [t, s]for member in members:    # Works for both Teachers and Students    member.tell()</code>

실행 결과:

$ python oop_subclass.py(Initialized SchoolMember: Mrs. Shrividya)(Initialized Teacher: Mrs. Shrividya)(Initialized SchoolMember: Swaroop)(Initialized Student: Swaroop)Name:"Mrs. Shrividya" Age:"40" Salary: "30000"Name:"Swaroop" Age:"25" Marks: "75"
동작 원리

상속을 사용하기 위해, 예제에서 정의된 여러 기본 클래스들의 이름들이 상속 튜플에 지정됩니다. 다음으로,기본 클래스의 <code>__init__</code> 메소드가 <code>self</code> 변수를 이용하여 명시적으로 호출되며 따라서 객체의 기본 클래스에정의된 초기화 명령들을 호출합니다. 즉, 파이썬은 기본 클래스의 생성자를 자동으로 호출해 주지 않으므로명시적으로 이것을 호출해 주어야 한다는 점을 기억하시기 바랍니다.

또한 기본 클래스의 메소드를 호출할 때 클래스 이름을 메소드 호출에 지정해 주었고 또 <code>self</code> 변수에인수들과 함께 넘겨 주었습니다.

여기서 <code>SchoolMember</code> 클래스의 <code>tell</code> 메소드를 사용할 때, <code>Teacher</code> 나 <code>Student</code> 와 같은 인스턴스들을<code>SchoolMember</code> 의 인스턴스로써 사용하였다는 점을 확인하시기 바랍니다.

또, 위에서 <code>tell</code> 메소드를 호출할 때 하위 클래스의 메소드가 호출되었고 <code>SchoolMember</code> 클래스의메소드가 호출되지 않았다는 것을 확인하세요. 즉, 파이썬은 언제나 해당 형식 안에서 해당 메소드가 있는지찾고, 여기서 메소드를 찾지 못한 경우 그 클래스의 기본 클래스를 한 단계씩 찾아 올라가면서 해당 메소드가있는지 계속 확인한다는 것을 기억하시면 이해하기 쉬울 것입니다.

상속 튜플에 하나 이상의 클래스가 등록되어 있을 경우, 이것을 다중 상속 이라고 부릅니다.

슈퍼 클래스의 <code>tell()</code> 메소드에서 <code>print</code> 문 뒤에 붙어 있는 쉼표는 그 다음에 출력 될 내용을 새로운줄에 출력하지 말고 그 줄에 이어서 출력하라는 것을 의미합니다. 이것은 <code>print</code> 가 <code>\n</code> (줄바꿈) 문자를마지막에 입력하지 않게 하는 것입니다.

14.7. 요약

지금까지 클래스와 객체의 다양한 속성에 대해 알아 보았으며, 또 통용되는 용어들에 대해서도 알아보았습니다. 또한 객체 지향 프로그래밍을 사용할 때의 장점과 주의해야 할 점에 대해서도 알아 보았습니다. 파이썬은 고도의 객체 지향 언어로 이러한 개념을 잘 익혀 두면 여러분이 좋은 파이썬 프로그래머로서꾸준히 성장할 수 있게 될 것입니다.

다음으로, 파이썬에서의 입/출력을 다루는 법과 파일을 읽고 쓰는 법에 대해 배워 보겠습니다.

15. 입력과 출력

프로그램을 만들다 보면 간혹 프로그램이 사용자와 상호 작용을 해야 할 때가 있을 것입니다. 예를 들어,사용자로부터 뭔가를 입력받고 처리 결과를 출력해 주는 것 같은 일이 필요할 때입니다. 파이썬에서는이를 위해 각각 <code>raw_input()</code> 함수와 <code>print</code> 문을 사용합니다.

결과를 출력해주기 위해서는 <code>str</code> (문자열) 클래스가 제공하는 여러 메소드를 사용할 수도 있습니다.예를 들면, <code>rjust</code> 메소드를 사용하여 출력될 문자열이 특정 폭의 문자열 안에서 오른쪽 정렬되도록할 수 있습니다. <code>help(str)</code> 을 실행하여 이들에 대해 자세히 알아보시기 바랍니다.

또 다른 입/출력의 형식은 파일을 다루는 것입니다. 파일을 생성하고, 읽고, 쓰는 것은 많은 프로그램에서중요한 부분을 차지하고 있으며 이 챕터에서는 이러한 기능에 대해 자세히 알아보게 될 것입니다.

15.1. 사용자로부터 입력받기

<code>io_input.py</code> 로 저장하세요:

<code class="python language-python">def reverse(text):    return text[::-1]def is_palindrome(text):    return text == reverse(text)something = raw_input("Enter text: ")if is_palindrome(something):    print "Yes, it is a palindrome"else:    print "No, it is not a palindrome"</code>

실행 결과:

$ python io_input.pyEnter text: sirNo, it is not a palindrome$ python io_input.pyEnter text: madamYes, it is a palindrome$ python io_input.pyEnter text: racecarYes, it is a palindrome
동작 원리

문자열을 뒤집기 위해서는 슬라이스를 사용합니다. 앞서 보았듯이 열거형의 슬라이스기능을 이용하여 <code>seq[a:b]</code> 와 같은 코드를 통해 위치 <code>a</code> 부터 위치 <code>b</code> 까지 문자열을 얻어올 수있습니다. 슬라이스 숫자에 세 번째 인수를 넘겨 주어 슬라이스 스텝 을 지정해줄 수 있습니다.스텝을 지정하지 않으면 기본값 <code>1</code> 이 지정되며, 이 경우 지정된 문자열을 차례로 슬라이스 하는 것을의미합니다. 음의 스텝을 지정하면 열거형의 마지막부터 반대 방향으로 슬라이스가 진행되며,예를 들어 <code>-1</code> 을 지정하면 뒤집혀진 문자열이 반환됩니다.

<code>raw_input()</code> 함수는 인수로 넘겨받은 문자열을 화면에 표시해 줍니다. 그리고 나서는 사용자가사용자가 무언가를 입력하고 엔터 키를 누를 때까지 기다립니다. 사용자가 입력을 마치고 엔터 키를누르면 <code>raw_input()</code> 함수는 사용자가 입력한 내용을 문자열로 반환해 줍니다.

이제 이 문자열을 받아서 뒤집어 줍니다. 여기서 뒤집혀진 문자열이 뒤집혀지지 않았을 때의 문자열과동일할 때, 이것을 영어로 palindrome 이라고 부릅니다.

15.1.1. 연습 문제

어떤 문자열이 palindrome이라고 하는 것은 그 안에 포함된 문장 부호들과 공백 등을 제외한 문자들을가지고만 판단해야 합니다. 예를 들어, "Rise to vote, sir." 은 palindrome이지만 위 예제 프로그램은이것은 palindrome이 아니라고 판단할 것입니다. 위 프로그램을 고쳐서 이러한 문자열들을 palindrome으로인식할 수 있는 프로그램을 작성해 보시기 바랍니다.

힌트를 하나 드리자면, 다음과 같이 하세요… [1]

15.2. 파일 입/출력

입/출력을 위해 파일을 열고 사용하려면 <code>file</code> 클래스의 객체를 생성한 후 <code>read</code>, <code>readline</code>, <code>write</code>와 같은 메소드들을 적절히 활용하면 됩니다. 파일을 열때 파일을 읽는 모드와 쓰는 모드를 따로지정해 줄 수 있습니다. 마지막으로 파일을 읽거나 쓰는 일을 모두 마친 후에는, <code>close</code> 메소드를호출하여 파이썬에게 그 파일을 다 사용했다는 것을 알려 주어야 합니다.

예제 (<code>io_using_file.py</code> 로 저장하세요):

<code class="python language-python">poem = '''\Programming is funWhen the work is doneif you wanna make your work also fun:    use Python!'''# Open for 'w'ritingf = open('poem.txt', 'w')# Write text to filef.write(poem)# Close the filef.close()# If no mode is specified,# 'r'ead mode is assumed by defaultf = open('poem.txt')while True:    line = f.readline()    # Zero length indicates EOF    if len(line) == 0:        break    # The `line` already has a newline    # at the end of each line    # since it is reading from a file.    print line,# close the filef.close()</code>

실행 결과:

$ python io_using_file.pyProgramming is funWhen the work is doneif you wanna make your work also fun:    use Python!
동작 원리

먼저, 내장 함수 <code>open</code> 을 이용하여 파일을 열어 줍니다. 이 때 파일을 어떤 용도로 사용할 것인지도함께 지정해 줍니다. 각 모드로는 읽기 모드 (<code>'r'</code>), 쓰기 모드 (<code>'w'</code>), 덧붙임 모드 (<code>'a'</code>) 등이있습니다. 또한 우리가 다룰 파일을 일반적인 텍스트 모드 (<code>'t'</code>) 로 다룰 지 또는 바이너리 모드 (<code>'b'</code>)로 다룰 지 여부도 함께 지정해 줄 수 있습니다. 이외에도 여러가지 다른 모드들이 있으며, <code>help(open)</code>을 통해 그 목록을 확인해 볼 수 있습니다. 모드에 아무것도 지정하지 않으면, <code>open()</code> 은 기본적으로파일을 텍스트('t’ext) 모드의 읽기('r’ead) 모드로 파일을 열어 줍니다.

위 예제에서는 먼저 파일을 쓰기/텍스트 모드로 열고 파일 객체의 <code>write</code> 메소드를 사용하여 파일에써준 후 <code>close</code> 로 파일을 닫아 줍니다.

다음으로는, 똑같은 파일을 이번에는 읽기 모드로 엽니다. 이 때 아무 모드도 지정하지 않았는데이렇게 하면 기본값인 읽기/텍스트 모드 가 지정됩니다. 파일을 연 후에는 반복문을 이용하여파일의 <code>readline</code> 메소드를 통해 파일의 내용을 한 줄씩 읽어옵니다. 이 메소드는 파일 내용을 읽다가줄바꿈 문자를 만날 때까지 한 줄을 읽어서 그 모든 내용을 반환해 줍니다. 만약 문자열이반환되었을 경우, 이것은 파일의 끝임을 의미하는 것이므로 break 문을 통해 반복문을 빠져나옵니다.

마지막으로, <code>close</code> 문으로 파일을 닫습니다.

이제 <code>poem.txt</code> 파일을 직접 열어 보시고 예제 프로그램이 올바른 내용을 쓰고 읽었는지 다시한번 확인해 보시기 바랍니다.

15.3. Pickle

파이썬은 <code>pickle</code> 이라고 불리우는 기본 모듈을 제공하는데, 이것은 어떤 파이썬 객체이든지파일로 저장해 두었다가 나중에 불러와서 사용할 수 있게 하는 모듈입니다. 이것을 객체를영구히 저장해 둔다고 합니다.

예제 (<code>io_pickle.py</code> 로 저장하세요):

<code class="python language-python">import pickle# The name of the file where we will store the objectshoplistfile = 'shoplist.data'# The list of things to buyshoplist = ['apple', 'mango', 'carrot']# Write to the filef = open(shoplistfile, 'wb')# Dump the object to a filepickle.dump(shoplist, f)f.close()# Destroy the shoplist variabledel shoplist# Read back from the storagef = open(shoplistfile, 'rb')# Load the object from the filestoredlist = pickle.load(f)print storedlist</code>

실행 결과:

$ python io_pickle.py['apple', 'mango', 'carrot']
동작 원리

파일에 객체를 저장하기 위해서 먼저 <code>open</code> 문을 이용하여 쓰기/바이너리 모드로 파일을 열어준 후 <code>pickle</code> 모듈의 <code>dump</code> 함수를 호출하여 줍니다. 이 과정을 피클링(pickling) 이라고 합니다.

다음으로 <code>pickle</code> 모듈의 <code>load</code> 함수를 이용하여 파일에 저장된 객체를 불러옵니다. 이 과정을언피클링(unpickling) 이라고 합니다.

15.4. 유니코드

지금까지 우리가 문자열을 쓰거나 읽고, 또 파일에 쓸 때에 영어 알파벳 문자들만을 주로 이용해왔습니다. 만약 여러분이 영어가 아닌 다른 언어로 된 문자를 읽고 쓰고 싶을 경우에는<code>unicode</code> 형식을 이용할 필요가 있으며, 이것은 문자 <code>u</code> 를 앞에 붙여 주어 지정해 줍니다:

>>> "hello world"'hello world'>>> type("hello world")<type 'str'="">>>> u"hello world"u'hello world'>>> type(u"hello world")<type 'unicode'=""></type></type>

비 영어권 언어를 다룰 때에는 <code>str</code> 대신 <code>unicode</code> 형식을 사용하여 문자를 다루어 주어야 합니다.그러나 여러분이 파일을 읽고 쓰거나 인터넷 상의 다른 컴퓨터와 교신하려고 할 때에는 이러한 유니코드문자열들을 송수신 가능한 형태로 바꾸어 주어야 하며, 이러한 형식의 이름을 "UTF-8" 이라고 부릅니다.다음과 같이 <code>open</code> 표준 함수에 간단한 키워드 인수를 넘겨 줌으로써 이 형식을 사용하여 파일을읽고 쓰게 할 수 있습니다.

<code class="python language-python"># encoding=utf-8import iof = io.open("abc.txt", "wt", encoding="utf-8")f.write(u"Imagine non-English language here")f.close()text = io.open("abc.txt", encoding="utf-8").read()print text</code>
동작 원리

당장은 <code>import</code> 문은 무시하셔도 됩니다. 여기에 대해서는 모듈 챕터에서 상세히 다룰것입니다.

위에서 사용한 것과 같이 유니코드 문자가 포함된 프로그램을 작성할 때에는 반드시 파이썬에게이 프로그램이 UTF-8 형식을 사용하여 작성되었음을 알려 주어야 하며, 이를 위해 <code># encoding=utf-8</code>과 같이 프로그램의 맨 윗줄에 주석을 한 줄 입력하여 줍니다.

<code>io.open</code> 문을 사용할 때에는 "encoding" 과 "decoding" 인수를 넘겨 주어 파이썬에게 우리가 유니코드를사용할 것임을 알려 주고, 또 문자열을 넘겨 줄 때에는 <code>u""</code> 와 같이 해 주어 우리가 유니코드 문자열을사용중이라는 것을 명확하게 해 줍니다.

다음 글들을 읽어 보시면 더 많은 것들을 배울 수 있을 것입니다:

15.5. 요약

지금까지 여러가지 종류의 입/출력 및 파일을 다루는 법, 그리고 pickle 모듈을 다루는 법과 유니코드에 대해배워 보았습니다.

다음으로는 예외 처리의 개념에 대해 알아봅시다.

16. 예외 처리

예외란 말 그대로 프로그램에서 벌어지는 예외적인 상황을 뜻합니다. 예를 들자면 여러분이 파일을읽고자 할 때 그 파일이 존재하지 않는 경우라던지, 또는 프로그램이 한참 실행중인데 그 파일을갑자기 지워버렸다던지 하는 경우 등입니다. 이러한 상황을 처리해 주는 것을 예외 처리 라고 합니다.

비슷하게 여러분의 프로그램에 존재하지 않는 명령문이 있을 경우 어떻게 될까요? 이런 경우 파이썬은손을 들고(raise) 프로그램에 오류(error) 가 있다고 알려 줍니다.

16.1. 오류

간단한 <code>print</code> 함수를 호출하는 상황을 생각해 봅시다. 이 때 <code>print</code> 를 <code>Print</code> 라고 잘못쳤을 경우 어떻게 될까요? 대/소문자 구분에 유의하세요. 이 경우, 파이썬은 구문 오류를 발생시킵니다.

>>> Print "Hello World"  File "<stdin>", line 1    Print "Hello World"                      ^SyntaxError: invalid syntax>>> print "Hello World"Hello World</stdin>

위와 같이 <code>SyntaxError (구문 오류)</code> 가 발생되었고 오류가 발생한 위치가 표시됩니다.이것은 이 오류의 오류 핸들러 에 의해 처리되는 것입니다.

16.2. 예외

이번에는 사용자로부터 뭔가를 입력 받는 것을 시도하는(try) 경우를 생각해 봅시다. 이 때 <code>ctrl-d</code>를 누르고 어떻게 되는지 살펴봅시다.

>>> s = raw_input('Enter something --> ')Enter something --> Traceback (most recent call last):  File "<stdin>", line 1, in <module>EOFError</module></stdin>

그러면 파이썬은 <code>EOFError</code> 라고 불리우는 오류를 발생시키는데 이때 EOF란 파일의 끝(end of file) 을의미하며(파일의 끝은 <code>ctrl-d</code> 에 의해 표현됩니다), 갑자기 파일의 끝이 올 것을 예상하지 못했기 때문에위와 같은 오류가 발생하는 것입니다.

16.3. 예외 처리

예외는 <code>try..except</code> 문을 통해 처리할 수 있습니다. 이것은 try 블록 안에 평소와 같이 명령을 입력하고예외 상황에 해당하는 오류 핸들러를 except 블록에 입력해 주면 됩니다.

예제 (<code>exceptions_handle.py</code> 로 저장하세요):

<code class="python language-python">try:    text = raw_input('Enter something --> ')except EOFError:    print 'Why did you do an EOF on me?'except KeyboardInterrupt:    print 'You cancelled the operation.'else:    print 'You entered {}'.format(text)</code>

실행 결과:

# Press ctrl + d$ python exceptions_handle.pyEnter something --> Why did you do an EOF on me?# Press ctrl + c$ python exceptions_handle.pyEnter something --> ^CYou cancelled the operation.$ python exceptions_handle.pyEnter something --> No exceptionsYou entered No exceptions
동작 원리

이 예제에서는 예외가 발생할 수 있는 모든 명령문을 <code>try</code> 블록에 넣어 주었으며 오류/예외를 적절하게 처리해줄 핸들러를 <code>except</code> 절/블록에 넣어 주었습니다. <code>except</code> 절에서는 지정된 한 개의 오류 혹은 예외를 처리할수도 있고, 괄호로 묶여진 모든 오류/예외 목록을 처리해 줄 수도 있습니다. 만일 오류/예외가 지정되지 않은경우에는 모든 오류/예외를 처리하게 됩니다.

이 때 모든 <code>try</code> 절에는 적어도 한 개의 <code>except</code> 절이 있어야 합니다. 아니면 try 블록을 사용할 아무런 이유가없겠지요?

만약 어떤 오류나 예외든지 이처럼 처리되지 않는 경우, 기본 파이썬 오류 핸들러가 호출되는데 그러면 이에 의해프로그램의 수행이 중단되며 해당하는 오류 메시지가 출력됩니다. 위에서 기본 파이썬 오류 핸들러가 어떻게동작하는지 보았습니다.

또한 <code>try..except</code> 블록에는 추가로 <code>else</code> 절을 붙여줄 수 있습니다. <code>else</code> 절은 어떤 예외도 발생하지 않았을경우 호출됩니다.

다음 예제에서 예외 객체를 얻어오는 방법과 이를 통해 추가 정보를 알아내는 방법에 대해 알아보겠습니다.

16.4. 예외 발생시키기

<code>raise</code> 문에 오류/예외의 이름을 넘겨 주는 것을 통해 예외를 직접 발생(raise) 시킬 수 있습니다.그러면 예외 객체가 throw 됩니다.

이 때 발생시킬 수 있는 오류나 예외는 반드시 직접적으로든 간접적으로든 <code>Exception</code> 클래스에서 파생된클래스이어야 합니다.

예제 (<code>exceptions_raise.py</code> 로 저장하세요):

<code class="python language-python">class ShortInputException(Exception):    '''A user-defined exception class.'''    def __init__(self, length, atleast):        Exception.__init__(self)        self.length = length        self.atleast = atleasttry:    text = raw_input('Enter something --> ')    if len(text) < 3:        raise ShortInputException(len(text), 3)    # Other work can continue as usual hereexcept EOFError:    print 'Why did you do an EOF on me?'except ShortInputException as ex:    print ('ShortInputException: The input was ' + \           '{0} long, expected at least {1}')\          .format(ex.length, ex.atleast)else:    print 'No exception was raised.'</code>

실행 결과:

$ python exceptions_raise.pyEnter something --> aShortInputException: The input was 1 long, expected at least 3$ python exceptions_raise.pyEnter something --> abcNo exception was raised.
동작 원리

위 예제에서는 <code>ShortInputException</code> 이라고 불리우는 새로운 예외 형식을 직접 하나 만들어 보았습니다.여기에는 두 개의 필드가 있습니다. 하나는 <code>length</code> 필드로 주어진 입력의 길이를 의미하며, 또 하나는<code>atleast</code> 필드로 프로그램이 요구하는 최소한의 길이를 의미합니다.

이제 <code>except</code> 절에서 <code>as</code> 를 이용하여 해당 오류의 클래스를 좀 더 짧은 이름의 변수로 대신하여 사용할수 있게 해 줍니다. 여기서 새로 정의한 예외 형식에 정의한 필드와 값의 관계는 마치 함수에서의 매개 변수와인수의 관계와 비슷합니다. 마지막으로 이 오류를 처리해주는 <code>except</code> 절에서는 해당 예외 객체의 <code>length</code> 와<code>atleast</code> 필드를 이용하여 사용자에게 적절한 결과를 출력해 줍니다.

16.5. Try … Finally 문

프로그램이 파일을 읽고 있는 상황을 가정해 봅시다. 이 때 예외가 발생할 경우, 예외의 발생 여부와상관없이 파일 객체를 항상 닫아 주도록 할 수는 없을까요? 이를 위해 <code>finally</code> 블록을 사용합니다.

아래 프로그램을 <code>exceptions_finally.py</code> 로 저장하세요:

<code class="python language-python">import sysimport timef = Nonetry:    f = open("poem.txt")    # Our usual file-reading idiom    while True:        line = f.readline()        if len(line) == 0:            break        print line,        sys.stdout.flush()        print "Press ctrl+c now"        # To make sure it runs for a while        time.sleep(2)except IOError:    print "Could not find file poem.txt"except KeyboardInterrupt:    print "!! You cancelled the reading from the file."finally:    if f:        f.close()    print "(Cleaning up: Closed the file)"</code>

실행 결과:

$ python exceptions_finally.pyProgramming is funPress ctrl+c now^C!! You cancelled the reading from the file.(Cleaning up: Closed the file)
동작 원리

아주 평범한 파일을 읽는 코드를 작성하였지만, 파일에서 한 줄을 읽어올 때마다 <code>time.sleep</code> 함수를호출하여 2초씩 멈추게 하는 인위적인 코드를 집어넣어 프로그램이 천천히 실행되도록 해 주었습니다(파이썬은 원래 굉장히 빠릅니다). 프로그램이 실행중일 때, <code>ctrl + c</code> 를 눌러 프로그램을 강제로중단시켜 봅시다.

그러면 <code>KeyboardInterrupt</code> 예외가 발생되며 프로그램이 종료됩니다. 그러나 프로그램이 종료되기 전에finally 절이 실행되므로 파일 객체가 항상 닫히게 됩니다.

여기서 <code>print</code> 문 뒤에 <code>sys.stdout.flush()</code> 를 사용하여 화면에 결과를 바로바로 출력하도록 해주었습니다.

16.6. <code>with</code> 문

<code>try</code> 블록에서 시스템 자원을 가져오고 <code>finally</code> 문에서 이를 해제하여 주는 것은 공통된 패턴입니다.그렇지만, <code>with</code> 문을 이용하면 이것을 좀 더 깔끔하게 작성해 줄 수 있습니다.

<code>exceptions_using_with.py</code> 로 저장하세요:

<code class="python language-python">with open("poem.txt") as f:    for line in f:        print line,</code>
동작 원리

위 예제는 이전의 예제와 동일한 결과를 출력합니다. 차이점은 <code>open</code> 함수를 사용할 때 <code>with</code> 문을사용하였다는 것입니다. 그러면 파일을 직접 닫아 주지 않아도 <code>with open</code> 이 자동으로 파일을 닫아줍니다.

그러면 <code>with</code> 문은 어떻게 자동으로 이러한 것들을 처리해 주는 것일까요? 우선 <code>with</code> 문은 <code>open</code>문이 반환해 주는 객체를 받아 오는데, 일단 여기서는 이것을 "thefile" 이라고 해 봅시다.

<code>with</code> 문은 항상 <code>thefile.__enter__</code> 함수를 호출한 뒤 해당 블록의 코드를 실행하며, 실행이 끝난후에는 항상 <code>thefile.__exit__</code> 가 호출됩니다.

따라서 <code>finally</code> 블록에 써 준 코드가 <code>__exit__</code> 메소드에 의해 자동적으로 다루어져야 할 경우에만이를 사용할 수 있을 것입니다. 이런 경우, 위 방법대로 하면 매번 <code>try..finally</code> 문을 명시적으로쓰지 않고도 같은 일을 할 수 있습니다.

이에 대한 좀 더 자세한 설명은 이 책이 다루는 범위를 벗어납니다.자세한 설명은 PEP 343 을 읽어 보시기 바랍니다.

16.7. 요약

지금까지 <code>try..except</code> 문과 <code>try..finally</code> 문의 사용법을 배워 보았습니다. 또 사용자 정의 예외 형식을만드는 법과 예외를 일으키는 법에 대해서도 알아 보았습니다.

다음으로, 파이썬 표준 라이브러리에 대해 알아 보겠습니다.

16.8. 표준 라이브러리

파이썬 표준 라이브러리는 파이썬을 설치할 때 항상 함께 설치되는 많은 수의 유용한 모듈들을 말합니다.파이썬 표준 라이브러리에 익숙해지면 이를 이용해 해결할 수 있는 많은 문제들을 좀 더 빠르고 쉽게해결할 수 있습니다.

지금부터 표준 라이브러리에 포함된 많은 모듈 중에서 자주 사용되는 몇가지 모듈에 대해 알아볼 것입니다.파이썬 표준 라이브러리에 포함된 모든 모듈에 대한 자세한 설명은 파이썬과 함께 설치되는 설명서의라이브러리 레퍼런스 섹션 에서 확인해 보실 수 있습니다.

여기서는 유용한 몇 개의 모듈만 다뤄 보겠습니다.

Caution
이 챕터에서 다루는 내용은 조금 어려울 수 있습니다. 그런 경우 일단 이 챕터를 읽지 말고 넘기세요.그렇지만 여러분이 파이썬에 좀 더 익숙해지게 되면 이 챕터로 다시 돌아오기를 강력히 권합니다.

16.9. <code>sys</code> 모듈

<code>sys</code> 모듈에는 시스템의 기능을 다루는 여러 함수들이 들어 있습니다. 예를 들어 <code>sys.argv</code> 리스트에는명령줄 인수들이 들어 있습니다.

또 <code>sys</code> 모듈을 통해 현재 사용하고 있는 파이썬의 버전을 알아올 수 있습니다.

$ python>>> import sys>>> sys.version_infosys.version_info(major=2, minor=7, micro=6, releaselevel='final', serial=0)>>> sys.version_info.major == 2True
동작 원리

<code>sys</code> 모듈에는 <code>version_info</code> 라고 하는 파이썬의 버전 정보가 담겨 있는 튜플이 들어 있습니다.첫 번째항목은 주 버전을 의미합니다. 이제 이 정보를 읽어와 사용할 수 있습니다.

16.10. logging 모듈

여러분이 디버그를 할 때 중간에 변수들의 내용 등을 출력하고 싶거나 혹은 실행시 중요한 메시지를 어딘가에저장해 두게 하여 여러분의 프로그램이 제대로 실행되고 있는 지 확인하고 싶을 때 어떻게 하면 좋을까요?어떻게 이러한 메시지들을 "어딘가에 저장해" 둘 수 있을까요? 이를 위해 <code>logging</code> 모듈을 사용합니다.

<code>stdlib_logging.py</code> 로 저장하세요:

<code class="python language-python">import os, platform, loggingif platform.platform().startswith('Windows'):    logging_file = os.path.join(os.getenv('HOMEDRIVE'),                                os.getenv('HOMEPATH'),                                'test.log')else:    logging_file = os.path.join(os.getenv('HOME'),                                'test.log')print "Logging to", logging_filelogging.basicConfig(    level=logging.DEBUG,    format='%(asctime)s : %(levelname)s : %(message)s',    filename = logging_file,    filemode = 'w',)logging.debug("Start of the program")logging.info("Doing something")logging.warning("Dying now")</code>

실행 결과:

$ python stdlib_logging.pyLogging to /Users/swa/test.log$ cat /Users/swa/test.log2014-03-29 09:27:36,660 : DEBUG : Start of the program2014-03-29 09:27:36,660 : INFO : Doing something2014-03-29 09:27:36,660 : WARNING : Dying now

여러분의 명령행 환경에서 <code>cat</code> 명령을 사용할 수 없을 경우, 아무 텍스트 에디터에서나 <code>test.log</code>파일을 열어서 내용을 확인해 보실 수 있습니다.

동작 원리

위 예제에서는 표준 라이브러리에 있는 세 가지 다른 모듈을 사용하였습니다. 그 중 하나는 시스템의운영 체제와 상호 작용할 때 쓰이는 <code>os</code> 모듈이고, 또 하나는 플랫폼(운영 체제라던지)의 정보를알아오는 데 사용되는 <code>platform</code> 모듈이며 마지막 하나는 정보를 기록(log) 하는 데 사용되는<code>logging</code> 모듈입니다.

먼저, <code>platform.platform()</code> 이 반환해주는 문자열을 통해 현재 사용중인 운영 체제가 무엇인지알아옵니다 (이 모듈에 대해 더 자세히 알아보려면 <code>import platform; help(platform)</code> 을 입력하세요).이제 윈도우 플랫폼인 경우 홈 드라이브 및 홈 폴더를 알아내어 정보를 저장해 둘 파일 이름을 구성합니다.다른 플랫폼의 경우, 현재 사용자의 홈 폴더만 알면 파일의 전체 경로를 구성해낼 수 있습니다.

다음으로 <code>os.path.join()</code> 함수를 이용하여 이 세 문자열을 하나의 경로 문자열로 합쳐 줍니다. 이 때문자열을 단순히 합치지 않고 이러한 특별한 함수를 이용하여 합쳐 준 것은 합쳐진 최종 경로가 현재사용중인 운영 체제의 형식에 맞는 형태로 생성되도록 확실하게 해 두기 위함입니다.

이제 <code>logging</code> 모듈을 이용하여 필요한 기록 사항들을 지정해준 파일에 정해준 형식대로 기록합니다.

마지막으로 각 메시지가 디버깅 정보인지, 단순 정보인지, 경고나 혹은 중요한 메시지인지 등에 따라다르게 저장해 줍니다. 이 프로그램이 실행되어도 화면에는 아무것도 출력해 주지 않지만, 이 파일의내용을 확인해 보면 프로그램이 실행되며 어떤 일들이 일어났는지 확인할 수 있습니다.

16.11. 금주의 모듈 시리즈

파이썬 표준 라이브러리에는 다음과 같은 더 많은 모듈이 있습니다.디버깅 모듈,명령행 옵션 관련 모듈,정규 표현식 모듈 등등입니다.

파이썬 표준 라이브러리에 대해 좀 더 알아볼 수 있는 한 좋은 방법은 Doug Hellmann이 쓴금주의 파이썬 모듈 시리즈를 읽는 것입니다 (이것은 으로도 읽을 수 있습니다). 또 다른 좋은 방법은파이썬 문서 를 읽는 것입니다.

16.12. 요약

지금까지 파이썬 표준 라이브러리에 있는 많은 모듈의 몇몇 기능들에 대해 다뤄 보았습니다. 이에 만족하지 말고,파이썬 표준 라이브러리 문서 를 읽고 사용 가능한 모든 모듈에 대한 정보를알아보는 것을 추천해 드립니다.

다음으로는, 우리의 파이썬 여정을 좀 더 완전하게 해 줄 파이썬의 여러 장점에 대해 알아 보겠습니다.

17. 더 많은 것들

지금까지 앞으로 여러분이 사용하게 될 파이썬의 여러 주요한 기능들에 대해 다뤄 보았습니다. 이 챕터에서는,여러분이 앞으로 파이썬을 사용하면서 추가로 알아두면 좋을 몇 가지를 다뤄 보겠습니다.

17.1. 튜플 넘기기

함수의 실행 결과로 두 개 이상의 값을 반환하고 싶을 때가 있지 않았나요? 파이썬에서는 할 수 있습니다.단순히 튜플을 넘겨 주기만 하면 됩니다.

>>> def get_error_details():...     return (2, 'details')...>>> errnum, errstr = get_error_details()>>> errnum2>>> errstr'details'

위와 같이 <code>a, b = <계산식></code> 과 같이 해 주면 계산식의 결과로 넘어온 튜플이 자동으로 두 값에 알맞게들어가게 됩니다.

이것을 이용하여 두 변수의 값을 바꾸어야 할 때 다음과 같이 할 수 있습니다:

>>> a = 5; b = 8>>> a, b(5, 8)>>> a, b = b, a>>> a, b(8, 5)

17.2. 특별한 메소드들

클래스에는 <code>__init__</code> 이나 <code>__del__</code> 메소드처럼 특별한 일을 하는 몇 개의 메소드들이 있습니다.

이러한 특별한 메소드들을 이용하면 파이썬에 내장된 특정 형식들을 흉내낼 수 있습니다. 예를 들어,여러분이 새로 만든 클래스에서 <code>x[key]</code> 와 같은 형태의 인덱싱 연산을 가능하게 하고 싶을 경우(리스트나 튜플처럼), 클래스에 <code>__getitem__()</code> 메소드를 구현해 두기만 하면 됩니다. 사실 이것은파이썬에 내장된 <code>list</code> 클래스에도 똑같은 방식으로 구현되어 있습니다!

아래에 몇 개의 유용한 특별한 메소드의 목록이 있습니다. 모든 특별한 메소드들에 대해 알고 싶으시면,공식 설명서를 읽으세요.

<code>__init__(self, ...)</code>

이 메소드는 객체가 새로 생성될 때 호출됩니다.

<code>__del__(self)</code>

이 메소드는 객체가 메모리에서 제거되기 직전에 호출됩니다 (그러나 언제 호출될 지 분명하지 않으므로가능하면 사용을 피하세요).

<code>__str__(self)</code>

<code>print</code> 문이라던가 <code>str()</code> 등이 사용될 경우 호출됩니다.

<code>__lt__(self, other)</code>

작음 연산자 (<) 가 사용될 경우 호출됩니다. 이와 비슷하게, 모든 연산자(+, -, 등등)에 해당하는특별한 메소드들이 하나씩 따로 존재합니다.

<code>__getitem__(self, key)</code>

<code>x[key]</code> 형태의 인덱싱 연산이 사용될 경우 호출됩니다.

<code>__len__(self)</code>

열거형 객체의 길이를 얻어오기 위한 내장 함수 <code>len()</code> 이 사용될 경우 호출됩니다.

17.3. 한 줄짜리 블록

지금까지 여러분이 작성한 프로그램에서는 각 블록이 서로 다른 들여쓰기 단계에 따라 구분되어 있었을것입니다. 그렇지만 한 가지 예외가 있습니다. 만약 블록에 딱 한 개의 명령만 존재하는 경우, 특히조건문이나 반복문을 사용할 때, 그 줄에 해당 명령을 이어서 지정해 줄 수 있습니다. 아래 예제를 보면이것을 좀 더 명확하게 이해할 수 있을 것입니다:

>>> flag = True>>> if flag: print 'Yes'...Yes

위와 같이, 한 줄짜리 블록은 새로 블록을 생성하지 않고 그 줄 뒤에 이어서 사용됩니다. 이러한 방식을사용하면 여러분의 프로그램을 몇 줄 줄여줄 수는 있겠지만, 디버깅을 할 때와 같은 경우를 제외하고는가능하면 이 방법을 사용하지 않기를 강력히 권합니다. 그 주된 이유는 적절한 들여쓰기를 사용할 경우,그 아래에 추가 명령을 삽입하기가 좀 더 쉬워지기 때문입니다.

17.4. lambda 식

<code>lambda</code> 문은 새 함수 객체를 만들 때 사용됩니다. 기본적으로, <code>lambda</code> 문은 한 줄짜리 수식을매개 변수로 넘겨 받게 되어 있는데 이것이 곧 함수의 본체가 되고, 이렇게 생성된 함수를 호출하면지정해준 수식을 통해 계산된 결과값이 반환됩니다.

예제 (<code>more_lambda.py</code> 로 저장하세요):

<code class="python language-python">points = [ { 'x' : 2, 'y' : 3 },           { 'x' : 4, 'y' : 1 } ]points.sort(key=lambda i : i['y'])print points</code>

실행 결과:

$ python more_lambda.py[{'y': 1, 'x': 4}, {'y': 3, 'x': 2}]
동작 원리

<code>list</code> 의 <code>sort</code> 메소드는 <code>key</code> 매개 변수를 받는데, 이것은 어떻게 리스트를 정렬할 것인지를 결정해주는것입니다 (주로 오름차순으로 할 지 내림차순으로 할 지 정도만 지정해 주지만요). 위 예제에서는 특별히우리가 정의한 방식대로 정렬을 하려고 하며, 따라서 이 일을 해 주는 함수를 하나 만들어 주어야 합니다.이 때 <code>def</code> 블록을 사용하여 함수를 생성하지 않고 lambda 식을 사용하여 새 함수를 그 자리에서 바로만들어 주었습니다.

17.5. 리스트 축약(Comprehension)

리스트 축약은 이미 존재하는 하나의 리스트를 기반으로 또 다른 리스트를 생성할 때 사용됩니다. 예를들어 숫자로 이루어진 리스트가 하나 있을 때 이 리스트의 모든 항목에 대해 각 항목이 2 보다 클 경우에만2 를 곱해준 리스트를 생성하고 싶다고 해 봅시다. 리스트 축약은 이러한 상황에 적절하게 사용될 수있습니다.

예제 (<code>more_list_comprehension.py</code> 로 저장하세요):

<code class="python language-python">listone = [2, 3, 4]listtwo = [2*i for i in listone if i > 2]print listtwo</code>

실행 결과:

$ python more_list_comprehension.py[6, 8]
동작 원리

위 예제에서는 기존 리스트에서 특정 조건 (<code>if i > 2</code>)을 만족하는 항목에 대해 2 를 곱해주는 조작을 가한(<code>2*i</code>) 새 리스트를 생성하였습니다. 이 때 기존 리스트는 변경되지 않습니다.

리스트 축약을 사용하면 반복문을 사용하여 리스트에 있는 각각의 항목에 접근하고 새 리스트를 생성하는등의 많은 양의 코드를 한번에 줄여서 쓸 수 있는 장점이 있습니다.

17.6. 함수 인자를 튜플이나 사전 형태로 넘겨받기

<code>*</code> 혹은 <code>**</code> 을 이용하면 함수의 매개 변수를 튜플이나 사전 형태로 넘겨받을 수도 있습니다.이 방법은 함수의 인자의 개수가 정해지지 않은 함수를 정의하고 싶을 때 유용하게 사용됩니다.

>>> def powersum(power, *args):...     '''Return the sum of each argument raised to the specified power.'''...     total = 0...     for i in args:...         total += pow(i, power)...     return total...>>> powersum(2, 3, 4)25>>> powersum(2, 10)100

변수 <code>args</code> 앞에 <code>*</code> 을 붙여 주면, 함수로 넘겨진 모든 다른 인수들이 <code>args</code> 라는 튜플에 담겨진 형태로함수에 넘어오게 됩니다. <code>*</code> 대신 <code>**</code> 을 앞에 붙여 주면, 이번에는 인수들이 사전의 형태, 즉 키/값 쌍의형태로 변환되어 넘어오게 됩니다.

17.7. assert 문

<code>assert</code> 문은 어떤 조건이 참인지 확실하게 짚고 넘어가고 싶을 때 사용됩니다. 예를 들어, 리스트에적어도 한 개의 항목이 담겨 있어야 하는 상황에서 그렇지 않은 경우 오류 메시지를 발생시키고 싶을경우와 같을 때 <code>assert</code> 문을 유용하게 사용할 수 있습니다. 조건이 참이 아닌 경우, <code>AssertionError</code>가 발생됩니다.

>>> mylist = ['item']>>> assert len(mylist) >= 1>>> mylist.pop()'item'>>> assert len(mylist) >= 1Traceback (most recent call last):  File "<stdin>", line 1, in <module>AssertionError</module></stdin>

따라서 <code>assert</code> 문은 신중하게 사용하여야 합니다. 보통 이보다는 예외 처리 구문을 작성하여,즉 문제가 무엇인지 확인하여 사용자에게 오류 메시지를 보여주고 프로그램을 종료하게 하는 과정을거치도록 하는 것이 낫습니다.

17.8. 데코레이터

데코레이터는 해당 항목을 감싸 주는 함수의 축약문입니다. 이것은 같은 코드를 "감싸는" 일을 계속반복하여 해야 할 경우 유용하게 사용됩니다. 아래 예제에서는 어떤 함수가 실행되는 중에 오류가발생하면 최대 5 번 까지 일정 간격을 두고 재실행하게 하는 <code>retry</code> 데코레이터를 만들어 주었습니다.또 데코레이터는 여러분이 원격 컴퓨터에 네트워크를 통해 접속을 시도하거나 하는 상황에도 유용하게사용됩니다.

<code class="python language-python">from time import sleepfrom functools import wrapsimport logginglogging.basicConfig()log = logging.getLogger("retry")def retry(f):    @wraps(f)    def wrapped_f(*args, **kwargs):        MAX_ATTEMPTS = 5        for attempt in range(1, MAX_ATTEMPTS + 1):            try:                return f(*args, **kwargs)            except:                log.exception("Attempt %s/%s failed : %s",                              attempt,                              MAX_ATTEMPTS,                              (args, kwargs))                sleep(10 * attempt)        log.critical("All %s attempts failed : %s",                     MAX_ATTEMPTS,                     (args, kwargs))    return wrapped_fcounter = 0@retrydef save_to_database(arg):    print "Write to a database or make a network call or etc."    print "This will be automatically retried if exception is thrown."    global counter    counter += 1    # This will throw an exception in the first call    # And will work fine in the second call (i.e. a retry)    if counter < 2:        raise ValueError(arg)if __name__ == '__main__':    save_to_database("Some bad value")</code>

실행 결과:

$ python more_decorator.pyWrite to a database or make a network call or etc.This will be automatically retried if exception is thrown.ERROR:retry:Attempt 1/5 failed : (('Some bad value',), {})Traceback (most recent call last):  File "more_decorator.py", line 14, in wrapped_f    return f(*args, **kwargs)  File "more_decorator.py", line 39, in save_to_database    raise ValueError(arg)ValueError: Some bad valueWrite to a database or make a network call or etc.This will be automatically retried if exception is thrown.
동작 원리

다음을 참고하세요:

17.10. 요약

이 챕터에서는 좀 더 다양한 파이썬의 여러 기능에 대해 살펴보았습니다. 아직 우리가 파이썬의 모든기능을 다 짚고 넘어온 것은 아니지만, 여러분이 실전에서 사용할 수 있을 만큼은 충분히 다루었습니다.이제 앞으로 무엇을 더 배워야 할 지에 대해서는 앞으로 여러분이 어떤 프로그램을 만들게 될 지에 따라여러분이 직접 결정하면 될 것입니다.

다음으로 파이썬에 대해 좀 더 자세히 알아볼 수 있는 방법에 대해 알아보겠습니다.

지금까지 이 책의 내용을 잘 따라오신 분들이라면 아마 많은 파이썬 프로그램을 작성해 보셨을 것이고,아마 파이썬에 대한 느낌도 좀 더 편안할 것이며 파이썬에 좀 더 친숙해 졌을 것입니다. 또 이 책의예제 프로그램 이외에도 이것저것 다른 것들도 시도해 보신 분들도 계시겠죠. 혹시 아니라면,지금이라도 그렇게 하셔야 합니다. 자, 이제 남은 질문은 하나입니다. 앞으로 무엇을 해 보면 좋을까요?

아래 문제를 한번 해결해 보시기 바랍니다:

명령줄에서 실행되는 주소록 프로그램을 만들어 보세요. 여기에는 친구, 가족, 동료 등을 카테고리별로나눠 저장해 두며, 또 항목을 검색하거나 새로 추가 혹은 삭제할 수 있고 각 사람의 메일 주소, 전화번호등의 정보를 담을 수 있도록 하세요. 또한 이러한 정보들을 저장해 두었다가 언제든 불러와 사용할 수있게 하세요.

지금까지 살펴본 다양한 내용들을 다시 되짚어 보면 위 문제 정도는 쉽게 해결할 수 있을 것입니다.힌트를 원하신다면 아래 꼬리말을 참조하세요 [2].

위 문제를 성공적으로 해결하셨다면, 어러분은 이제 파이썬 프로그래라고 불러도 손색이 없을 것입니다.이제 저에게 이런 좋은 책을 써서 고맙다는 메일 한 통을 보내 주세요;-). 또, 이 책의 지속적인 발전을 위해 책을 구입하시는 것도 고려해 주세요.

위 문제가 너무 쉬웠다면, 아래 문제도 해결해 보시기 바랍니다:

replace 명령을 직접 구현해 보세요. 이 명령은주어진 파일들 내부의 특정 문자열을 다른 문자열로 전부 치환하는 데 사용됩니다.

여러분의 의향에 따라 구현은 단순히 문자열을 치환해 주는 식으로 구현될 수도 있고 패턴 검색 (정규표현식)을 통해 좀 더 유연하게 구현될 수도 있습니다.

17.11. 더 많은 과제

위 문제들이 너무 쉬웠다면, 다음 사이트에 주어진 과제들을 프로그램으로 구현해 보시기 바랍니다:https://github.com/thekarangoel/Projects#numbers(또는 Martyr2의 Mega Project List)

파이썬 중급 과제 목록도 확인해 보시기 바랍니다.

17.12. 예제 코드 읽기

프로그래밍 언어를 배우는 가장 좋은 방법은 코드를 직접 많이 써보고 또 많이 읽는 것입니다:

  • Python Cookbook 은 파이썬을 이용하여 어떤문제를 해결할 때 유용한 해결 방법과 팁을 정리해 놓은 굉장히 좋은 사이트입니다. 파이썬 사용자라면반드시 한번쯤 읽어 볼 필요가 있습니다.

  • 금주의 파이썬 모듈 도 또한 한번쯤 읽어 봐야 할,또 다른 매우 잘 쓰여진 표준 라이브러리 가이드입니다.

17.17. 커뮤니티

파이썬을 사용하다가 도저히 해결하지 못할 문제에 직면한 경우,python-tutor list (영문) 혹은파이썬 마을(한글) 에 질문하시면 좋습니다.

질문하기 전에 먼저 직접 문제를 해결하려고 노력해 보신 후에 질문하시기 바라며, 다음을 읽어 보시기 바랍니다:좋은 질문을 하는 방법(영문)

17.18. 새로운 소식

파이썬 세계에서 벌어지고 있는 최신 정보들을 접하고 싶으시면공식 Python Planet 사이트 (영문) 을 확인하세요.

17.19. 라이브러리 설치하기

파이썬 패키지 목록 (Python Package Index)에 여러분의 프로그램에서사용할 수 있는 수많은 오픈 소스 라이브러리가 존재합니다.

이 라이브러리들을 쉽게 설치하고 사용하기 위해서, pip를 사용할 수 있습니다.

17.20. 홈페이지 제작

플라스크(Flask)를 이용하여 홈페이지를 만들 수 있습니다. 다음을 읽어 보세요:

17.21. GUI 프로그램 만들기

파이썬 바인딩을 제공하는 여러 GUI(Graphical User Interface) 라이브러리를 사용하여 GUI 프로그램을제작할 수 있습니다. 바인딩이란 C, C++ 혹은 다른 언어로 제작된 라이브러리를 파이썬에서 불러와사용할 수 있도록 하는 일종의 연결 모듈을 말합니다.

다음은 파이썬에서 사용할 수 있는 GUI 라이브러리 목록입니다:

Kivy

http://kivy.org

PyGTK

이것은 GNOME을 제작할 때 사용된 GTK+ 의 파이썬 바인딩입니다. GTK+은 처음에는 사용하기 불편할 수있지만 한번 익숙해지면 GUI 프로그램을 빠르게 제작할 수 있게 됩니다. 이 때 Glade 라는 디자인 도구를많이 사용합니다. GTK+ 를 사용하여 자유/독점 소프트웨어를 모두 작성할 수 있습니다. PyGTK를 사용하시려면PyGTK 튜토리얼을 읽어 보세요.

PyQt

이것은 KDE을 제작할 때 사용된 Qt 의 파이썬 바인딩입니다. Qt는 Qt Designer라는 디자인 도구와 방대한문서 덕택에 굉장히 사용이 쉽고 강력한 도구입니다. PyQt는 오픈 소스 (GPL 하에서) 소프트웨어를작성하려고 할 때에 무료로 사용할 수 있습니다만, 독점 소프트웨어를 작성하려고 할 때에는 사용권을구입하여야 합니다. 또 Qt 4.5 부터는 GPL이 아닌 소프트웨어 또한 작성할 수 있습니다. PyQt를 사용하시려면PySide 를 읽어 보세요.

wxPython

이것은 wxWidgets의 파이썬 바인딩입니다. wxPython은 조금 어렵기 때문에 익숙해 지기 까지 조금 시간이필요할 수 있습니다. 그러나, wxPython으로 작성된 프로그램은 GNU/Linux, Windows, Mac 등 여러 플랫폼을지원하며 심지어 임베디드(embedded) 플랫폼에서도 사용이 가능합니다. 또한SPE (Stani’s Python Editor)wxGlade와 같은 IDE 혹은 GUI 디자인 도구들을 사용할 수 있습니다. wxPython을 이용하여 독점소프트웨어 또한 자유롭게 작성이 가능합니다. wxPython을 사용하시려면wxPython 튜토리얼을 읽어 보세요.

17.22. 그 외의 GUI 저작 도구들

아직까지는 파이썬을 위한 표준 GUI 저작 도구같은 것이 없으므로, 위 목록에서 여러분의 상황에 맞는도구를 하나 골라 사용하시는 것을 추천합니다. 아마 첫 번째 고려해야 할 점은 여러분이 선택한 GUI 저작도구를 구입할 지 여부일 것이고, 두 번째 고려해야 할 점은 여러분의 프로그램이 윈도우 환경이나 맥,리눅스 중 하나에서만 동작해도 되는지 아니면 모든 환경에서 잘 동작해야 하는지를 결정해야 할 것입니다.이 때 여러분이 리눅스 환경을 선택했다면 여러분이 KDE를 사용하는지 GNOME을 사용하는지도 고려 대상이될 것입니다.

이에 대한 좀 더 상세하고 포괄적인 분석을 원하신다면,The Python Papers, Volume 3, Issue 1의 26 페이지를 참조하시기 바랍니다.

17.23. 다양한 파이썬 구현들

프로그래밍 언어는 크게 두 부분으로 나뉘는데, 그 하나는 언어이고 또 하나는 소프트웨어입니다. 여기서언어란 어떻게 프로그램을 작성하는지 정의해 둔 것을 말하며, 소프트웨어란 이렇게 작성된 프로그램을실제로 실행시키는 그 무엇 을 말합니다.

지금까지 우리는 여러분이 작성한 프로그램을 실행시키기 위해 CPython 이라는 소프트웨어를 사용해왔습니다. 이것은 C 언어로 작성되었기 때문에 CPython이라고 불리우며, 가장 기본적인 파이썬 인터프리터입니다.

그렇지만, 우리가 작성한 파이썬 프로그램을 실행할 수 있는 다양한 다른 소프트웨어들도 존재합니다:

Jython

이것은 자바 플랫폼 상에서 동작하는 파이썬 구현입니다. 이를 이용하면 파이썬 언어 안에서 자바라이브러리 및 클래스를 불러와 사용할 수 있으며, 그 반대도 가능합니다.

IronPython

이것은 .NET 플랫폼 상에서 동작하는 파이썬 구현입니다. 이를 이용하면 파이썬 언어 안에서 .NET라이브러리 및 클래스를 불러와 사용할 수 있으며, 그 반대도 가능합니다.

PyPy

PyPy는 파이썬으로 작성된 파이썬 구현입니다! 이것은 C, Java, C# 등과 같은 정적인 언어를 배제한동적 언어로 구현된 인터프리터가 어디까지 빨라질 수 있으며 또 얼마나 쉽게 구현할 수 있는지확인해보려는 연구 프로젝트입니다.

이외에도 CLPython (Common Lisp 으로 작성된 파이썬 구현)이 있습니다. 또 자바 스크립트 인터프리터 상에서 동작하는 Brython 이 있는데,이를 이용하면 자바 스크립트 대신 파이썬을 이용하여 웹 브라우저 상에서 동작하는 프로그램 ("Ajax")을제작할 수도 있습니다.

이러한 각각의 파이썬 구현은 각 분야에서 유용하게 사용됩니다.

17.24. (고급 프로그래머를 위한) 함수형 프로그래밍

여러분이 큰 프로그램을 제작해야 할 경우, 앞서 객체 지향 프로그래밍 챕터에서 배웠던 클래스기반 접근 대신 함수형 접근 방법에 대해서도 한번쯤 배워 볼 필요가 있습니다:

17.25. 요약

이제 여러분은 이 책의 마지막에 다다랐습니다. 그러나, 이것은 또 다른 시작일 뿐입니다! 여러분은이제 열의에 차 있는 한 명의 파이썬 사용자일 것이며, 파이썬을 이용해 더 많은 문제들을 해결할 준비가되어 있을 것입니다. 이전에는 생각하지 못했던 여러 자동화 스크립트를 작성해 보시거나, 직접 게임을 만들어본다거나 여러 가지 시도를 해 보시기 바랍니다. 자, 이제 시작해 봅시다!

18. 부록: FLOSS

Note
이 섹션은 2003년에 작성되었습니다. 따라서 몇몇 사항은 최신의 내용이 아닐 수 있습니다.

"자유/오픈 소스 소프트웨어(Free/Libre and Open Source Software)", 줄여서 FLOSS란 공동체의 공유 정신, 특히 지식의 공유 정신에 의해 개발되는 소프트웨어를 의미합니다.FLOSS는 자유롭게 사용할 수 있고 수정할 수 있으며 재배포할 수 있습니다.

여러분이 이 책을 읽으셨다면 FLOSS에 이미 익숙할 것입니다. 왜냐면 지금까지 여러분이 사용해 왔던파이썬이 바로 오픈 소스 소프트웨어이기 때문입니다!

아래 공동체에 의해 개발되는 몇가지 FLOSS의 예가 있습니다:

리눅스(Linux)

이것은 GNU/Linux 운영 체제에서 사용되는 FLOSS 운영 체제 커널입니다. 리눅스, 즉 커널은 학생 시절의리누스 토발즈 (Linus Torvalds)에 의해 시작되었습니다. 안드로이드도 리눅스를 기반으로 합니다.또 현재 여러분이 접속하여 사용하는 거의 모든 웹 사이트들도 리눅스를 기반으로 동작하고 있습니다.

우분투(Ubuntu)

캐노니컬(Canonical) 사의 후원을 받는 우분투는 커뮤니티에 의해 개발되는 GNU/Linux 배포판이며,현재 가장 널리 사용되고 있습니다. 우분투는 여러 FLOSS를 누구나 쉽게 설치하여 사용할 수 있도록 해줍니다. 가장 좋은 점은 CD를 넣고 컴퓨터를 재부팅하는 것만으로 GNU/Linux를 바로 사용해 볼수 있다는 점입니다! 즉, 여러분의 컴퓨터에 설치하기 전에 완전한 새 OS를 사용해 볼 수 있습니다.그러나 우분투는 완전한 자유 소프트웨어는 아닙니다. 우분투에는 몇가지 독점 드라이버, 펌웨어,소프트웨어 등이 함께 포함되어 있습니다.

리브레오피스(LibreOffice)

커뮤니티에 의해 개발되는 리브레오피스는 문서 편집기, 프리젠테이션, 스프레드시트, 그리기 도구등 여러 기능을 갖춘 뛰어난 오피스 프로그램입니다. 리브레오피스를 이용하면 MS 워드, MS 파워포인트 등의파일들 또한 쉽게 열고 편집할 수 있습니다. 리브레오피스는 모든 플랫폼 상에서 동작하며 완전히 무료이고,완전한 자유/오픈 소스 소프트웨어입니다.

모질라 파이어폭스(Mozilla Firefox)

이것은 최고의 웹 브라우저입니다. 모질라 파이어폭스는 무시무시하게 빠르며, 감각적이고인상적인 기능으로 인해 많은 찬사를 받아 왔습니다. 확장 기능을 통해 여러 플러그인을 사용할 수있습니다.

모노(Mono)

모노는 마이크로소프트(Microsoft) .NET 플랫폼의 오픈 소스 구현입니다. 이를 이용하면 .NET 소프트웨어를GNU/Linux, 윈도우, FreeBSD, Mac OS 및 다른 플랫폼들에서 개발하고 구동할 수 있습니다.

아파치 웹 서버(Apache web server)

이것은 지구상에서 가장 많이 사용되는 오픈 소스 웹 서버입니다! 현존하는 모든 웹사이트의 절반 이상이아파치 웹 서버를 기반으로 동작하고 있습니다. 아파치는 마이크로소프트 IIS를 포함한 모든 경쟁자들이구동하는 홈페이지 수를 모두 합친 수보다 많은 홈페이지를 구동하고 있습니다.

VLC 플레이어(VLC Player)

이것은 DivX, Mp3, Ogg, VCD, DVD 등등 수많은 형식을 지원하는 동영상 재생기입니다. 누가 오픈 소스소프트웨어가 별로 안 좋다고 하던가요? ;-)

위 목록은 여러분에게 FLOSS에 대해 간략히 소개해드리기 위한 것일 뿐, Perl 이나 PHP 와 같은언어들, 웹 사이트 관리 시스템 드루팔(Drupal), 데이터베이스 서버 PostgreSQL, 레이싱 게임 TORCS,KDevelop IDE, 동영상 재생기 Xine, 편집기 VIM 과 Quanta+, 음악 재생기 밴시(Banshee),사진 및 그림 편집기 GIMP 등등 셀 수 없이 많은 뛰어난 FLOSS들이 존재합니다.

FLOSS의 최신 소식이 궁금하시다면 다음 웹 사이트들을 확인해 보세요:

FLOSS에 대해 좀 더 알고 싶으시다면 다음 웹 사이트들을 확인해 보세요:

이제 자유롭고 언제나 열려 있는 방대한 FLOSS의 세계로 떠나 보세요!

19. 부록: 끝맺음

이 책을 제작하는데 사용된 거의 모든 소프트웨어는 FLOSS 입니다.

19.1. 책의 탄생

이 책의 초판은 Red Hat 리눅스 9.0 을 기반으로 한 시스템에서 발행되었으며, 6 판부터는Fedora Core 3 리눅스를 기반으로 한 시스템을 사용하여 발행되었습니다.

또 서문의 History Lesson 에서 언급한 것과 같이, 이 책은 KWord를 사용하여처음으로 작성되었습니다.

19.2. 책의 십대 시절

이후에는 Kate를 사용하여 DocBook XML으로 문서를 편집하기 시작했지만 이것은 조금 복잡하고 어려워서문서 포맷팅에 필요한 여러 뛰어난 기능이 제공되는 OpenOffice를 사용해 보았지만, 이것은 PDF에 비해HTML로는 문서를 예쁘게 잘 만들어 주지 못했습니다.

그러던 중 XEmacs라는 좋은 툴을 발견하게 되었고, 그래서 저는 DocBook XML을 사용하여 처음부터다시 책을 작성하기로 했습니다.

책의 6판부터는 Quanta+ 편집기를 이용하기 시작했고, 또 이 때는 Fedora Core 3 리눅스와 함께 제공되는기본 XSL 스타일시트를 사용하였습니다. 그렇지만 이 때는 HTML 페이지에 여러 색과 스타일을 주기 위해CSS 문서들을 작성해 주어야 했습니다. 또한 예제 프로그램의 문법 강조 기능을 위해 파이썬으로 문법분석기를 직접 작성하여야 했습니다.

책의 7판에 이르러서는 MediaWiki를 사용해 보았습니다. 이를 통해 문서를온라인으로 편집할 수 있고 위키 웹 사이트를 통해 독자가 직접 내용을 읽고/편집하고/토론할 수 있게할 수 있었지만, 저는 책을 작성하기 보다 스팸과 싸우는 데 시간을 더 많이 할애해야 했습니다.

책의 8판에서는 Vim,Pandoc, 그리고 Mac OS X를 이용했습니다.

19.3. 책의 현재

책의 9판에 이르러, 저는 Emacs 24.3,tomorrow theme,tomorrow theme,Fira Monofont, adoc-mode를 이용하여AsciiDoc format으로 책을 재작성하였습니다.

프로그래밍,파이썬,Python,framework