'파이썬'에 해당되는 글 9건

  1. 2021.09.15 파이참(pycharm) 단축키 정리
  2. 2018.04.09 정규표현식(Regular Expression)
  3. 2018.04.03 Python 문법
posted by 귀염둥이채원 2021. 9. 15. 09:47

파이참(pycharm) 단축키 정보입니다.

PyCharm_단축키.pdf
0.21MB

macOS

 

윈도우

Action

Shift + Ctrl + A : Search for Action (IDE의 기능 검색 : Shift double type 시 전체 기능 검색으로 자동 이동)

- action에서 " Locate Duplicate" 입력 하면 중복코드 검색 가능

Code assistance

Ctrl + Alt + L : Code format ( 코드 자동 정렬 )

Ctrl + Alt + Shift + L : Whole file Code format

Ctrl + Alt + O : Import 정리

Ctrl + P : 인자값 즉시 보기

Ctrl + Q : Quick popups ( doc 주석 바로 보기 )

Ctrl + Shift + I : 코드 구현부 즉시 보기

F2 : next highlighted error

= Alt + Enter : 수정 내용 추천

= Ctrl + F1으로 에러 내용 확인

Editing

Alt + Shift + Up/Down : 현재 라인 위아래 이동

Ctrl+ Shift + Up/Down : 현재 라인의 메소드, IF 등 블럭 단위로 위아래 이동

Alt + Enter : Context action (파이썬 추천 코드 형식으로 리팩토링 제안)

Ctrl + Space : Basic code completion (the name of any class,method or variable)

- dic 변수 선언하고 가져다 쓸때, dic_name[ __ ] 상태에서 Ctrl + Space 누르면 Key 값 추천 됨 (caret은 _ 부근에 )

 

- Class 멤버 번수 init에 넣고 메소드에서 사용 할때 self. __ 에서 자동 완성 기능 됨

Ctrl + Shift + Space : Smart code completion (filters the list of methodsand variables by expected type)

Ctrl + Shift + Enter: Complete statement

Ctrl + P : 함수호출시 인수 정보 확인 (within method call arguments)

Ctrl + Q : 코드에 대한 문서창 팝업

Shift + F1 : 코드에 대한 문서 인터넷 브라우저로 팝업

Ctrl + mouse : 코드를 링크처럼 타고 들어감

Ctrl + F1 : Show descriptions of error or warning at caret

Alt + Insert : 코드 생성 (Getters, Setters, Constructors,hashCode/equals, toString)

Ctrl + O : 메서드 오버라이드 구현

Ctrl + I : 인터페이스 메서드 구현

Ctrl + Alt + T : 다음으로 코드 감싸기… (if..else, try..catch, for,synchronized, etc.)

Ctrl + Shift + Delete : Unwrap try

Ctrl + / : 줄 단위 주석 토글

Ctrl + Shift + / : 블럭 단위 주석 토글

Ctrl + W : 가장 안쪽의 괄호부터 선택(점점 확장 된다.)

Ctrl + Shift + W : Decrease current selection to previous state

Alt + Q : Context info

Alt + Enter : Show intention actions and quick-fixes

Ctrl + Alt + L : 파일 단위 재정렬 (이클립스의 ctrl + shift + f)

Ctrl + Alt + O : import 문 최적화

Ctrl + Alt + I : 줄단위 재정렬

Tab / Shift + Tab : 들여쓰기/내어쓰기

Ctrl + X or Shift + Delete : 잘라내기 (블럭 선택이 안되어 있으면 라인을 잘라냄)

Ctrl + C or Ctrl + Insert : 복사하기(블럭 선택이 안되어 있으면 라인을 복사함)

Ctrl + V or Shift + Insert : 붙여넣기

Ctrl + Shift + V : 복사하기 (목록에서 선택하여)

Ctrl + D : 선택된 블럭을 복제

Ctrl + Y : 캐럿을 있는 곳의 라인 삭제

Ctrl + Shift + J : 스마트하게 코드를 한 줄로 합친다.

Ctrl + Enter : 스마트하게 코드를 여러줄로 나눈다.

Shift + Enter : 커서가 어디에 있건 다음 라인을 생성하고 첫줄로 이동

Ctrl + Shift + U : 커서가 있는 곳이나 블럭이 있는 곳을 대문자 및 소문자로 치화

Ctrl + Shift + ] / [ : 가장 가까운 괄호 시작/종료로 이동

Ctrl + Delete : 단어 삭제 (커서 시작부터)

Ctrl + Backspace : Delete to word start

Ctrl + '+/-' : Expand/collapse code block

Ctrl + Shift + '+/-' : Expand/collapse ALL code block

Ctrl + F4 : Close active editor tab

 

Alt + J : Multiple select ( HTML 태크 속성 같은 것을 선택 </td> )

Alt + Shift + J : 위에 역

Postfix completion

if movies_dict.get('year') is not None: ### movies_dict.get('year').ifnn

my_car = Car() print("The car has driven ${my ____ kilometers")

Navigation

Ctrl + B or Ctrl + Click : Go to declaration

Alt + F7 / Ctrl + F7 : Find usages , Find usages in file

Ctrl + F12 : 파이선 파일의 클라스 구조 요약해서 보여 주고 검색 가능하여, 해당 코드로 바로 이동 가능

Alt + 7 : 파이선 파일의 클라스 구조 보여 줌

Ctrl + E : Recent files popup

Ctrl + Shift + E : 최근 방문한 코드 파일 popup

Shift press twice : Search Everywhere

Ctrl + N : Go to class

Ctrl + Shift + N : Go to file

Ctrl + Alt + Shift + N : Go to symbol

Alt + Right/Left : Go to next/previous editor tab

F12 : Go back to previous tool window

Esc : Go to editor (from tool window)

Shift + Esc : Hide active or last active window

Ctrl + Shift + F4 : Close active run/messages/find/... tab

Ctrl + G : Go to line

Ctrl + Alt + Left/Right : Navigate back/forward

Ctrl + Shift + Backspace : Navigate to last edit location

Alt + F1 : Select current file or symbol in any view

Ctrl + Alt + B : Go to implementation(s)

Ctrl + Shift + I : Open quick definition lookup

Ctrl + Shift + B : Go to type declaration

Ctrl + U : Go to super-method/super-class

Alt + Up/Down : Go to previous/next method

Ctrl + ] / [ : Move to code block end/start

Ctrl + F12 File : structure popup

Ctrl + H Type : hierarchy

Ctrl + Shift + H : Method hierarchy

Ctrl + Alt + H : Call hierarchy

F2 / Shift + F2 : Next/previous highlighted error

F4 / Ctrl + Enter : Edit source / View source

Alt + Home : Show navigation bar

F11 : Toggle bookmark

Ctrl + F11 : Toggle bookmark with mnemonic

Ctrl + #[0-9] : Go to numbered bookmark

Shift + F11 : Show bookmarks

Refactoring

Shift + F6 : Rename

- Alt + 3 : 창이 뜨면 refactoring 대상 삭제 가능

Ctrl + Alt + V: Extract variable

- 반복 변수 (arr[i+1] 에서 'i+1' 도 해당) 추출 하여, 가독성 높일수 있음

Ctrl + Alt + M : Extract Method

- a[i], a[i + 1] = a[i + 1], a[i] 의 구문이 반복적으로 사용시, 자동으로 추출 및 메소드 생성 가능

F5 : Copy

F6 : Move

Alt + Delete : Safe Delete

Ctrl + F6 : Change Signature

Ctrl + Alt + N : Inline

Ctrl + Alt + F : Extract Field

Ctrl + Alt + C: Extract Constant

Ctrl + Alt + P : Extract Parameter

Debugging

Shift + F9 : 디버깅 시작

Ctrl + F8 : Toggle breakpoint

Ctrl + Alt + F8 : 디버깅 중 인자값 예상 가능

def extract_number(s): return int(s.split()[0]) # s.split()[0] 값 예상 가능 / s.split()[0] 셀렉해줘야 나옴

F8 : Step over : 중단점 이후에 코드를 한줄씩 실행시키지만 함수가 있어도 실행 후 다음으로 넘어갑니다.

F7 : Step into : 중단점 이후에 코드를 한줄씩 실행시키지만 함수 내부로 들어갑니다.

Shift + F7 : Smart step into

Shift + F8 : Step out : 함수를 끝까지 실행시키고 호출시킨 곳으로 되돌아 갑니다.

Alt + F9 : Run to cursor

Alt + F8 : Evaluate expression

F9 : Resume program

Ctrl + Shift + F8 : View breakpoints

 

Double Shift Search everywhere

Ctrl + F : Find

F3 : Find next

Shift + F3 : Find previous

Ctrl + R : Replace

Ctrl + Shift + F : Find in path

Ctrl + Shift + R : Replace in path

Ctrl + Shift + S : Search structurally (Ultimate Edition only)

Ctrl + Shift + M : Replace structurally (Ultimate Edition only)

Usage Search

Alt + F7 / Ctrl + F7 : Find usages , Find usages in file

Ctrl + Shift + F7 : Highlight usages in file

Ctrl + Alt + F7 : Show usages

Compile and Run

Ctrl + F9 : Make project (compile modifed and dependent)

Ctrl + Shift + F9 : Compile selected file, package or module

Alt + Shift + F10 : Select configuration and run

Alt + Shift + F9 : Select configuration and debug

Shift + F10 : Run

Shift + F9 : Debug

Ctrl + Shift + F10 : Run context configuration from editor

VCS/Local History

Ctrl + K : Commit project to VCS

Ctrl + T : Update project from VCS

Alt + Shift + C : View recent changes

Alt + BackQuote (`) : ‘VCS’ quick popup

Live Templates

Ctrl + Alt + J : Surround with Live Template

Ctrl + J : Insert Live Template

iter : Iteration according to Java SDK 1.5 style

inst : Check object type with instanceof and downcast it

itco : Iterate elements of java.util.Collection

itit : Iterate elements of java.util.Iterator

itli : Iterate elements of java.util.List

psf : public static final

thr : throw new

General

Alt + #[0-9] : Open corresponding tool window

Ctrl + S : Save all

Ctrl + Alt + Y : Synchronize

Ctrl + Shift + F12 : Toggle maximizing editor

Alt + Shift + F : Add to Favorites

Alt + Shift + I : Inspect current file with curre?nt profile

Ctrl + BackQuote (`) : Quick switch current scheme

Ctrl + Alt + S : Open Settings dialog

Ctrl + Alt + Shift + S : Open Project Structure dialog

Ctrl + Shift + A : Find Action

Ctrl + Tab : Switch between tabs and tool window

메인메소드 생성 및 실행

- 디렉토리, 패키지, 클래스 등 생성 목록 보기

맥 : Command + n

윈도우 : Alt + Insert

- 코드 템플릿

메인 메소드 : psm

System.out.println() : sout

if Null 구문 : ifn

실행환경 실행

- 현재포커스

맥 : Command + Shift + R

윈도우, 리눅스 : Shift + Ctrl + F10

- 이전실행

맥 : Ctrl + R

윈도우 : Shift + F10

라인 수정하기

-라인 합치기(라인단위)

맥 : Command + Shift + J

윈도우 : Ctrl + Shift + J

라인 단위로 옮기기

- 구문 이동

맥 : Command + Shift + 위,아래

윈도우 : Ctrl + Shift + 위,아래

- 라인 이동

맥 : Option + Shift + 위,아래

윈도우 : Alt + Shift + 위,아래

- Element 단위로 옮기기

맥 : Option + Shift + Command+ 왼쪽,오른쪽

윈도우 : Alt + Ctrl + Shift + 왼쪽,오른쪽

포커스 에디터

- 단어별 이동

맥 : Alt + <, >

윈도우, 리눅스 : Ctrl + <, >

- 단어별 선택

맥 : Shift + Alt + <, >

윈도우, 리눅스 : Shift + Ctrl + <, >

- 라인 첫/끝 이동

맥 : Fn + <, >

윈도우 : Home, End

- 라인 전체 선택

맥 : Shift + Command + <, >

윈도우, 리눅스 : Shift + Home, End

- Page Up/Down

맥 : Fn + 위/아래

윈도우 : Page Up / Down

포커스 특수키

- 포커스 뒤로/앞으로 가기

맥 : Command + [ , ]

윈도우, 리눅스 : Ctrl + Alt + 좌,우

- 멀티 포커스

맥 : Alt + Alt + 아래

윈도우, 리눅스 : Ctrl + Ctrl + 아래

- 오류 라인 자동 포커스

맥 : F2

윈도우, 리눅스 : F2

검색 텍스트

- 현재 파일에서 검색

맥 : Command + F

윈도우 : Ctrl + F

- 현재 파일에서 교체

맥 : Command + R

윈도우 : Ctrl + R

- 전체 검색

맥 : Command + Shift + F

윈도우 : Ctrl + Shift + F

- 정규표현식으로 검색, 교체

맥, 윈도우 : Regex 체크

검색기타

- 파일 검색

맥 : Shift + Command + O

윈도우 : Shift + Ctrl + N

- 메소드 검색

맥 : Alt + Command + O

윈도우 : Shift + Ctrl + Alt + N

- Action 검색

맥 : Shift + Command + A

윈도우 : Shift + Ctrl + A

- 최근 열었던 파일 목록 보기

맥 : Command + E

윈도우 : Ctrl + E

- 최근 수정했던 파일 목록 보기

맥 : Command + Shift+ E

윈도우 : Ctrl + Shift + E

- 변수/필드의 데이터 변경 지점 찾기

변경되는 포인트 : 변수나 필드에 커서를 놓고 action 에서 "dataflow" 입력 후 "Analyze Dataflow to Here" 선택

영향주는 포인트 : 변수나 필드에 커서를 놓고 action 에서 "dataflow" 입력 후 "Analyze Dataflow from Here" 선택

- 중복된 코드 찾기

action에서 " Locate Duplicate" 입력

자동완성

- 스태틱 메소드 자동완성

맥 : control + Shift * 2

윈도우 : control + Shift * 2

- Getter/Setter/생성자 자동완성

맥 : Command + N

윈도우 : Alt + Insert

- 자동완성

맥 : control + I

윈도우 : Ctrl + I

Live Template

- Live Template 목록 보기

맥 : Command + J

윈도우, 리눅스 : Ctrl + J

- Live Template 메뉴에서 나만의 템플릿 추가 가능

리팩토링 Extract

- 변수 추출하기

맥 : Command + Option + V

윈도우, 리눅스 : Ctrl + Alt + V

- 파라미터 추출하기

맥 : Command + Option + P

윈도우, 리눅스 : Ctrl + Alt + P

- 메소드 추출하기

맥 : Command + Option + M

윈도우, 리눅스 : Ctrl + Alt + M

- 이너클래스 추출하기

맥 : F6

윈도우, 리눅스 : F6

리팩토링 기타

- 이름 일괄 변경 하기

맥 : Shift + F6

윈도우, 리눅스 : Shift + F6

- 메소드 일괄 변경하기

맥 : Shift + Command + F6

윈도우, 리눅스 : Shift + Ctrl + F6

- Import 정리하기

맥 : control + Option + O

윈도우, 리눅스 : Ctrl + Alt + O

- Import 자동 정리하기

Settings | Editor | General | Auto Import에서 Optimize imports on the fly 선택

- 코드 자동 정렬하기

맥 : Command + Option + L

윈도우, 리눅스 : Ctrl + Alt + L

디버깅

- Debug 모드로 실행하기(현재 위치의 메소드)

맥 : control + Shift + D

윈도우, 리눅스 : 없음

- Debug 모드로 실행하기(이전에 실행한 메소드)

맥 : control + D

윈도우, 리눅스 : Shift + F9

- Resume(다음 브레이크 포인트로 이동하기)

맥 : Command + Option + R

윈도우, 리눅스 : F9

- Step Over(현재 브레이크에서 다음 한줄로 이동하기)

맥 : F8

윈도우, 리눅스 : F8

- Step Into(현재 브레이크의 다음 메소드로 이동)

맥 : F7

윈도우, 리눅스 : F7

- Step Out(현재 메소드의 밖으로 이동)

맥 : Shift + F8

윈도우, 리눅스 : Shift + F8

- Evaluate Expression(브레이크된 상태에서 코드 사용하기)

맥 : Option+ F8

윈도우, 리눅스 : Alt + F8

- Watch(브레이크 이후의 코드 변경 확인하기)

맥 : 없음

윈도우, 리눅스 : 없음

Git 기본 기능 사용하기

- Git View On

맥 : Command + 9

윈도우, 리눅스 : Alt + 9

- Git Option Popup

맥 : control + V

윈도우, 리눅스 : Alt + '(Tab 위 버튼)

- Git History

맥 : control + V --> 4

윈도우, 리눅스 : Alt + '(Tab 위 버튼) --> 4

- Branch

맥 : control + V --> 7

윈도우, 리눅스 : Alt + '(Tab 위 버튼) --> 7

- Commit

맥 : Command + k

윈도우, 리눅스 : Ctrl + k

- Push

맥 : Command + Shift + k

윈도우, 리눅스 : Ctrl + Shift + k

- Pull

맥 : Command + Shift + A --> git pull

윈도우, 리눅스 : Ctrl + Shift + A --> git pull

GitHub 연동하기

- GitHub 연동하기

맥 : Command + Shift + A --> Share github

윈도우, 리눅스 : Command + Shift + A --> Share github

- GitHub Clone

메인 화면에서 Check out from Version Control 선택 후 Git 선택

클래스

- 클래스 구조 확인

맥 : command+7

윈 : Alt + 7

플러그인

- 플러그인 설치

맥 : Command + Shift + A --> Plugins(Preferences)

윈도우, 리눅스 : Command + Shift + A --> Plugins(Preferences)

- Terminal

맥 : Option+ F12

윈도우, 리눅스 : Alt + F12

'파이썬' 카테고리의 다른 글

정규표현식(Regular Expression)  (0) 2018.04.09
Python 문법  (0) 2018.04.03
Jupyter Notebook이란?  (0) 2018.04.03
iterator, generator 사용법  (0) 2018.04.03
decorator(wrapper) 사용법  (0) 2018.04.03
posted by 귀염둥이채원 2018. 4. 9. 21:26

0. 목차

  • 1.개념
  • 2.메타문자(. ^ $ * + ? { } [ ] \ | ( ))
  • 3.백슬래시와 raw string
  • 4.re 모듈 주요 함수
  • 5.컴파일 옵션
  • 6.Grouping
  • 7.Lookahead Assertion
  • 8.Greedy vs Non-Greedy

1. 개념

문자열 처리를 더 쉽고 강력하게 하기 위한 기법이다. 파이썬만이 가지고 있는 것이 아니라 대부분의 언어에서 공유하고 있는 공통 약속이라고도 할 수 있겠다. 예를 들어 회원가입 창에서 전화번호를 입력받았다고 할 때 사용자가 숫자만 써서 '01012341234'라고 했을 수도 있고 '010-1234-1234'로 했을 수도 있다. 이런 입력에서 원하는 '숫자'만 정확하게 가져오는데 정규표현식이 아주 강력한 기능을 제공한다.

직접 생각해본 패턴들을 활용하면서 공부하는게 더 효율적이다. 그래서 일단 모르더라도 아래 코드에서 '!!!!여기!!!!' 부분의 정규표현식을 바꿔가며 실습하면 좋겠다.

import re
text = 'some string'
REGEX = re.compile('!!!!여기!!!!')
result = REGEX.findall(text)
print(result)

2. 메타 문자 간단 설명

종류: . ^ $ * + ? { } [ ] \ | ( )

A. ^ : not (또는 맨 앞 문자열 특정)

  • [ ] 안에서 쓰이는 경우: 패턴 맨 앞에 붙어서 'not'을 의미한다.
  • [ ] 바깥에서 쓰이는 경우: 문자열의 맨 앞을 특정한다. 아래쪽에 re.MULTILINE 옵션에서 좀 더 자세하게 이야기하기로 한다. 맨 뒤를 특정하는 메타문자가 $다.

B. [ ] : 문자 클래스

  • [abc] : 문자열이 a, b, c 중 아무거나 하나만 포함한다면 매치된다. 'abc', 'aaa', 'bike' 같은 경우 매치되고, 'dude'는 매치 안된다.
  • [a-z] : [ ] 안에 '-' 하이픈이 들어가면 범위를 나타낸다. 이 예는 a부터 z까지의 모든 문자를 나타낸다. 즉 [abcdefghijklmnopqrstuvwxyz] 와 같은 의미다. 숫자도 통한다. [0-9] 는 모든 숫자를 나타낸다.
  • [^a-zA-Z] : not을 의미하는 '^'를 활용하여 문자가 아닌 것을 매치
  • [0-9]와 [a-zA-Z]같은 자주 쓰는 표현식은 따로 표기법이 만들어졌다.
    • \d : [0-9], 숫자와 매치
    • \D : [^0-9], 숫자가 아닌 것과 매치
    • \s : [ \t\n\r\f\v], whitespace 문자들과 매치. 맨 앞의 공백 포함
    • \S : [^ \t\n\r\f\v], 공백이 아닌 것들
    • \w : [a-zA-Z0-9], alphanumeric
    • \W : [^a-zA-Z0-9], alphanumeric이 아닌 것.

C. . : 개행문자(\n)을 제외한 모든 문자와 매칭된다.

  • re.DOTALL 옵션을 주면 개행문자도 적용 가능하다.
  • 'a.b' : 'a' + 모든 문자 중 한 개 + 'b'의 의미다. a와 b 사이에 뭐 하나는 꼭 있어야 하고 여러 개 있는건 안된다. 즉 'aab', 'acb'는 되지만, 'accb' 는 매칭 안된다. 예를 들어 다음 문자열이라면 'aab ab aaaaab acccv a.b' 결과는 ['aab', 'aab', 'a.b'] 를 리턴한다. findall 메소드는 매칭되는 문자열을 텍스트에서 모두 찾아서 리스트로 리턴한다. 텍스트에서 aaaaaab는 a와 b 사이에 한 문자만 있는게 없다. 그래서 매칭되는 문자열이 여기선 안나오는 것.
  • 'a[.]b' 'a\.b' : 말 그대로 .을 문자 그 자체로 취급하는 경우다. 바로 위 예의 텍스트를 매치시켜보면 ['a.b'] 만 리턴된다.

D. 반복 관련: *, +, {m,n}, ?

  • *
    • 바로 앞의 문자가 0번 이상 반복될 수 있다는 의미
    • 'ab*c' : ac, abc, abbbbc 모두가 매칭된다.
  • +
    • 앞의 문자가 1번 이상 반복될 수 있다는 것.
    • 0번, 즉 아예 없는거는 적용 안되는 점에서 '*'와 다르다.
    • 'ab+c' : abc, abbbbc 는 매칭되지만 ac는 안된다.
  • {m, n}
    • 바로 앞의 문자가 m 이상 n 이하 반복되는 것과 매치된다.
    • {m} : 무조건 m번 반복되어야 한다.
    • {, m}, {m, } : 순서대로 m 이하 반복되는 것(0번 포함), m 이상 반복되는 것과 매칭된다.
    • 'ab{2, 4}c : abbc, abbbc, abbbbc는 매칭. abc, ac, abbbbbc는 매칭 안된다.
  • ?
    • 바로 앞에 있는 문자가 있어도 되고 없어도 된다는 의미다. 즉 {0, 1}과 같다.
    • 'ab?c' : ac, abc 매칭. abbc, abbbc, abbbbbbc 는 매칭 안된다.
  • 어쩔 수 없는 경우가 아니라면, 그리고 표현이 가능하다면 주로 *, +, ?를 쓰는것을 추천한다. 표현도 간결하고 이해도 쉽다.

E. 다른 메타 문자들

  • $ : 문자열 끝부분을 특정해서 매칭하는 메타문자
  • \ : 백슬래시. 여러 정해진 요소들을 변수처럼 활용할 때 쓴다. 위에서 \d, \w 같은 경우가 주요 예다.
  • | : 여러 패턴을 or 로 묶는다. 이 패턴도 되고 저 패턴도 된다는 의미.
  • ( ): 그룹으로 묶을 수 있다. 아래 설명한다.
  • \A, \Z : 순서대로 ^, $와 의미가 같다. 다른 점은 re.MULTILINE 옵션이 추가되더라도 여전히 첫 번째, 마지막만 가리킨다.
  • \b : 단어 구분자다. 패턴을 r'\bcode\b' 라고 쓴다면 'code'만 딱 매칭되고 'xcode', 'supercodefighter' 이것들은 매칭 안된다. 주로 whitespace로 구분되지만 - , : . @같은 거도 구분된다. \b를 파이썬 컴파일러가 백스페이스로 인식하므로 이것을 쓸 땐 꼭 raw string으로 써야한다.
  • \B : 역시 대문자로 쓰면 반대다. 만약 r'\Bcode\B라고 썼다면 좌우에 다 써서 감쌌으므로 양쪽에 뭔가 문자나 숫자로 감싸져있는 것만 매칭된다. 'xcodex'는 매칭되고 'xcode', 'codex'는 매칭안된다. 그리고 저 패턴대로라면 findall의 결과물은 단순히 'code'다. 'xcodex'가 결과 리스트에 포함되는 것이 아니다. 전체 문자열을 다 뽑고 싶으면, 즉 'xcodex'를 뽑고 싶으면 r'\w+\Bcode\B\w+라고 패턴을 설정하면 된다.

3. backslash(\)와 raw string

  • 위의 예 중에서 \d\W같은 패턴을 봤을 것이다. 이렇게 백슬래시를 쓰는 패턴들이 있기 때문에 백슬래시 문자 자체를 찾고싶은 경우 종종 문제가 발생한다. 예를 들어 '\section'이나 '\dragon'같은 경우엔 각각 순서대로 [ \t\n\r\f\v]ection, [0-9]ragon 과 같은 패턴이 되어버린다. 내가 원하는건 그게 아닌데 말이다.
  • 그래서 백슬래시를 백슬래시 자체로 인식하기 위해 2번 써주면 되지 않을까? 생각하지만 안된다. 왜 안될까. 이번엔 파이썬 엔진이 \\\ 문자로 바꿔주기 때문이다. 그래서 결국 세 개를 써줘야 된다. re.compile('\\\section') 이라고 해줘야 텍스트 중에서 '\section'을 뽑아낼 수 있다. 이 얼마나 복잡한가.
  • 그래서 raw string이 생겼다. 문자열을 그 자체로 인식하게 해주는 파이썬 문법이다. 문자열 앞에 r을 붙여주면 된다. 그래서 위 같은 경우 re.compile(r'\\section') 이라고 쓰기만 하면 된다. raw string이면서 왜 또 2개를 적어주냐면 이건 파이썬 컴파일러에게 적용되는 것이기 때문이다. 파이썬 컴파일러가 저 두 개의 백슬래시를 하나로 만들어주지 않도록 하는 것이 raw string인 것이다. 그래서 정규표현식 엔진이 \s를 공백으로 인식하지 않게 하기 위해선 여전히 두 개를 써줘야 한다.
  • 정리: 정규표현식에서 백슬래시 문제는 파이썬 엔진과 정규표현식 엔진이 동시에 작용하기 때문이다. 그래서 raw string을 활용해서 파이썬 엔진의 작용을 배제해야 한다. 그러면 정규표현식 엔진에 대해서만 백슬래시 문자 처리를 해주면 된다.

4. re 모듈 주요 함수

A. compile

다음 순서로 쓴다.

  • 모듈 import 하고
  • 패턴으로 정규표현식 객체를 만들고
  • 객체를 이용해 매칭되는 문자열을 뽑아낸다.
import re
REGEX = re.compile('pattern', re.IGNORECASE)
result = REGEX.findall("Some String")

compile 메소드는 매개변수로 패턴 뿐만 아니라 flag 정수 값도 받는다. 디폴트는 0이고 위의 re.IGNORECASE는 2를 나타낸다. 2가 들어가면 대소문자를 무시한다. 옵션 값은 아래에서 추가 설명한다.

B. match, search

  • 패턴이 문자열과 매치되는지 찾는 메소드들이다. match는 전체 문자열에서 처음부터 바로 패턴이랑 일치하는지 찾는 것이고, search는 문자열 처음이 패턴과 맞지 않더라도 이후에도 맞는게 있는지 쭉 찾아나가는 것이다.
  • 매치되는게 있으면 match object를 리턴한다. 없으면 None
  • 예를 들어 패턴이 '\w+'라면 '!@#abcde00 hello' 문자열에 대해서 match는 첫 문자가 특수기호이므로 바로 None을 리턴한다. 하지만 search는 계속 검사를 해서 'abcde00'에 대한 match object를 리턴한다.
  • match object는 다음 코드에서와 같이 group(), start(), end(), span() 네 가지 메소드를 가지고 있다. group은 매치된 첫 번째 문자열을 리턴하고, start는 전체 텍스트에서 그 매치된 문자열의 시작 인덱스, end는 매치된 문자열의 마지막 인덱스+1을 리턴한다. span은 시작, 끝 인덱스를 튜플로 리턴한다. 아래 코드를 참조한다.
import re

text = '!@#abcde00 hello'
REGEX = re.compile('\w+')
result = REGEX.search(text)

if result:
    print('group: ', result.group())
    print('start: ', result.start())
    print('end: ', result.end())
    print('span: ', result.span())
else:
    print("No match")

C. findall

  • 위의 예제에서처럼 match와 search는 '!@#abcde00 hello'의 경우 뒤에 있는 'hello'는 리턴하지 않는다. 이렇게 패턴과 매칭되는 모든 문자열을 찾고 싶다면 findall을 쓰면 된다.
  • 매칭되는 모든 문자열을 리스트에 담아서 리턴한다.
find_result = REGEX.findall(text)
print(findresult)
# -> ['abcde00', 'hello']

D. finditer

  • 하지만 findall은 그 문자열의 인덱스는 알 수 없다. 그렇다고 match나 search를 쓰기엔 모든걸 찾지 못한다. 그래서 나온게 finditer다. 전체 텍스트에서 패턴과 매칭되는 모든 문자열을 찾지만 인덱스도 알 수 있도록 각각의 match object를 iterator로 만들어 리턴한다.
iter_result = REGEX.finditer(text)
if iter_result:
    for mo in iter_result:
        print('group: ', mo.group())
        print('start: ', mo.start())
        print('end: ', mo.end())
        print('span: ', mo.span())

E. sub, subn

  • sub : re_object.sub(repl, text, count=1) 형태로 사용할 수 있다. text에서 re_object에서 정의된 패턴을 repl로 바꾼다. count 매개변수는 명시해줘야 하며 적어주지 않을 땐 모든 패턴 매칭을 다 바꾸고, count에 숫자를 정하면 그 수만큼만 바꾼다.
p = re.compile('(blue|white|red)')
p.sub('colour', 'blue socks and red shoes')
# 리턴값: 'colour socks and colour shoes'
  • subn: sub과 리턴값이 다르다. 바꿔진 결과와 바꿔진 회수를 튜플로 리턴한다.

  • sub, subn backreference 가능: \g<그룹명> 형태로 repl을 지정해주면 된다. 물론 참조 번호로 \1 \2 이런걸 사용해도 좋다.

p = re.compile(r"(?P<name>\w+)\s+(?P<phone>(\d+)[-]\d+[-]\d+)")
print(p.sub("\g<phone> \g<name>", "park 010-1234-1234"))
# print(p.sub("\g<2> \g<1>", "park 010-1234-1234"))
# 리턴값: 010-1234-1234 park
  • sub 함수의 repl 파라미터에 함수가 들어갈 수 있다. match object를 매개변수로 받게 되므로 그렇게 함수를 정의해줘야한다. 마치 finditer 함수를 실행한 것처럼 문자열과 매치된 모든 match object를 함수의 매개변수로 하나하나 넣어주는 것 같다. 함수의 리턴값으로 문자열에서 매치된 부분이 변환되고 전체 문자열이 최종 리턴된다.
def hexrepl(match):
    "Return the hex string for a decimal number"
    value = int(match.group())
    return hex(value)

p = re.compile(r'\d+')
p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')

# 리턴값: 'Call 0xffd2 for printing, 0xc000 for user code.'

F. re 모듈에서 바로 사용하기

매개변수를 순서대로 패턴, 문자열로 주면 모듈에서 바로 사용할 수있다.

result = re.search('\d+', text)
print(result.group())

5. 컴파일 옵션

변수명약어의미
DOTALLS. 이 줄바꿈 문자를 포함하여 모든 문자와 매치할 수 있도록 한다.
IGNORECASEI대소문자 관계없이 매치
MULTILINEM여러 줄과 매치할 수 있도록 함. (^, $ 메타 문자와 관련 있다.)
VERBOSEXverbose 모드 사용 가능. 정규식을 보기 편하게 만들 수 있고 주석 등을 활용 가능

re.DOTALLre.IGNORECASE는 쉬워서 예제는 생략하겠다.

A. re.MULTILINE

  • 우선 ^$에 대하여
    • re.MULTILINE은 다음 두 메타 문자와 관련있다: ^ - 문자열의 처음, $ - 문자열의 마지막
    • '^python'의 패턴이라면 전체 텍스트가 'python'으로 시작해야 한다는 의미다. 'python$'의 패턴은 전체 텍스트의 마지막이 'python'으로 끝나야 한다는 의미다.
    • 아래 코드에서 두 결과 모두 ['python'] 다. 딱 하나씩만 python이 담겨 나온다. 즉 전체 텍스트에서 맨 앞, 맨 끝을 검사하는거다.
import re
text = '''python hihi 
python aslkdj1249sk
ldkjfsd92 23 
asldkf python'''

REGEX_front = re.compile('^python')
REGEX_end = re.compile('python$')
f_result = REGEX_front.findall(text)
e_result = REGEX_end.findall(text)
if f_result: print('^ result:', f_result)
if e_result: print('$ result:', e_result)
  • re.MULTILINE
    • 즉 한마디로 설명하면 ^, $를 사용할 때 전체 텍스트를 대상으로 하지말고 개행문자 기준으로 한 줄씩 대상으로 한다는 의미다.
    • 위 코드에서 만약 REGEX_front = re.compile('^python', re.M) 으로 수정한다면 f_result 출력 결과는 ['python', 'python']이 된다. 끝. 쉽죠?
    • 추가로 ^$를 문자 그 자체로 이용하고 싶다면 \를 붙이든가, [ ] 안에 넣는다.

B. re.VERBOSE

한마디로 '복잡한 정규식의 경우 이해하기가 어려우므로 의미 단위로 라인을 구분하고, 주석을 달 수 있도록 해주는 flag 값이다!' 라고 정의할 수 있겠다.

  • 정말 알아보기 힘들다. ↓
charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')
  • 같은 의미지만 훨씬 이해가 편하다. ↓
charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

re.VERBOSE flag를 적용하면 저렇게 라인과 탭 등으로 구분해서 들어가게된 white space는 컴파일할 때 다 사라진다. 하지만 [ ] 내에서 사용된 것은 남는다.

6. Grouping : ( )

A. 기본 개념

  • 그룹 단위 속성 적용: 말 그대로 그룹이다. +나 *, ?를 문자 하나가 아니라 문자 집단에 적용하고싶을 때 사용한다. (ABC)+ 라면 'ABC'가 1번 이상 반복된다는 의미다.
  • 매치된 텍스트에서 특정 부분만 뽑아낼 때: 이름과 전화번호가 연달아 적힌 패턴을 찾아낸다고 가정했을 때 거기서 이름만 뽑아내고자 한다. 이럴 때 그룹이 굉장이 유용하다. 아래와 같은 코드에서 group() 메소드의 매개변수에 들어가는 숫자로 그룹을 지정할 수 있다. 0은 전체, 1은 첫 번째 그룹, 2는 두 번째 그룹이다.
  • 재밌는건 그룹을 중첩시킬 수도 있다는 것이다. 바깥에서부터 안으로 들어가는 순서다. 아래 예제를 보면 마지막 5674가 출력된다.
import re
REGEX = re.compile(r"(\w+)\s+((\d+)[-](\d+)[-](\d+))")
text = "park 010-1234-5674"
print(REGEX.search(text).group(5))

B. Backreference, 재참조

동일한 문자열이 반복되는 패턴을 찾고싶을 때 backreference를 쓴다. 그냥 같은 패턴을 다시 쓰기 싫어서 Backreference를 쓰는 것이 아니다. 정확하게 같은 단어가 반복되는 것을 찾을 때 사용한다. 파이썬 컴파일러와 충돌이 일어날 수 있으므로 \1를 사용할 땐 꼭 raw string으로 해야 한다. \1은 첫 번째 그룹, \2는 두 번째 그룹인 방식이다.

p = re.compile(r'(\b\w+)\s+\1')
p.search('Paris in the the spring').group()
# 리턴값: 'the the'

만약 findall 메소드를 썼을 때 패턴에 그룹이 있다면 그룹에 포함된 것만 리턴한다.

result = re.findall('abc(de)fg(123)', 'abcdefg123 and again abcdefg123')
print(result)
# 리턴값: [('de', '123'), ('de', '123')]

하지만 패턴에 그룹이 있는데 그 그룹이 반복되는 경우엔 마지막 반복만 포함한다. 아래 코드의 경우에 'www.naver.', 'www.daum.'까지 매칭이 되지만 그룹이 설정되어있고, 그 그룹이 반복되기 때문에 반복되는 마지막 결과인 'naver.'과 'daum.'이 리스트로 리턴된다.

import re
result = re.findall('(\w+\.)+', 'www.naver.com www.daum.net')
print(result)
# 리턴값: ['naver.', 'daum.']

C. 그룹 이름 지정

그룹이 많아지는 경우 구분이 힘들기 때문에 그룹에 이름을 붙일 수 있게 되었다. 쉽다. 그룹으로 지정한 패턴앞에 ?P그룹명만 덧붙여주면 된다. 물론 그룹 안에. 결과값을 뽑아낼 때 group(1), group(2)가 아니라 group('name') 형태로 뽑아낼 수 있다.

p = re.compile(r"(?P<name>\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group("name"))

만약 이름이 있는 그룹을 backreference 하려고 한다면 아래처럼 ?P=그룹명 형태로 그룹이름을 지정해주면 된다.

p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
p.search('Paris in the the spring').group()

7. Lookahead Assertions

  • 사용 상황: 찾고자 하는 문자열의 패턴과 관련있지만 리턴값에는 없었으면 할 때 사용한다.
  • 종류 2가지
    • 긍정형 (?=...) : 패턴에는 포함되는데 리턴값에는 없는 경우
    • 부정형 (?!...) : 패턴에 포함되면 안되며! 리턴값에는 당연히 패턴에 포함되지 않으니 없을 것이다. 그래서 제외되지 않아야할 패턴은 부정형 lookahead assertion 뒤에 삽입해주면 된다. 선후관계 중요.
  • 긍정형 예제
# 결과는 ['https:'] 이다. 그런데 'https'만 가져오고싶다면?
import re
REGEX = re.compile('.+:')
result = REGEX.findall('https://www.google.com')
print(result if result else 'no')
# 긍정형으로 사용하면 된다. 패턴에 :는 분명히 있어야하지만 포함되진 않는다.
import re
REGEX = re.compile('.+(?=:)')
result = REGEX.findall('https://www.google.com')
print(result if result else 'no')
  • 부정형 예제: 'bat' 확장자를 제외한 파일의 파일명을 찾고싶다면?
# 파일명 + . + 확장자(문장의 끝 한정) 의 패턴으로 찾는 것이다. 하지만 멀티라인 옵션을 적용해줘서 줄마다 찾을 수 있게 해줬다.
# 결과: ['abcd.exe', 'power.dat', 'super.scriv', 'iron.bat', 'hi.cf']
import re
REGEX = re.compile('.*[.].*$', re.M)
result = REGEX.findall("""abcd.exe
power.dat
super.scriv
iron.bat
hi.cf
""")
print(result if result else 'no')
# 그런데 만약 bat 확장자를 제거하고 싶다면?
# bat가 위치할 지점, 원래 확장자를 의미하는 패턴의 앞에서 미리 lookahead assertion 부정형으로 차단해준다.
# 아래 코드에서 보면 확장자 패턴의 바로 앞, 그리고 '.'을 나타내는 패턴 바로 뒤에 '(?!bat$)'가 사용되었다. 저러면 bat는 제외된다.
# 역시 부정형 패턴에도 $는 꼭 들어가줘야한다. 만약 안들어가고 그냥 '(?!bat)'가 사용된다면 'hehe.bat.ho' 문자열도 매치되게 된다.
# bat 뿐만 아니라 exe도 제외하고 싶다면 '(?!bat$|exe$)'처럼 구분한다.
import re
REGEX = re.compile('.*[.](?!bat$).*$', re.M)
result = REGEX.findall("""abcd.exe
power.dat
super.scriv
iron.bat
hi.cf
hehe.bat.ho
""")
print(result if result else 'no')

8. Greedy vs Non-Greedy

.* 같은 패턴을 사용하면 '.'을 제외한 모든 문자들이 다 매칭된다.(greedy) 아래예제에서 만약 .*을 그대로 사용하면서 <html>만 뽑아내고 싶다면 어떻게 해야할까.

s = '<html><head><title>Title</title>'
# len(s) -> 32
re.match('<.*>', s).span()
# (0, 32)
re.match('<.*>', s).group()
# <html><head><title>Title</title>

이 때 non-greedy 문자인 ?를 사용한다. ?는 반복 메타문자 뒤에 붙어서 가능한 가장 적은 반복만을 수행하게 만든다. *?, +?, ??, {m,n}? 처럼 사용.

re.match('<.*?>', s).group()
# <html>


'파이썬' 카테고리의 다른 글

파이참(pycharm) 단축키 정리  (0) 2021.09.15
Python 문법  (0) 2018.04.03
Jupyter Notebook이란?  (0) 2018.04.03
iterator, generator 사용법  (0) 2018.04.03
decorator(wrapper) 사용법  (0) 2018.04.03
posted by 귀염둥이채원 2018. 4. 3. 01:59

1. 주석

  • 한 줄 주석: #
  • 여러 줄 주석
    • 문자열을 만드는 방법과 동일하게 """ 내용 """ or ''' 내용 ''' 사이에 넣을 수도 있지만
    • PEP8에선 한 줄짜리 주석을 연속해서 쓰는 것을 권장하고 있다.
    • 서브라임 텍스트 등 대부분의 에디터는 cmd(or ctrl) + / 단축키를 지원한다.

2. 자료형

2.1. 숫자형

항목사용 예
정수123, -123, 0
실수1.2, -0.4, 3.4e10
복소수1+2j, -3J
8진수0o45, 0O42
16진수0xA1, OXFF
  • 지수 표현하기: 1의 자리 수와 소수로만 표현한다. 그리고 뒤에 e(E 동일)를 붙여서 10의 제곱수를 곱해서 표현한턴. 1.23e10은 1.23에 10의 10승을 곱한 것이고, 3.45e-10은 3.45에 10의 -10승을 곱한 것이다.
  • 복소수 활용: 내장함수가 있다.
    • 복소수.real복소수.imag 처럼 뒤에 붙여 사용하면 순서대로 실수부와 허수부를 리턴한다.
    • 복소수.conjugate()라는 내장함수를 사용하면 켤레복소수를 리턴한다.
    • abs(복소수)는 절대값을 리턴하는데 계산 방식은 1+2j일 때 1의 제곱과 2의 제곱을 더해서 루트씌운것이다.

2.2 문자열

2.2.1 기본

  • 문자열 나타내는 방법: ''""''' '''""" """ 이렇게 4가지다.
  • 문자열 합칠 때: 더하면 된다. "hihi" + "hello" => "hihihello"
  • 문자열 반복시키기: 곱하면 된다. "hi" * 2 => "hihi"
  • 문자열 역시 iterable이다. 인덱싱과 슬라이싱 활용할 수 있다.
    • 'abc'[2] => 'c''abcde'[-1] => 'e''abc'[-0] => 'a'
    • 'abc'[:2] => 'abc''abcde'[1:3] => 'bcd''abcde'[1:-2] => 'bc'
    • 하지만 인덱싱을 활용해서 문자열의 내용을 바꿀 수는 없다. 'abc'[0] = 'A' 를 하려면 에러가 뜬다. 새로 만들어야 한다. 기존 것을 활용하고 싶다면 바꾸고 싶은 글자의 인덱스를 확인하여 전과 그 후 부분을 슬라이싱해서 이어붙이면 된다.
    • :을 기준으로 start, end, stride 다. 만약 stride가 -면 뒤에서부터 역순으로 밟아나간다 생각하면 된다. 'abc'[::-1]이면 'cba'이고, 'abc'[::-2]이면 'ca'이다.

2.2.2 문자열 포매팅

코드설명
%s문자열 String
%c문자 character
%d정수 Integer
%f부동 소수 floating-point
%o8진수
%x16진수
%%퍼센트 문자 나타내기
  • '%d %s + %' 사용 방법
    • "I eat three %s" % "apple"
    • "I eat %d %s" % (3, "apple")
    • “I eat %s apples” % 3 이렇게 하면 3이 문자열 형태로 치환돼서 들어감. 변수가 무슨 타입인지 모르면 그냥 %s로 다 받아도 상관없다.
    • 값을 나타내는 변수를 활용해도 된다.
    • %를 사용할 때 % 문자를 나타내려면 %% 두 번 적어야 한다. %d%%
    • %10s 우측정렬. %-10s 좌측정렬. 공백 10개
    • %.4f 소수점 4자리까지
  • format 사용 방법
    • "{0} is {1}".format(1, “hi”)
    • 역시 % 때와 마찬가지로 숫자는 문자열로 자동 변환되고 값이 아닌 변수를 활용해도 오케이.
    • 이름으로 치환 가능하고 혼용도 된다: “I ate {0} applse. so I was {sick}”.format(3, sick=“hi”)
  • format에서 정렬하기
    • {0:<10} 좌측 정렬, {0:>10} 우측 정렬, {0:^10} 가운데 정렬 10칸 공백
    • 정렬기호(<, >, ^) 앞에 문자 하나 넣으면 그걸로 빈칸 채움. {0:_^10} 이런 식
  • .format에서 소수점 표현: {0:10.4f}
  • .format에서 curly bracket { }를 문자 그 자체로 표현하려면 2번 써준다. {{ }}
  • 문자열 앞에 r을 붙여서 r'hello' 이렇게 쓰면 순문자열이 된다. 즉 excape 문자 \를 쓰지 않아도 \n이나 \t 같은 문자를 나타낼 수 있다.

2.2.3 주요 함수들

  • 문자열에서 특정 문자 개수 세기: a = ‘hobby’ , a.count(‘b’)
  • 문자열에서 특정 문자 위치: a.find(‘b’) 또는 a.index(‘b’)
  • 문자열 삽입 join: “,”.join(‘abcd’) 를 하면 “a,b,c,d” 가 된다.
  • 공백 지우기: a.lstrip()a.rstrip() 왼쪽 오른쪽 지우기. 양쪽은 그냥 strip()
  • 문자열 바꾸기 replace. 정규표현식 간편하게 만든 느낌이다.
    • a = “life is too short”
    • a.replace(“life”, “yours”)
    • a = “yours is too short” 가 됨
  • split(). 나눠서 리스트에 넣음
    • () 사이에 아무것도 안넣으면 공백 기준으로 구분함
    • a=“a:b:c:d” 일 때 a.split(“:”) 하면 [‘a’, ‘b’, ‘c’, ‘d’]
  • str.maketrans(x[, y[, z]]) : 문자 단위 매핑되는 사전을 만드는 것
    • 매개변수 한 개: dictionary 객체
    • 두 개: 동일한 길이의 두 문자열이 들어가서 같은 위치끼리 대치된다.
    • 세 개: 앞의 두 매개변수는 두 개일 때와 같고, 세 번째 문자열은 모든 문자가 None으로 매핑된다.
  • 'Hello world!'.translate(dict_obj) : maketrans 함수로 나온 dict 객체를 규칙으로 해서 문자열을 변환한다.

2.3 리스트

2.3.1 기본

  • 리스트에 다양한거 다 들어갈 수 있다. 리스트까지 들어갈 수 있음.
  • 빈 리스트 생성은 a = list() or a = []
  • 리스트의 리스트는 이차원배열처럼 이해하면 됨. 리스트의 리스트의 리스트는 당연하게도 삼차원배열처럼 뽑아냄
  • 리스트 슬라이싱. 문자열 슬라이싱과 동일
  • 리스트 더하면 합쳐진 리스트가 됨. 곱하기는 같은게 반복되서 리스트가됨.
  • 리스트 수정은 그 부분 뽑아서(요소 하나만 인덱스로 뽑든, 슬라이싱으로 뽑든) 다른거 대입하면 된다. 리스트를 집어넣으면 리스트가 들어간다. 다만 한 가지 다른 것은
    • a[0] = [1, 2, 3] 으로 하면 리스트 자체가 들어가게되고
    • a[0:1] = [1, 2, 3]으로 하면 첫 칸에 요소 세 칸이 들어가는 것. 리스트가 들어가는게 아니다.
  • 리스트 요소 삭제는 a[0]=[] , a[1:3]=[] 식으로 빈 리스트를 대입하면 된다. 혹은 del 함수를 사용해서 del a[0] 해도 된다. del 하면 객체 자체가 지워진다. 즉 사용하던 메모리를 free 시킨다는 것을 의미한다. 즉 garbage collection이며 파이썬이 자체적으로 하고 있기 때문에 메모리 사용량을 위해 굳이 따로 해줄 필요는 없다.

2.3.2 관련 함수들

  • 리스트 + 리스트 하면 두 리스트가 연결된다.

  • [1] * 5 를 하면 [1, 1, 1, 1, 1]이 된다. 초기값 세팅할 때 좋을듯. 다음 예는 5X5 이차원 배열에 문자 'O'를 세팅하는 예다.

    board = []
    for i in range(5):
        board.append(["O"]*5)
  • a.append('something') 요소 추가는 맨 마지막에 붙는다.

  • a.sort()는 요소를 순서대로 정렬하는 것. 숫자도 되고, 문자도 된다. 오름차순.

  • a.reverse()는 요소 순서를 반대로 바꾸는거. 즉 sort한 다음에 리버스하면 내림차순 정렬이 됨.

  • a.index(요소) 를 하면 인덱스값을 반환.

  • a.insert(index, value) 를 하면 대체가 아니라 추가가 된다. 0 인덱스에 넣으면 원래 있던 요소들이 앞으로 한 칸씩 밀린다. 즉 설정한 인덱스 이후의 요소들이 모두 한칸씩 뒤로 밀린다.

  • a.remove(value)를 하면 a의 요소들 중 첫 value 요소를 제거한다. 만약 요소가 없다면 에러가 난다. 모든 요소를 다 제거하고 싶으면 try 안에 반복문 돌리는 것도 괜찮겠다.

  • a.pop() 은 맨 마지막 요소 빼낸다. 매개변수로 인덱스 값을 넣어주면 remove와 똑같이 첫 요소를 제외한다. 다만 remove와 다른 점은 뽑은 값을 리턴한다는 것.

  • a.count(1)은 1이 몇 겐지 세아려서 갯수를 리턴함

  • a.extend([1,2,3])을 하면 a 리스트 뒤에 매개변수 값이 합쳐진다. a += [1, 2, 3]과 동일한 의미다. append와 다른 점은 만약 a.append([1, 2, 3]) 하면 a의 마지막에 리스트 자체가 원소로 들어간다. 리스트가 합쳐지는게 아니라 리스트가 붙는다. 즉 위의 리스트 수정에서 extend는 슬라이싱, append는 인덱싱과 매칭된다 할 수 있다.

2.4 튜플

  • 리스트와 대부분 쓰는 방법이 같다. 생성은 my_tuple = ()를 쓰는 것이 일반적이고 아예 안써도 된다. 예를 들어 a = 1, 2, 3 처럼.
  • 위처럼 적용되기 때문에 리스트 내포 for문을 사용할 때 []로 감싸주지 않고도 바로 sum이나 max 함수를 쓸 수 있는 것이다.
  • 수정이 불가능하다. 상수화 된 리스트라고 생각하면 될까. 이 특성이 가장 중요하다. 대부분의 메소드를 똑같이 쓸 수 있지만 수정, 삭제, 추가는 안된다.
  • 요소 한 개만 쓰려면 a = (1,) 이렇게 뒤에 콤마 붙여야 함

2.5 딕셔너리

2.5.1 기본

  • a = {‘key’:’value’, ‘key’:’value’}
  • 키와 밸류로 이루어짐. 키를 인덱스처럼 활용해서 밸류를 뽑아낼 수 있다.
  • 키에는 숫자도 되고 문자열도 됨. 튜플도 됨. 하지만 리스트는 안됨. 키에는 변하는 값이 들어가면 안된다. 밸류에는 어떤 값이든 다 됨
  • 딕셔너리에는 인덱싱이나 슬라이싱 안된다. 무조건 키를 인덱스처럼 활용해서 밸류를 뽑아내는 수밖에 없다.
  • 뽑아내는거랑 같은 방식으로 썼을 때 만약 그 쌍이 없다면 추가되는 것.
  • 딕셔너리에는 순서가 없음.
  • 삭제는 del a[key] 형태로.
  • 처음 딕셔너리를 생성할 때 {1:111, 1:222} 형태로 키를 중복시키면 랜덤으로 하나만 남는다. 뭐가 없어지고 남을지 모른다.
  • 딕셔너리도 len(dict) 먹힌다. key-value pair 개수를 리턴.

2.5.2 관련 함수

  • a.keys() 라고 하면 딕셔너리의 키들이 뽑혀나옴. dict_keys 라는 객체 형태로 뽑힘. 만약 리스트가 필요하다면 list(a.keys()) 로 형변환하면 됨. 근데 굳이 변환 안해도 반복문 쓸 수 있음.
  • dict_keys 객체에선 append, insert, pop, remove, sort 메소드 사용 안된다.
  • a.values() 라고 하면 dict_values 객체가 리턴됨. 키객체와 같음
  • a.items()를 하면 쌍을 튜플로 각각 묶어서 dict_items 객체로 리턴함
  • 다 지우려면 a.clear()
  • a[key] 와 비슷하게 a.get(key) 도 됨. 다른 점은 없는걸 원했을 때 전자는 에러를 띄우지만 후자는 NONE을 출력. 후자가 나은듯. 에러 없으니
  • a.get(key)를 쓸 때 만약 값이 없을 때 논 대신 다른걸 쓰려면 디폴트값 설정할 수 있다. 이렇게. a.get(key, default)
  • key가 있는지 조사할 때 key in my_dict 쓰면 된다. 사실 in은 리스트나 튜플, 문자열 등에서도 모두 쓰일 수 있다. True False 리턴한다.

2.6 집합(Sets)

  • set은 my_set = set(my_list) 형태로 만든다.
    • my_set = set([1,2,3,4,5,5,5,5,5]) => set([1, 2, 3, 4, 5])
    • my_set2 = set(‘hello’) => set([‘h’, ‘e’, ‘l’, ‘o’])
  • 중복도 없고 순서도 없다.(index 미지원)
  • list(my_set) 처럼 형변환해서 인덱스 써라.
  • 교집합: & 또는 set1.intersection(set2)
  • 합집합: | 또는 set1.union(set2)
  • 차집합: set1 - set2 또는 set1.difference(set2)
  • 집합에 추가할 때
    • 한개만 추가: set1.add(value)
    • 여러개 동시 추가: set.update([5,6,7])
  • 제거: set.remove(value) 이것도 매개변수 딱 하나만 받는 함수다.
  • 세트의 원소로 리스트, 세트, 딕셔너리는 들어갈 수 없다. unhashable type이라고 TypeError라고 뜬다.

2.7 Boolean

  • 문자열, 리스트, 튜플, 사전형, 세트가 차있으면 참. 비어있으면 거짓
  • a = [1, 2, 3, 4] 일 때 a 리스트를 조건으로 해서 pop으로 뽑아내면 모두 뽑힌다. 예를 들어 while(a): print(a.pop())대신 이렇게 하면 반복이 끝난 후 a는 빈 리스트가 된다.

2.7 변수에 대하여

  • (a, b) = 1, 2 혹은 [a, b] = [3, 4] 식으로 여러 변수에 값을 한 방에 대입할 수 있다.
  • 두 변수의 값을 swap 하는 재밌는 방법: a, b = b, a
  • list를 복사할 때는 단순히 b = a 처럼 대입하면 안된다.
    • 두 레퍼런스 변수가 같은 객체를 가리키는 것이 되어버린다. 동일한 놈을 가리키고 있음.
    • 이러면 a가 가리키는 list의 원소를 수정했을 때 b가 가리키는 list의 원소도 변한다. 같은 list니까.
    • b = a[:] 처럼 하거나 from copy import copy 한 후에 b = copy(a) 처럼 활용한다.

3. 제어문(if, while, for)

  • value in iterable 형태 잘 쓰임. value not in iterable 도 가능.

  • is 와 == 는 같은 의미. 동시에 is not과 != 역시 같은 의미

  • 조건문에서 아무것도 하기 싫으면 pass 사용. 아예 안적으면 오류나서 이거 적어줘야 한다.

  • 가장 가까운 반복문 빠져나가는 break

  • 반복문에서 아래 코드는 더 이상 실행하지 않고 다음 반복으로 넘어가는 continue

  • 리스트 내포: [표현식 for 항목 in 반복가능객체 if 조건문]

  • for문에서 2개씩 변수를 받을 수도 있다.

    • 근데 만약 변수를 하나로만 받으면 아래 코드의 케이스에서 [1,2] [3,4] [5,6] 이렇게 세 뭉치로 튀어나오고
    • 변수를 i, j, k 세 개로 받으면 2개밖에 없는데 왜 3개 지정했냐고 에러가 난다. (루비에서는 알아서 k에 None을 넣더라. 에러 없이)
    test_list = [[1, 2], [3, 4], (5, 6)]
    for i, j in test_list:
        print(i, j)
  • print는 자동으로 개행한다. 없애려면 print("somethin", end=" ") 식으로 end에 원하는 문자를 지정해주면 된다. 디폴트가 개행문자 \n인 셈이다.

  • for와 while에서 else를 같이 쓸 수 있다.

    • 조건에 맞게 반복을 돈 후, 빠져나올 때 else의 실행문을 한 번 실행한다.
    • 하지만 조건이 아니라 중간에서 break 때문에 빠져나올 경우엔 else를 실행하지 않는다.
    • 리스트에서 조건 검사를 할 때 온전히 통과했다는 메시지를 else를 통해 해줄 수 있겠다. 만약 중간에서 틀린 검사가 나와서 break 했을 경우엔 else가 실행되지 않으므로 통과 메시지가 출력되지 않는다.
  • zip : 리스트가 2개 있는데 매칭해서 출력하고 싶을 때 사용한다. 짧은 쪽 리스트가 끝날 때 반복이 멈추고 원하는 만큼 리스트들을 zip할 수 있다.

    list_a = [3, 9, 17, 15, 19]
    list_b = [2, 4, 8, 10, 30, 40, 50, 60, 70, 80, 90]
    
    for a, b in zip(list_a, list_b):
        print max(a, b)

4. 입출력

4.1 함수

  • 함수 정의할 때 매개변수 없더라도 빈 괄호를 붙여줘야 한다.

    def hi():
        print("HI")
  • def 라인 바로 아래에는 주석으로 함수에 대한 설명을 적어주면 좋다.

  • 함수를 정의할 때 다른 함수 활용 가능. 즉 함수 내에서 함수 호출 가능

  • 함수의 리턴값은 오직 하나다. 두 개 이상을 리턴하는 것으로(예로 return a, b) 함수가 짜여진다면 이것은 (a,b)라는 하나의 튜플이 리턴되는 형태다. 그래서 c, d = a() 이런식으로 바로 두 개 변수에 집어넣을 수 있음.

  • 매개변수로 몇 개를 받을지 모를 때 앞에 * 붙여주면 된다. 주로 *args 라고 칭하는게 컨벤션이고 원하면 args 말고 다른 단어(python)를 써도 된다. 마지막에 써줘야 함. 이 args를 쓰려면 튜플 형태로 매개변수가 들어오기 때문에 iterable 활용하는 방식으로 써주면 된다.

  • 매개변수가 입력되지 않았을 때 디폴트값(초기값)을 설정할 수 있다. 매개변수 뒤에 param=value 하면 된다. 대신 디폴트값이 없는 매개변수 뒤에 있어야한다.

  • 함수 내의 변수 효력 범위

    • 아래 코드처럼 함수를 실행해도 a의 값은 변하지 않는다.
    • 정말 단순히 함수 내의 지역변수일 뿐이다. 값만 전달받은 것 뿐(call by value), 그 값 자체를 변화시키지(call by reference) 않는다.
    • 1을 증가시킨 값을 리턴해서 원래 변수에 다시 대입하는 방식밖에 없다.
    a = 1
    def variable_test(n):
        n += 1
        return
    variable_test(a) # a doesn't change

4.2 입력과 출력

  • print에서 print('hi' 'hi' 'hi')처럼 붙여쓰면 +랑 똑같고,
  • comma(,)로 이으면 띄워써진다. print(‘hi’, ‘hi’, ‘hi’)
  • 사용자 입력은 input() 해주면 된다. 리턴값은 입력받은 값이고, 매개변수로 문자열을 넣으면 콘솔에 "입력하세요: " 이런 문구로 사용된다. 무조건 문자열 타입 리턴

4.3 파일 읽고 쓰기

4.3.1 파일 스트림 열고 닫기

  • 아래 코드가 가장 일반적인 포맷이다. 즉 파일객체 = open(파일이름, 모드) 형태.

  • 모드는 r, w, a가 있고 순서대로 읽고, 쓰고, 추가한다. r+를 넣으면 read, write 둘 모두 된다.

    # 디렉토리에서 ~ 단축키는 안 먹힌다. 절대경로 쓰려면 다 적어줘야 함
    f = open("/Users/gyubin/Desktop/hi.txt", 'w')
    f.close()

4.3.2 읽기 함수

  • f.read() : 파일의 모든 데이터를 읽어온다. 모든 데이터를 읽어왔다면 다시 이 함수를 실행했을 때 빈 문자열 ""을 리턴한다.
  • f.read(int_value) : 숫자크기 만큼만 글자를 읽어온다. 3을 넣으면 3글자씩 읽어온다. 실행할 때마다 정한 크기만큼 글자를 읽어오고 모두 읽어왔을 때는 역시 빈 문자열 ""를 리턴한다.
  • f.readline() : \n이 발견될 때까지 개행문자를 포함해서 읽어온다. 즉 한 줄씩 읽어온다. 파일이 개행문자 없이 끝난다면 파일 끝까지 읽어들인다. 역시 파일 끝에 도달한 후에는 빈 문자열 ""이 리턴된다.
  • 쓸데없는 실험
    • 재밌는 현상 1: 만약 write 함수를 이용해서 f.write('hi\n') , f.write('hello\n') 이 두 명령어를 실행했다고 하자. 그리고 파일을 에디터로 열어보면 hi와 hello 딱 두 줄만 있다.
    • 재밌는 현상 2: 현상 1에 f.write('\n')이 추가로 실행한다면 세 번째 줄에 공백라인이 하나 더 있다.
    • 재밌는 현상 3: 에디터에서 바로 위의 예처럼 hi와 hello 딱 두 줄만 적고 저장해서 f.readline() 해보면 hello 뒤에는 \n 문자가 없이 나온다.
    • 재밌는 현상 4: 그런데 만약 현상 3에 추가로 한 줄을 띄워서 공백 라인을 하나 만든다면 hi\nhello\n이 됨은 물론 \n이라는 놈이 하나 또 나온다.
    • \n의 의미: '보여지는' 관점에서 개행문자의 의미는 에디터에서 개행문자를 기준으로 이전 문자열과 이후 문자열은 줄을 나눠서 보여라!는 의미다. 반대로 '입력하는' 관점에서 개행문자의 의미는 그 다음 줄부터 입력할 준비가 되었다!는 의미다.
    • 에디터에서 엔터키: 단순히 엔터키를 치기 전까지의 편집하던 줄 끝에 개행문자를 붙이는게 아니다. 엔터키를 친 이후 넘어간 라인의 끝에도 자동으로 개행문자를 붙인다. 즉 에디터에서 엔터키란 이전 라인, 이후라인 모두의 끝에 개행문자를 붙인다는 의미다.
    • 결론: 의미없다. 그냥 뭐가 다른지 궁금했을 뿐이다. 하나 정하자면 f.write을 통해 데이터를 입력할 때 에디터에서 마지막에 한 줄 공백라인을 보이고싶다면 파일 끝에 개행문자를 2개 넣어라. f.write('end of file\n\n'
  • for line in f: print(line, end="")
    • f 파일 객체에서 바로 반복문을 돌릴 수 있다. readline()처럼 개행문자까지 읽어들인다. 즉 한 줄씩 line 변수에 문자열로 할당된다.
    • readline()과 달리 콘솔에 출력하면 개행문자가 보이지 않는다. 보여지는 대신 에디터에서처럼 개행이 적용되어 출력된다. 그래서 개행문자가 연달아 입력되어있다면 공백 라인이 여러줄 출력되기도 한다.
    • print 함수가 기본적으로 개행을 하기 때문에 end=""를 적어줘서 중복되지 않게 해야 한다.
    • 가장 빠르고 효율적인 코드라고 공식문서에 적혀있다.

4.3.3 쓰기 함수

  • f.write(str_data): str_data에 들어있는 값을 파일에다가 쓴다. str_data는 문자열이어야 한다. 숫자거나 boolean이라면 에러난다. 리턴값은 쓰여진 문자열의 문자 개수다. "hi\n"을 입력했다면 3이 리턴된다.
  • JSON 파일로 저장하기!: 파이썬 데이터를 JSON으로 바꾸는 것을 serializing, JSON to Python Data를 deserializing이라고 한다.
    • import json
    • json.dumps(my_obj) : 괄호 안에 넣은 object를 serializing한 문자열을 리턴한다. 1은 '1''abc'는 "'abc'"[1, 2, 'abc']는 "[1, 2, 'abc']"로 바꿔준 값을 리턴하는 것. 결국 이 문자열을 파일 스트림을 쓰기모드로 my_json.json 이란 이름으로 열어서 쓰면 json 파일이 만들어지는 것이다.
    • json.dump(object, FILE) : s가 없어진 그냥 dump다. 매개변수로 저장할 객체와 쓰기 모드로 열린 파일 스트림 객체를 받는다. 이 코드를 실행하면 객체를 serializing한 문자열을 파일 스트림과 연결된 json 파일에 쓴다. 리턴값은 따로 없다.
    • [1, 2, 3]을 '[1, 2, 3]' 문자열로 바꿔서 파일에 쓰고, 파일을 에디터에서 열어보면 [1, 2, 3] 이라고 적혀있다.
    • my_var = json.load(FILE) : load 함수는 json 파일과 읽기 모드로 연결된 파일 객체를 매개변수로 받는다. 그리고 json 파일을 deserializing해서 데이터 객체로 만든 후 my_var 변수에 할당한다.
  • 즉 정리하면 "쓰기모드 파일객체 + json.dump"와 "읽기모드 파일객체 + json.load" 요렇게만 잘 쓰면 끝이다.

4.3.4 기타 관련 함수

  • with: 함수가 시작되면 파일이 열리고, 함수가 끝나면 파일이 닫힌다. 파일 객체는 빌트인 메소드로 __enter__() 와 __exit__()를 가지고 있다. 여기서 exit 메소드가 실행되면 파일 스트림이 닫히게된다. 이 메소드가 with에서 구현되어있다. 그래서 아래처럼 가능한 것.

    with open("foo.txt", "w") as f:
        f.write("Life is too short, you need python")
  • f.closed : 파일 객체인 f가 close 되었는지 확인할 수 있는 boolean 값이다. 닫혔으면 True를 리턴한다.

  • sys: 파일을 python으로 실행할 때 파일 외부에서 매개변수로 데이터를 받아올 수 있게 한다.

    • 예를 들어 아래 코드가 sys1.py 라는 파일이라면 python sys1.py 로 코드를 실행할 것이다. 여기서 python 명령어 다음에 오는 것이 매개변수다.
    • sys.argv는 이 매개변수들을 여러개 받아서 저장한 리스트다.
    • 'python sys1.py aaa bbb ccc' 라고 명령어를 터미널에서 실행하면 aaa bbb ccc가 출력될 것이다.
    • 아래 코드에선 2번째 원소부터 반복을 돌렸는데 첫 원소부터 돌리면 첫 번째 원소는 "sys1.py" 일 것이다.
    # 파일명: sys1.py, 명령어: python sys1.py aaa bbb ccc
    import sys
    args = sys.argv[1:] 
    for i in args: 
        print(i)
    # => aaa
    #    bbb
    #    ccc

5. 클래스

기본 구조는 다음과 같다.

class MyClass(ParentClass):
    <클래스 변수 1>
    <클래스 변수 2>
    ...
    def 클래스함수1(self[, 인수1, 인수2,,,]):
        <수행할 문장 1>
        <수행할 문장 2>
        ...
    def 클래스함수2(self[, 인수1, 인수2,,,]):
        <수행할 문장1>
        <수행할 문장2>
        ...
    ...
  • 클래스 내 로컬 함수를 정의할 땐 무조건 매개변수로 self 넣어줘야 한다. 인스턴스를 생성한 후 '인스턴스.함수' 형태로 함수를 실행하면 자동으로 매개변수로 self를 넣어주기 때문이다.

  • def __init__(self, *args): ~~ : init 함수는 생성자라고도 하며 인스턴스가 만들어질 때 항상 실행된다. self 무조건 들어감.

  • 클래스 상속은 뒤에 () 안에 상속받을 클래스를 적어주면 된다.

  • 연산자 오버로딩: 객체끼리 +, -, *, / 등의 연산을 할 수 있다.

    • 예를 들어 A라는 클래스에 __add__ 함수를 추가하면 + 연산이 가능하다.
    • A로 만든 a 객체가 앞에 있든 뒤에 있든 + 연산은 수행 가능하지만, self의 적용은 달라진다.
    • a + b 인 경우 self는 a이고, b + a인 경우에 self는 b이다. 두 객체 중 하나에만 add가 있으면 된다.
  • 변수 종류

    • global variable: 말 그대로 전역변수. 어느 위치에서도 호출 가능
    • member variable: init 함수 밖에서 선언된 변수. 결국 클래스 변수다. 클래스명.변수명 형태로 접근할 수 있다. 클래스에서도 호출할 수 있지만 인스턴스 변수 각각에서도 이 변수를 가지고 있어서 호출 가능하다. 즉 Hello 클래스에서 a, b 인스턴스를 만들었을 때 셋 모두 member variable을 갖고 있어서 다른 값을 설정할 수 있다. 웬만하면 사용하지말고 꼭 필요한 경우, 예를 들어 인스턴스 개수를 설정할 때 클래스의 멤버 변수만 활용하라고 말하는 사람들이 있다. 인스턴스에서는 웬만하면 호출하지 않는걸로.
    • instance variable: init 함수 안에서 선언된 변수. 만약 여기서 선언되지도 않고 대입되지 않았더라도 인스턴스.새로운인스턴스변수 = 값 형태로 적어주면 인스턴스에 변수가 추가된다.
    • 인스턴스 Namespace --> 클래스 Namespace --> Global Namespace 순서로 scope를 올려가며 변수를 찾는다.
    • 인스턴스 객체에서 클래스 멤버 변수로 접근하려면 myClass.__class__.classMember = 10처럼 __class__ 메소드를 활용한다.
  • 클래스의 함수를 method라고 한다. 일반 함수를 function

  • init 함수가 아니더라도 다른 함수에서 인스턴스 변수를 선언할 수 있다. init 함수가 실행되기 전엔 변수가 존재하지 않는다. 호출해도 없는 속성이라고 에러난다. AttributeError.

  • 클래스를 만들거면 웬만하면 object 클래스를 상속하자.

  • 클래스의 객체를 print했을 때 원하는 출력물을 지정하고 싶으면 __repr__ 메소드를 만들고 원하는 문자열을 return 하면 된다. 매개변수는 오직 self만.

    def __repr__(self):
        return "(%d, %d, %d)" % (self.x, self.y, self.z)
  • super: 아래 코드가 예시다. 부모 클래스의 메소드를 그대로 자식 클래스에서 쓰고 싶을 때 super를 쓴다. super(내클래스, self).메소드명(매개변수) 형태로 쓴다.

    class Employee(object):
        def __init__(self, employee_name):
            self.employee_name = employee_name
    
        def calculate_wage(self, hours):
            self.hours = hours
            return hours * 20.00
    
    class PartTimeEmployee(Employee):
        def calculate_wage(self, hours):
            self.hours = hours
            return hours * 12.00
        def full_time_wage(self, hours):
            return super(PartTimeEmployee, self).calculate_wage(hours)
    
    milton = PartTimeEmployee('Milton')
    print milton.full_time_wage(10)
  • 정적 메소드

    • 인스턴스를 통하지 않고 클래스를 통해 바로 메소드를 호출하기 위해 정적 메소드를 사용하게 된다. Python에서는 클래스의 정적 메소드를 구현하기 위해 다음과 같이 해당 메소드가 정적메소드임을 등록해야 한다.
    • Method Name = staticmethod(Method in Class)
    • 외부에서 호출 시에는 위의 Method Name으로 호출 하게 된다.
  • Private 멤버

    • Python에서는 문법적으로 클래스의 private 멤버를 지원하지 않는다. 대신 Name mangling을 이용하여 이와 유사한 기능을 수행하도록 할 수 있다.
    • 멤버 변수나 함수가 __로 시작하는 경우 외부에서 참조할 때는 자동으로 _클래스이름__멤버이름으로 변경하게 된다. 이로써 원래의 멤버이름으로는 접근 시 에러가 발생하게 되어 private 멤버 처럼 사용할 수 있게 된다. 당연히 클래스 내부에서 사용 시에는 멤버 변수 이름 그대로 사용 가능하다.
    class MyClass(parent):
        """ Class Document """
        __privateMember = 0
        def __init__(self):
            pass

6. 모듈

  • 함수 혹은 변수들로 이루어진 .py 확장자의 텍스트 파일이다.
  • abc.py라는 모듈 파일이 있다면 이 파일이 위치한 디렉토리에서 python 실행 후 import abc 하면 된다. 이렇게 모듈 파일 이름으로 단순하게 import하는것을 generic import라고 한다.
  • import abc 에서 import는 abc를 쓸 수 있게 해준다는 의미다. import 없이는 abc 라고 입력했을 때 선언되지 않은 변수라고 에러가 뜬다. 저 명령어를 쳐 줘야 abc가 의미를 갖는다.
  • abc 모듈에 AAA라는 함수가 있다고 할 때, import abc 했다고 그냥 바로 AAA 함수를 쓸 순 없다. abc.AAA라고 해야 한다. 앞에 abc를 생략하고 싶다면 from abc import AAA 라고 하면 바로 AAA 쓸 수 있다. 함수라면 뒤에 () 생략한다. 함수 이름만 써준다.
  • Universal Imports: from math import * 이렇게 하면된다. 썩 좋은 방법은 아님. 왜냐면 기본적으로 이미 import돼있는 수많은 변수나 함수가 존재한다. 근데 저렇게 math의 모든 것을 import 해버리면, 뭔가가 겹칠 수 있다. 같은 이름의 변수나 같은 이름의 함수들이. 좋은 방법이 아니다.
  • 만약 모듈에 함수나 변수만 덩그러니 있는게 아니라 실제 실행되는 명령어가 있다고 치자. 예를 들어 print문이 있다고 하면 import abc를 했을 때 그 코드들이 실행이 되게된다. import했을 때는 실행이 안되도록 하려면 if __name__ == "__main__": 이 if 블락 안에 실행문들을 넣으면 된다. 실제 python 명령어로 실행됐을 때만 실행 코드들이 동작하도록 만드는 조건이다.
  • 다른 모듈 사용할 때 import는 클래스 밖에서 사용한다.
    • vector.py 모듈과 모듈 내의 Vector class를 직접 만들었다고 하자.
    • 이 Vector 클래스는 norm이라는 메소드를 갖는데 이 메소드가 math 모듈의 sqrt 메소드를 사용한다.
    • 이럴 경우 import math를 클래스 내부에서 선언하면 norm 메소드가 동작하지 않는다. 클래서 definition 바깥에서 import 해줘야 한다.
  • 파이썬 모듈 저장 디렉토리 추가하기
    • 터미널에서 파이썬 repl을 실행한 후 import sys 한다. 그리고 sys.path를 입력해보면 리스트 형태로 경로들이 존재한다. 여기에 리스트이므로 append 함수로 경로를 문자열로 추가해주면 그 경로에 위치한 모듈은 바로 import해서 쓸 수 있다.
    • 혹은 터미널에서 set PYTHONPATH = C:\Python\Mymodules 형태로 지정해줄 수도 있다.

7. 2진수

  • 0b를 앞에 붙여주면 된다.

  • 2진수를 print 하면 10진수 형태로 출력된다.

  • bin(integers) : 정수를 매개변수로 받아서 문자열 형태인 2진수를 리턴한다.

  • oct(int)hex(int) : 8진수, 16진수로 바꾸는.

  • int(str_num, 자리수) : 첫 번째 매개변수는 문자열로 이루어진 숫자, 두 번째는 진법을 나타내는 숫자다.

    • 10이 디폴트값이고 2, 8, 16 등이 올 수 있다.
    • 진법 수는 2 이상 36 이하다.
    • 첫 번째 매개변수에 2, 8, 16진수를 나타내는 0b, 0o, 0x가 붙은 문자열이 들어올 수도 있다. 이 때는 이 진법에 맞춘 숫자가 두 번째 매개변수에 들어가야된다. 다른게 들어가면 에러난다.
  • shift 연산: operator 모듈의 lshiftrshift다. <<와 >>가 매칭된다.

    • lshift<<가 2배씩 커지는거고, rshift>>가 2배씩 작아지는 거다.
    • 하지만 항상 2배씩 변하는 것은 아니다. 예를 들어 0b0010 >> 2 하면 0이 되어버린다.
    • 오른쪽으로 1이 한 칸씩 가지만 끝에 도달하면 아예 사라지기 때문이다. 이 때문에 숫자 변화가 항상 1/2이 되는 것은 아니다.
  • bitmask: 예를 들어 오른쪽에서 3번째 자리수가 1인지 확인하고 싶다면 0b100과 검사하고싶은 수를 & 연산하면 된다. 결과가 0보다 크면 1인거고, 아니면 0인거다.

  • 원하는 비트 1로 만들기: 원하는 비트만 1인 수를 만들고 | 연산한다. 즉 오른쪽에서 세 번째 비트를 on하고 싶다. 그러면 0b100과 그 수를 | 연산하고 결과값을 쓰면 된다.

  • 비트를 다 뒤집고 싶다면: 원하는 수의 2진법 표현과 똑같은 자리수만큼 1로 채워서 ^ 연산하면 된다. 0b110101을 뒤집고싶으면 똑같은 자리수로 0b111111을 ^ 한다.

    def flip_bit(number, n):
        return bin(number ^ (0b1 << n-1))

8. 자주 쓸 것 같은 함수들

  • isalpha() : 문자열이 오로지 알파벳으로만 이루어져있는지
  • isdigit() : 문자열이 오로지 숫자로만 이루어져있는지
  • dir(math) : math 모듈에서 사용 가능한 모든 것을 리스트로 보여준다.
  • abs(-5), max(1,2,3), min(-4, -2, -10) : 절대값, 최대값, 최소값. 저렇게 단순한 콤마로 구분해서 여러 수를 넣을 수 있는 것은 콤마만 적으면 자동으로 튜플이 되기 때문이다.
  • type(something) : something의 타입을 리턴함.
  • import random
    • randint(low, high) 많이 쓰인다. low부터 high까지 임의의 정수 하나를 리턴한다. 중요한건 high 포함이고 둘 모두 정수여야 한다.
    • random.choice(iterable) : iterable에서 무작위로 원소 하나 리턴한다.
    • random.shuffle(iterable) : iterable을 무작위로 섞는다.
  • re 모듈에서 sub 함수가 있다. re.sub(pattern, replacement, string) 으로 쓰면 된다. 매개변수가 2개 더 있지만 저렇게만 자주 쓰일듯.
  • my_str.lower()my_str.upper()는 호출되는 대상을 바꾸지 않는다. 다시 대입해줘야.
  • filter(function, iterable) : iterable의 원소를 하나하나 빼내서 function에 적용한 후 리턴값이 True이면 리스트에 집어넣는다. 그리고 최종적으로 리스트를 리턴한다. Python2에선 리스트, Python3에선 필터 객체다.
  • map(func, iterable) : filter와 다르게 iterable의 원소 하나하나를 func에 대입해서 나온 결과값을 리턴 객체에 넣는다. 2에선 리스트, 3에선 맵 객체
  • locals() : 함수 내에서 실행하면 함수의 로컬 변수들을 딕셔너리 형태로 리턴한다.
  • all(iterable) : iterable 원소들이 모두 참인 경우 True 리턴한다.
  • any(iterable) : 참인 원소가 하나라도 있으면 True
  • chr(아스키코드값) : 아스키코드값을 받아서 문자로 리턴한다. ord 는 그 반대다.
  • divmod(7, 3) : 7을 3으로 나눈 몫과 나머지를 튜플로 리턴한다.
  • eval('1+2') : 실행 가능한 함수나 수식 등을 문자열로 받아서 결과값을 리턴한다. 이 코드는 3을 리턴한다. eval('divmod(7,3)') -> (2, 1)
  • repr(object) : 객체를 출력 가능한 문자열로 변환해서 리턴한다. 예를들어 repr('hi'.upper()) -> "'HI'"
  • lambda : 이름 없는 함수이며 주로 간단한 함수식을 표현할 때 쓴다. lambda 인수1, 인수2, ... : 인수를 이용한 표현식으로 나타낸다. 인수를 이용한 표현식 부분이 자동으로 리턴된다.
  • id(object) : 주소값 리턴
  • sortedziptype도 기억.
  • import os
    • os.environ: 시스템 환경변수값을 딕셔너리 객체로 리턴
    • os.chdir: 디렉토리 변경
    • os.getcwd: 현재 디렉토리 문자열 리턴
    • os.system("명령어"): 터미널에서 명령어 실행한 결과값 리턴
    • os.mkdir(디렉토리명): 디렉토리를 생성한다.
    • os.rmdir(디렉토리): 비어있는 디렉토리 삭제
    • os.unlink(파일): 파일 삭제
    • os.rename(src, dst): src 파일을 dst로 이름 변경
  • import webbrowser: 브라우저에서 URL을 연다.
    • webbrowser.open("URL")
    • webbrowser.open_new("URL")
  • import shutil -> shutil.copy("src.txt", "dst.txt") 파일 카피다. 만약 목표 디렉토리에 같은 이름의 파일이 있다면 덮어쓴다.
  • import glob -> glob.glob("/users/gyubin/dev/Q*") 지정 디렉토리의 파일명을 리스트화한다. Q*는 q로 시작하는 파일들만으로 한정한 것.
  • import tempfile 임시파일 관련 모듈이다.

9. 예외처리

9.1 에러 처리 기본

try: 
    f.open('wow.txt', 'r')
except [발생에러[as 에러메시지변수]]: # []는 생략해도 된다는 의미
    pass  # 에러 나든 말든 넘기고 싶으면 pass
else:
    pass
finally:
    f.close()
  • 에러가 날 수 있는 코드를 try에 넣고, 에러가 났을 때 처리를 except에 넣는다. 에러가 발생하지 않았을 경우 실행되는 코드는 else안에 둔다. finally는 에러가 나든 안나든 무조건 실행해주는 코드로 주로 파일 스트림 객체를 닫는데 쓰인다.
  • []는 생략해도 된다는 의미다. 그냥 except만 적어도 되고, 에러를 명시해줘도 되고, 그 에러를 내 입맛에 맞게 바꿔불러도 된다.
try:
    4 / 0 
except ZeroDivisionError as e: 
    print(e)
# => 출력: division by zero

9.2 에러 일으키기 raise

다음은 Bird 클래스를 상속하는 자식 클래스는 무조건 fly 메소드를 오버라이드 해야한다는 의미의 코드다.

class Bird:
    def fly(self):
        raise NotImplementedError

class Eagle(Bird):
    pass

eagle = Eagle()
eagle.fly()

class Eagle(Bird):
    def fly(self):
        print("very fast")

eagle = Eagle()
eagle.fly()

10. 패키지

10.1 기본

복잡한 혹은 큰 규모의 파이썬 프로그램이라면 패키지를 만들어서 관리하는게 유용하다. 예를 들어 다음과 같은 구조가 있다. 아래 패키지에서 echo.py 모듈을 사용하려면

game/
    __init__.py
    sound/
        __init__.py
        echo.py
        wav.py
    graphic/
        __init__.py
        screen.py
        render.py
    play/
        __init__.py
        run.py
        test.py
  • (O) import game.sound.echo -> game.sound.echo.echo_test()
  • (O) from game.sound import echo -> echo.echo_test()
  • (O) from game.sound.echo import echo_test -> echo_test()
  • (-) import game -> 디렉토리를 import하면 game 디렉토리의 __init__.py의 내용만 참조 가능
  • (X) import game.sound.echo.echo_test 이건 에러난다. 이렇게 .으로 구분해서 디렉토리의 모듈을 import할 땐 마지막에 무조건 패키지나 모듈이 되어야 한다. 저렇게 함수가 들어가면 안된다.

하지만 디렉토리 자체를 import할 순 없다. 예를 들어 import game 한 후에 from game.sound.echo import echo_test 사용은 불가하다. 이렇게 디렉토리를 import 하는 경우는 __init__.py의 내용만 가져온다.

10.2 __init__.py에 대하여

해당 디렉토리가 패키지의 일부라는 것을 나타내주는 것이다. 이거 없이 패키지를 import하면 에러난다. 파이썬3에선 없어도 되는걸로 바뀌었지만 그래도 하위호환성을 위해 해주는게 좋다. 이 안에 all같은 필요한 몇가지 요소들을 적어준다.

10.3 __all__

from game.sound import * 이렇게 코드를 짜면 sound 패키지의 모든 모듈을 import한다는 의미다. 이 때 __init__.py에 __all__ 이 있어야 정상적으로 작동한다. __all__ = ['echo'] 이렇게 리스트 안에 모듈명을 문자열로 집어넣어주면 된다.

물론 from에서 마지막이 패키지로 끝나는 경우에 위의 작업이 필요한것이지 만약 from에서 마지막이 모듈로 끝난다면 그냥 import * 해도 속한 모든 메소드들이 호출 가능해진다. 하지만 이는 좋은 방법이 아니다.

'파이썬' 카테고리의 다른 글

파이참(pycharm) 단축키 정리  (0) 2021.09.15
정규표현식(Regular Expression)  (0) 2018.04.09
Jupyter Notebook이란?  (0) 2018.04.03
iterator, generator 사용법  (0) 2018.04.03
decorator(wrapper) 사용법  (0) 2018.04.03