TigerCow.Door


안녕하세요. 문범우입니다.

이번 포스팅에서는 파이썬에서 사용되는 컴프리헨션(Comprehension)이라는 개념에 대해서 알아보도록 하겠습니다.



1. 컴프리헨션(Comprehension)이란?


일단, 파이썬에서 사용되는 Comprehension이 무엇인지 알아보기 전에, 어떤 의미를 가지고 있는 단어인지 살펴보았습니다.

사전적으로는 이해, 이해력, 포용, 포용력, 포함, 압축 등의 뜻을 가지고 있습니다.

단순히 이런 의미로는 대체 어떻게 파이썬에서 사용되는지 감이 쉽게 안오실텐데, 하나씩 천천히 살펴보시면 충분히 이해하실 수 있을 것입니다.


앞으로 알아보는 Comprehension을 보다 제대로 이해하기 위해서는 기본적으로 파이썬의 조건문, 반복문 등의 개념을 알고 있으셔야 하며 해당 개념은 리스트, 집합(set), 딕셔너리(dictionary) 자료형에 대해 사용될 수 있기 때문에, 해당 자료형에 대해서도 알아야 제대로 이해할 수 있습니다.


2. List, Set, Dict Comprehension


먼저 알아볼 내용은 List, Set, Dict 자료형으로 사용되는 Comprehension입니다.

사용되는 방법이나, 문법등은 동일하나 어떤 자료형에 적용시키는지에 따라 다르기 때문에, 대표적으로는 리스트자료형으로 Comprehension을 알아보도록 하겠습니다.


List Comprehension은 쉽게 생각하면, 반복되거나 특정 조건을 만족하는 리스트를 보다 쉽게 만들어 내기 위한 방법입니다.



2-1. 반복문을 사용한 Comprehension


실제로 어떻게 사용되는지 먼저 간단한 예제를 통해 확인해보겠습니다.



위의 코드를 보시면 총 3번의 Comprehension이 사용되었습니다.

그 동안 우리는 특정 리스트를 생성하기 위해서 직접 값을 넣어주거나, 기타 다른 함수들을 이용했지만 Comprehension이라는 개념을 사용하면 위와 같이 쉽게 리스트를 생성할 수 있습니다.


첫번째 코드, [i for i in range(10)] 은 사실상 단순히 range()를 이용해도 되지만, Comprehension이 어떻게 사용되는지를 보여드리기 위해 보여드렸습니다.



2-2. 조건문을 사용한 Comprehension


위에서 살펴본 것은 반복문을 사용한 Comprehension 이며 반복문 이외에도 조건문을 추가로 이용하여 리스트를 생성할 수 있습니다.



위와 같이, 반복문과 조건문을 함께 사용하여 리스트를 생성한 모습입니다.


먼저 반복문을 적어주고, 반복문의 인자가 뒤에 적어준 조건문에 해당하는지를 확인하여 그 인자를 리스트의 요소로 가지게 되는 것입니다.


또한, 위에서 사용한 반복문이나 조건문을 여러개 이용하는 것도 가능합니다.

이때, 여러번 사용되는 반복문은 각각이 개별적으로 돌아가는 것이 아니고 조건문은 서로 and연산으로 묶인다고 생각하시면 됩니다.

아래 예시들을 통해 확인해보도록 하겠습니다.



2-3. 두 개의 반복문 사용하기


먼저, 두개의 반복문이 사용된 예제입니다.



먼저 반복문이 어떻게 돌아가는지 보다 잘 확인하기 위해 a,b,c,d,e 를 가진 리스트 a와 1,2,3,4,5를 가진 리스트 b를 만들어 주었습니다.

그리고 [i+j for i in a for j in b] 라는 Comprehension 구문으로 새로운 리스트를 생성해보았습니다.

해당 결과를 보면 먼저 앞의 for문에서 하나의 요소에 대해 뒤의 for문을 적용하는 방식임을 확인할 수 있습니다.

보다 쉽게 보자면, 아래와 같은 것임을 알 수 있습니다.



위의 코드를 보시면, 우리가 전에 알던 for문의 문법을 이용하여 a, b 리스트에 있는 요소를 하나씩 꺼내어 새로운 리스트에 삽입하는 방식으로 결과를 확인해보았습니다.



2-4. 두 개의 조건문 사용하기


이번에는 두개의 조건문이 사용된 예제를 확인해보도록 하겠습니다.



위의 결과를 보시면 0~49의 범위에서 2로 나눴을 때 0이며, 3으로 나눴을 때 0인 요소로 새로운 리스트가 생성된 것을 확인할 수 있습니다.

즉, 우리가 적어준 두개의 조건문이 서로 and로 묶인 것을 알 수 있습니다.



2-5. 조건문에서 else 사용하기


물론 우리가 사용하는 조건문에 대해서 if 이외에 else도 함께 사용할 수 있습니다. 하지만 else if (elif)는 사용할 수 없습니다.



위의 코드의 첫번째 줄에서 볼 수 있듯이 if와 else를 함께 사용할 수 있습니다.

0~9의 숫자에 따라서 2로 나누어 떨어지면 'even'을, 그게 아니면 'odd'를 출력하게 한 구문 입니다.

하지만 그 아래줄에서 0인 숫자에 대해서는 zero를 출력하도록, elif를 사용해보았지만 오류가 발생합니다.


그렇지만, else를 사용할 수 있기때문에 elif를 직접적으로 사용할 수는 없지만, 개념적으로 elif와 동일한 구문을 사용할 수는 있습니다.



2-6. 조건문에서 elif 사용하기



위와 같이 else 뒤에서 if를 한번 더 사용함으로써, elif와 같은 기능을 갖는 구문을 만들 수 있습니다.

첫 번째 줄에서는 0이 2로 나누어떨어진다고 보기 때문에 맨 앞에 있는 if 문에 걸려 even을 출력하게 되었습니다. 이를 수정하여 두번째 코드와 같이 작성하면 우리가 기대한 값이 출력됨을 볼 수 있습니다.

물론 이러한 경우에도 else를 여러번 중복하여 사용할 수 있습니다.



위의 코드에서는 0~9의 숫자에 대해서, 1일때는 'one', 2일때는 'two', 3일때는 'three', 4일때는 'four'를 출력하도록 여러개의 else와 if를 사용하였습니다. 그리고 그외에는 'hum'을 출력하도록 설정하였습니다.



3. Generator Expression


이번에는 Generator Expression에 대해서 알아봅니다.

지금까지 Comprehension에 대해서 알아보다가 갑자기 다른 주제라서 당황하셨나요?

하지만 Generator Expression도 Comprehension를 사용한 기능 중에 하나입니다.


처음에, Comprehension도 리스트말고도 {}를 사용하는 집합 자료형과 키와 값을 이용한 딕셔너리 자료형에서도 이용할 수 있다고 말씀드렸습니다.

그리고 이와 비슷하게, ()를 사용하면 Generator Expression이 되는 것 입니다.

표현하는 방법 자체는 위에서 알아본 Comprehension과 동일하니 어떻게 사용되는 것인지만 예제를 통해서 알아보도록 하겠습니다.



먼저 a와 b에 우리가 위에서 알아본 Comprehension 의 구문과 소괄호, ()를 이용하여 정의하였습니다. 그리고 각각을 print해보니 generator 객체가 나왔습니다.

이처럼 Comprehension 구문을 사용하여 소괄호로 묶어주면 자동적으로 파이썬에서 generator expression으로 인식하여 generator 객체를 생성하게 됩니다.

이를 사용하기 위해서는 해당 generator객체를 next로 감싸서 출력해주면 됩니다.


우리가 Comprehension를 통해 기대하는 값들이 순서대로 하나씩 출력되는 것을 볼 수 있습니다. 그리고, 모든 값에 대해 한바퀴를 돌게 되면 아래와 같이 Stop Iteration 이라는 오류를 출력하게 됩니다.




4. Comprehension 정리


우리는 위에서 Comprehension에 대해서 알아보았습니다.

그 구문과 사용법을 익히면, list, set, dict과 같은 자료형에서 다양하게 사용될 수 있으며, 소괄호를 이용하여 generator 객체를 만들어 이용할 수도 있습니다.

이러한 구문이 나왔을 때 당황하지 않고 리딩할 수 있어야 하며, 필요할때는 적극적으로 이용할 수 있어야 하기 때문에 꼭 한번씩 인터프리터등을 이용해 연습해보시기를 추천드립니다.

마지막으로 Comprehension 구문에 대해서 총정리를 해보면, 아래와 같습니다.




블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 파이썬에서 사용되는 언더스코어(_)에 대해서 정리해보고자 합니다.

언더바라고도 읽는, ' _ ' 와 같은 표시를 언더스코어라고 하는데 이것이 파이썬에서는 보다 특별한 의미를 가지고 사용되는 경우가 있습니다. 어떤 의미로 어떻게 사용되는지 하나씩 알아보도록 하겠습니다.


1. 값을 무시하고 싶은 경우


제일 먼저 알아볼 경우는 값을 무시하고 싶은 경우입니다. 물론 쓰레기 변수를 만들어서 사용해도 되겠지만 언더스코어를 사용하는 경우 더 깔끔하고, 코드를 확인할 때 사용하지 않는 값임을 나타내기 때문에 보다 직관적일 수 있다고 생각합니다.

사실상, 값을 무시하는 경우가 언제 필요할까? 라는 생각이 드시는 분도 있겠지만 간단하게는 아래와 같은 코드에서 값을 무시할 경우가 생깁니다.



예제가 깔끔한지는 의문이 들지만..

대략 무슨 느낌인지 아시겠나요?

우리가 for 문을 사용할때 지정되는 인덱스가 굳이 필요 없을때가 있습니다. 이럴때 언더스코어를 사용하며 또는, 우리가 함수 등에서 한번에 두개의 값을 반환받을 때 둘 중 하나의 값만 이용하고 싶다면, 아래와 같이 사용할 수 있습니다.



즉, 우리가 원래 변수로 사용하던 곳에 대신하여 언더스코어( _ )를 사용하면 그 값은 무시하게 되는 것 입니다.



2. 숫자 자리수 구분을 하는 경우


숫자의 자리수 구분으로 사용하는 경우는 간단합니다. 우리는 보통 1000 대신 1,000와 같이 반점을 이용해 숫자를 세자리씩 구분하는데 이러한 역할이라고 생각하면 됩니다.




3. private으로 선언하고 싶은 경우


이번에는 private으로 선언하고 싶은 경우입니다. 물론 변수/메소드/클래스 등 모든 것을 포함하는데, 사실상 이는 private 이라고 보기에는 약간 애매할 수 있습니다.

예들 들어, 아래와 같이 함수와 변수를 선언했다고 생각해보겠습니다.


물론 이후에, _hello() 함수를 실행시키거나 _private_var를 출력해도 결과가 올바르게 나옵니다. 그럼 무엇때문에 private 선언이라고 하느냐?

예를 들어, 위의 코드를 hello.py 라는 이름으로 저장하고, 다른 파일에서 이를 불러온다고 생각해봅시다.

그럼 우리는 from hello import * 와 같은 식으로 모듈을 불러오게 됩니다.

하지만, 이때 언더스코어( _ )로 시작된 함수나 클래스, 변수는 사용할 수 없게됩니다. 사용할 수 없다기보다 불러와지지 않는다는 말이 맞을듯 합니다.

즉, 외부에서 모듈을 불러올때 언더스코어로 시작된 변수나 함수, 클래스는 사용하지 못하는 것입니다.

하지만.. 이 또한 사용할 수 있는 방법이 있기는 있습니다.

import 를 할때 * 를 사용해서 하는 것이 아니고, 직접 함수나 변수명을 언급하여 import를 하면 사용할 수 있게됩니다.


완벽하게 private이라고 볼 수는 없겠지만, 숨기고 싶은 함수나 변수, 클래스를 만들때는 직관적으로라도 이해하기 위해 언더스코어를 사용하여 네이밍하는 것이 좋을 것 같습니다.



4. 중복된 이름을 피하고 싶은경우


이는 맹글링을 사용한다고 표현하기도 합니다.

맹글링이란 프로그래밍 언어 자체적으로 가지고 있는 규칙에 의해서 함수나 변수의 이름을 변경하는 것을 말합니다. 즉, 파이썬에서 가지고 있는 규칙에 의해서 우리가 네이밍한 변수나 함수의 이름을 변경하는 것 입니다.

위와 같이 코드가 구현되었을 때, A 클래스와 B 클래스의 두개의 함수명이 서로 같습니다. 물론 잘 구분해서 사용한다면 문제가 없겠지만, 코드가 복잡해지고 변수이름이 다양해졌을때에는 충분히 헷갈릴 수 있게됩니다.

이럴때 각 클래스에 대해서 중복된 함수명을 우리가 만들더래도, 맹글링을 통해 알아서 구분되는 함수명으로 변경시키기 위해 더블언더스코어( __ )를 사용합니다.

즉, 다음의 코드와 같습니다.

위와 같이, 함수를 네이밍할때 그 앞에 더블언더스코어( __ )를 사용하였습니다.

그리고 각 함수를 호출하기 위해서는 하단에서 보이는 것처럼 _<클래스명><함수명>과 같이 호출해야 합니다.

즉, 같은 함수명을 가졌더라도 함수를 호출할 때 직접적으로 클래스명을 언급해주어야 하므로 코드를 이해할때 보다 직관적으로 이해할 수 있습니다.



+ 인터프리터에서 사용할 때


마지막으로 알아볼 것은 언더스코어를 인터프리터에서 사용할 때 입니다.

인터프리터에서는 마지막 변수의 값을 일시적으로 가지고 있는 용도로 사용됩니다.


위와 같이, 마지막으로 실행된 결과 값이 언더스코어에 저장되는 것을 볼 수 있습니다.

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 정규표현식에서 사용되는 메타문자에 대한 총정리를 해보려 합니다.

지난 포스팅에서 기본적인 메타문자들을 정리해보았는데, 그 내용들을 포함해서 함께 정리해보도록 하겠습니다.

정규표현식에 대해 조금 더 궁금하신 분들은 아래의 포스트를 참고해주시길 바랍니다 :)


정규표현식이란? (1)


정규표현식이란? (2)



1. 백슬래시(\)


우리가 메타문자에 대해 총 정리를 하기 앞서서, 정규표현식을 사용할 때 혼란이 될 수도 있는 백슬래시(\)에 대해서 잠깐 이야기해보겠습니다.

먼저 백슬래시는 보통 자판의 엔터위에 있는 버튼을 통해 입력할 수 있습니다.


우리가 정규표현식을 이용하여 TEST라는 파일에서 "\section" 이라는, 백슬래시를 포함한 문자열을 찾으려고 한다고 생각해봅시다.

그럼 다음과 같은 정규식을 만들수 있습니다.


p = re.compile("\section")

 

하지만 위의 정규식은 백슬래시를 이용한 \s 문자가 whitespace로 해석되어 우리가 원하는 문자열을 찾지 못하게 됩니다.

그럼 어떻게 해야 할까요? 바로, 이스케이프 처리를 함으로써 백슬래시가 문자열 자체로 인식되게끔 해야 합니다.

바로 백슬래시 하나를 더 이용하는 건데요, 아래와 같이 코드를 구현하면 됩니다.


p = re.compile("\\section")


즉 위와 같이 코드를 구현하면, 파이썬 정규식 엔진에서는 파이썬의 특정 규칙에 의하여 \\ 를 \ 로 해석하게 됩니다.


* 이러한 문제는 정규식을 파이썬에서만 사용할 때 생기는 문제입니다.


그런데 만약 우리가 백슬래시 두개가 연속으로 포함된 문자열을 탐색하려면 어떻게 할까요? 위와 같은 방법으로 생각해본다면 다음과 같이 코드를 구현할 수 있을 것입니다.


p = re.compile("\\\\section")


하지만 너무 복잡하지 않나요?

이러한 문제 때문에 파이썬에서는 Raw String 이라는 것이 생겨나게 되었습니다.

이는 아래와 같이 사용할 수 있습니다.


p = re.compile(r'\\section')


이와 같이 파이썬에서는 정규식 문자열 앞에 r 을 붙여줌으로써 백슬래시 1개를 두개로 인식하게끔 할 수 있습니다.



2. 메타문자 총 정리


- []


먼저 알아볼 것은 문자 클래스 [] 입니다.

문자 클래스로 만들어지는 정규식은, [와 ]로 둘러쌓인 내부의 문자열과 매치되는 것이라는 의미를 가집니다.




또한 자주 사용되는 문자클래스는 아래와 같이 별도의 표기법으로 사용될 수 있습니다.



문자클래스 내부에서 쓰이는 ^ 는 뒤에서 알아볼 메타문자와는 다른의미인, not의 의미를 가지고 있습니다.





- . (Dot)


.(Dot) 은 줄바꿈 문자인 \n을 제외한 모든 하나의 문자와 매치되는 것을 의미합니다.





- *


*는 반복을 나타내는 메타문자로써, 해당 메타문자 앞의 글자가 0번이상 반복되는 모든 문자열과 매치됩니다.




- +


+는 *과 같은 반복을 나타내는 메타문자입니다. *는 다르게 앞의 글자가 0번을 제외한, 1번이상 반복되는 모든 문자열과 매치됩니다.


 


- {m,n}


{m,n}또한 반복을 나타내는 메타문자입니다. 위와는 다르게 반복횟수를 m과 n으로 정할 수 있습니다. 즉, 앞의 문자가 m번 이상 n번이하 반복되는 모든 문자열과 매치 됩니다.




- ?


? 는 앞의 문자가 0~1번 반복되는 모든 문자열과 매치됩니다.




- |


| 는 보통 키보드의 엔터키위에 있는 키입니다. 백슬래시로도 사용되는 키인데 shift와 함께 눌러주면 됩니다.

해당 | 메타문자는 a|b 와 같은 형식으로 사용되며 a 또는 b와 매치되는 문자열을 반환합니다.




- ^


^는 문자열의 맨처음을 의미하는 메타문자입니다. 문자클래서 내부에서 not의 의미로 사용되기도 하므로 혼동되지 않도록 주의하세요. 정규식으로 찾고자 하는 문자열의 앞에 입력합니다.





- $


$는 ^와 반대로 문자열의 맨 마지막을 의미하는 메타문자 입니다. ^와는 다르게 매치할 문자열의 뒤에 입력합니다.





- \A


\A는 기본적으로 ^와 같이 문자열의 맨 처음을 의미하는 메타문자입니다. 하지만 다른점이 있다면 우리가 re.MULTILINE이라는 컴파일 옵션을 사용했을때 ^는 라인별 문자열의 맨처음을 의미하지만 \A는 라인별이 아닌 문자열 전체에서의 맨 처음을 의미합니다.



- \Z


\Z는 기본적으로 $와 같이 문자열의 맨 뒤를 의미하는 메타문자입니다. 하지만 다른점은 \A와 같이, re.MULTILINE이라는 컴파일 옵션을 사용했을때 $는 라인별 문자열의 맨뒤를 의미하지만 \Z는 라인별이 아닌 문자열 전체에서의 맨 뒤를 의미합니다.



- \b


\b는 단어구분자로 사용됩니다. 즉, 해당 메타문자는 단순히 단어로 찾고자할 때 사용되는 메타문자입니다.




- \B


\B는 \b와 반대로 단어가 아닌 문자열을 찾는데 사용되는 메타문자입니다.





이렇게하여 많이 사용되는 메타문자들을 정리해보았습니다.

추후 메타문자에 대해서 추가적인 내용이나, 더 필요한 내용이 있다면 속해서 수정하도록 하겠습니다.

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요.

이번 포스팅에서는 파이썬에서 정규 표현식을 지원하는 re모듈, 정규식을 이용한 문자열 검색과 정규식 컴파일 수행시 가능한 옵션에 대해서 알아보도록 하겠습니다.

지난 포스팅에서도 말씀 드렸듯, 정규표현식은 단순히 파이썬에서만 사용되는 것이 아닙니다. 기본적인 정규표현식을 익혀두시면 그 쓰임새는 무궁무진하며, 단순히 프로그래밍 언어에 따라 사용법만 약간의 차이가 있을 뿐 입니다.



1. re 모듈


파이썬에서는 정규 표현식을 사용하기 위해 re(regular expression) 모듈을 제공합니다. 파이썬이 설치될 때 함께 설치되는 라이브러리로 단순히 import 하여 사용할 수 있습니다.


import re


그리고 re모듈을 이용하여 우리가 작성하는 정규표현식을 컴파일합니다.

여기서 컴파일한다는 의미를 쉽게 생각해본다면, 우리가 작성한 정규표현식을 이해하라고 명령을 내린다고 생각해 볼 수 있습니다.

예를 들어서, 아래와 같이 코드를 작성했다고 생각합니다.


1
2
import re
= re.compile('[a-z]')
cs


1번 줄에서 re 모듈을 불러 왔고, 2번 줄에서 re모듈의 compile함수를 사용합니다. 그리고 해당 함수의 인자로 정규표현식을 넣어주었습니다.

이렇게 하면 정규식을 컴파일한 '패턴'이라는 객체가 나오게 됩니다.

즉, p는 [a-z]라는 정규식을 이해한 객체, 패턴이 되는 것입니다.

그리고 우리는 해당 객체 (위에서는 p)를 이용하여 문자열 검색을 수행할 수 있습니다.



2. 문자열 검색하기


정규식을 컴파일한 패턴 객체를 이용한 문자열 검색을 하는데 총 4가지의 메서드가 제공됩니다.


 Method

목적 및 기능

 match()

 문자열의 처음부터 정규식과 매치(일지)하는지 확인한다.

 search()

 문자열 전체를 검사하여 정규식과 일치하는지 확인한다.

 findall()

 정규식과 매치되는 모든 문자열(substring)을 리스트로 반환한다.

 finditer()

 정규식과 매치되는 모든 문자열(substring)을 iterator 객체로 반환한다.


이때, match()와 search()는 정규식과 매치될 때, match 객체를 반환하고 그렇지 않을 때는 None을 반환합니다.


하나씩 코드를 보며 확인해보도록 하겠습니다.



- match()


위에서 언급했던 것 처럼, match() 함수는 문자열에 대해 처음부터 검사하여 정규식과 매치될 때 match 객체를 반환하고 그렇지 않으면 None을 반환합니다.

이때, match 객체로 반환되었다면 group() 함수를 통해 매치된 문자열을 확인할 수 있습니다.

match는 search와 다른점을 구별하기 위해서, match 는 문자열의 처음부터 검사한다는 것을 기억하시길 바랍니다.



위의 코드에서와 같이, 먼저 p 에 정규식 '[a-z]+' 을 컴파일 하였습니다.

그리고 총 3개의 테스트를 진행해보았습니다.


첫번째 테스트에서는 itsfine 이라는 문자열 모두가 정규식에 매치되어 그대로 반환되었습니다.

두번째 테스트에서는 3이라는 숫자로 시작하는 문자열이기 때문에 애초 3부터 정규식과 매치되지 않아 None을 반환하였고, None에 대해 group() 함수는 오류를 발생시킵니다.

세번째 테스트에서는 중앙에 있는 숫자 4의 위치전까지의 what 이라는 문자열이 정규식에 매치되어 그 값을 반환할 수 있었습니다.



- search()


search() 함수는 문자열 전체를 검사하여 정규식과 매치되는지 확인합니다.

match() 함수와 거의 동일하지만, match 는 문자열 처음부터 검사하고, search는 문자열 전체를 검사하는 차이가 있습니다.

이 차이가 실질적으로 어떤 차이가 있을지 코드를 통해 확인해보도록 하겠습니다.



위에서 확인해본 match() 함수에서 사용한 코드에서 단순히 검색 메소드를 search() 로 바꾸어보았습니다.

아까는 오류가 났었던 두번째 테스트에서 fail을 잘 반환해주고 있습니다.

즉, match() 함수는 문자열 처음부터 검색을 시작하다가 정규식과 매치되지 않는 문자열이 발견되면, 검색을 멈추고 지금까지 매치된 것을 반환하게 됩니다.

이와 다르게 search() 함수는 정규식과 매치되지 않는 문자열이 발견되더라도 지금까지 매치된 문자열이 없으며 탐색을 계속합니다. 세번째 테스트에서 확인할 수 있듯이, 매치되지 않는 문자열이 발견되었는데, 그 전에 매치된 문자열이 있었다면 match() 와 동일한 행동을 취하게 됩니다.



- findall()


이번에 알아볼 함수는 문자열 전체에서 정규식과 매치되는 모든 문자열을 리스트로써 반환하는 findall() 함수 입니다.

위에서 확인했던 테스트들과 동일한 값으로 테스트를 진행해보았습니다.



차이점이 보이시나요?

일단 findall() 함수는 특정 객체가 반환되는 것이 아니고, 정규식과 일치되는 모든 문자열을 리스트로 묶어서 반환해주기 때문에 group() 과 같은 함수를 사용할 필요가 없습니다.

또한 세번째 테스트를 확인해보면 match() 와 search()에서는 반환되지 않았던 'o'가 반환되는 것을 볼 수 있습니다.



- finditer()


finditer() 함수는 findall() 함수와 기능적으로 동일하지만 반환하는 형태가 다릅니다.

코드를 통해 어떻게 다른지 확인해보겠습니다.


위의 코드를 보시면, finditer() 함수는 findall() 함수와 같이 정규식과 매치되는 모든 문자열을 반환하지만 리스트형이 아닌 iterator객체로 반환합니다.

이를 확인하기 위해서 for 문을 이용하였고, 세번째 테스트를 보시면 그 결과를 확인할 수 있습니다.

해당 iterator 객체에서 문자열을 꺼내기 위해서는 match() 와 search() 에서 이용했던 group() 함수를 이용하면 됩니다.



+ 모듈로 한번에 실행하기


지금까지 우리는 아래 두줄의 코드와 같이 p 라는 것을 re.compile() 에 대한 객체로 두고, 해당 객체를 통해 검사 메소드를 실행시켜 m 객체를 얻었습니다.


p = re.compile('[a-z]+')

m = p.match('hello')


하지만 단순히 모듈에서 실행할 수 있는 방법이 있습니다. 즉, 위의 두줄 코드를 한줄로 줄일 수 있는 방법입니다.


m = re.match('[a-z]+', 'hello')


이와 같이 작성해도 위에서와 같은 결과를 반환합니다.

물론, match 이외의 나머지 함수또한 동일한 방법으로 사용가능합니다.



3. 컴파일 옵션


우리는 위에서 정규식을 컴파일하고, 특정 함수들의 특징에 따라 문자열에 대해 검색하는 방법에 대해서 알아보았습니다.

추가적으로 알아볼 내용은, 정규식을 컴파일할 때 추가할 수 있는 옵션들에 대해서 입니다.

추가할 수 있는 옵션으로는 총 4개가 있습니다.

옵션을 사용하는 방법으로는, 컴파일 함수에 두번째 인자로 옵션값을 입력해주면 됩니다.

예를 들어,


p = re.compile('[a-z]+', DOTALL)


과 같은 식으로 DOTALL 옵션을 사용할 수 있습니다. 이후 검색메소드를 사용하는 등의 행위는 그전과 동일합니다.


하나씩 천천히 알아보도록 하겠습니다.



- DOTALL or S


우리가 지난 포스팅에서 메타문자에 대해서 알아볼 때, dot( . )이라는 메타문자는 줄바꿈(\n) 을 제외한 모든 문자에 대한 의미라고 설명드렸습니다.

이때, 줄바꿈 조차 포함을 하기 위해서는 DOTALL 또는 S 컴파일 옵션을 사용하면 됩니다.


ex)

p = re.compile('[a.b]', re.DOTALL)

또는

p = re.compile('[a.b]', re.S)



- IGNORECASE or I


해당 옵션은 문자의 대소문자를 무시하는 옵션입니다.

즉, 원래대로라면 알파벳에서 대소문자 모두를 포함한 문자열을 의미하는 정규식은, '[a-zA-Z]' 이었겠지만, 해당 옵션을 사용하면 단순히 '[a-z]' 를 사용해도 됩니다.


ex)

p = re.compile('[a-z]', re.IGNORECASE)

또는

p = re.compile('[a-z]', re.I)



- MULTILINE or M


해당 옵션은 우리가 추후에 더 알아볼 메타문자 ^ 와 관련이 되어 있습니다.

옵션에 대한 설명을 위해 간단히 말씀드리면, 메타문자 ^ 는 문자열의 처음(시작)을 의미합니다. 즉 정규식 '^hello' 라고 한다면, hello 로시작하는 문자열을 의미하는 것입니다.

그런데 일반적으로 '^hello\s\w+' 라는 정규식을 이용하면

'''

hello python

Im beomwoo

hello everyone

'''

과 같은 여러개의 줄로 이루어진 문장에 대해서 첫번째 문장인 hello python 만을 반환하게 됩니다. findall() 함수를 사용해도 첫번째 문장만 반환하게 되는데 그 이유는 위의 문단이 결국 'hello python\nIm beomwoo\nhello everyone' 과 같은 문장이기 때문입니다.

이때 MULTILINE 옵션을 사용하면 각 문장에 대해서 정규식에 대해 검색을 진행합니다.

즉, MULTILINE을 사용한 컴파일에서 findall 메소드를 사용한다면 위의 문단이 반환하는 리스트는, ['hello python', 'hello everyone'] 이 될 것입니다.


ex)

p = re.compile('^hello\s\w+', re.MULTILINE)

또는

p = re.compile('^hello\s\w+', re.M)



- VERBOSE or X


해당 옵션은 특정 기능에 대한 것이라기 보다는 정규식을 보다 시각적으로 좋게 보기 위한 옵션입니다.

예를 들어서,

charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);')

이러한 정규식이 있다고 생각해봅시다. 아직 우리가 정규식에 대해 100% 공부를 하고 이해가 된것이 아니라는 것을 감안해도, 해당 정규식을 제대로 이해하기 어려운 부분이 있습니다. 하지만 VERBOSE 또는 X 정규식을 사용하면, 아래와 같이표현이 가능합니다.


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)

아직 우리는 이렇게 되어있어도 이해가 어려울 수 있지만 나중에 정규식을 더 공부하고나면 위의 코드가 더 이해하기 편할 것입니다. 또한 # 을 통해 주석을 쓸 수 있기 때문에, 보다 쉽게 코드를 이해할 수 있습니다.



이렇게 해서 정규식에 대한 두번째 포스팅을 진행하였습니다.

이번 포스팅에서는 정규식에서 사용되는 4가지 메소드와 4가지 컴파일 옵션에 대해서 알아보았습니다.

추가적으로 궁금한 사항은 댓글 및 이메일을 이용해주세요 :)

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

지난 포스팅에서 파이썬의 내장 및 외장함수까지 알아보며 파이썬에 대한 전체적인 설명은 마무리 된 것 같습니다.

추가적으로 이번 포스팅에서는 정규 표현식이라는 개념에 대해서 알아보려고 합니다.

정규 표현식은 파이썬 이외에도 많은 곳에서 사용될 수 있습니다.


1. 정규 표현식(Regular Expressions)이란?


정규 표현식(Regular Expressions)은 복잡한 문자열을 처리할 때 사용하는 기법입니다. 위에서도 말씀드렸듯, 파이썬 만의 고유 무법이 아니라 문자열을 처리하는 모든 곳에서 사용되는 것입니다. 즉, 정규표현식을 배우는 것과 파이썬과의 직접적인 연관은 크게 없습니다.

정규 표현식은 고급 주제이기 때문에 아직 프로그래밍이 익숙하지 않으신 분들에게는 많이 어려울 수 있습니다.


정규식이라고도 불리는 정규표현식은 왜 필요할까요?

아래의 간단한 예제를 보면 쉽게 이해할 수 있을 것입니다.

다음과 같은 문제가 주어졌다고 가정합니다.


- 주민등록번호를 포함하고 있는 텍스트가 있다. 이 텍스트에 포함된 모든 주민등록번호의 뒷자리를 * 문자로 변경하시오.


먼저, 정규식을 몰랐다고 했을 때 여러개의 조건을 활용하여 위의 문제를 해결하기 위한 코드를 작성한다면 다음과 같을 것입니다.



이와 다르게, 정규식을 사용한다면 아래와 같은 코드를 통해 문제를 해결할 수 있습니다.



아직 정규식에 대해 제대로 배우지 않았으니 간편히 코드만 어떤느낌인지 보시면 됩니다.

이렇게 간단한 문제 하나를 비교해보아도 한눈에 보이는 것은 코드의 복잡성입니다.

정규식으로 해결한 코드는 코드가 매우 간단하고 직관적으로 보입니다.

문자열에 대해 우리가 보다 복잡한 문제가 주어졌을때 정규식은 보다 큰 효용성을 보여줄 것입니다.

그리고 이러한 것이 우리가 정규표현식을 배우고, 알아야 할 이유와 같습니다.



2. 정규 표현식의 기초, 메타 문자


먼저 정규 표현식에서는 메타 문자라는 것을 사용 합니다.

메타문자란, 원래 그 문자가 가진 뜻이 아닌 특별한 용도로 사용되는 것을 이야기 합니다.

정규 표현식에서 사용되는 메타 문자(meta characters)는 다음과 같은 것들이 있습니다.


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


그럼 하나씩 알아보도록 하겠습니다.


먼저, 문자 클래스 [ ]

우리가 가장 먼저 살펴볼 메타 문자는 문자 클래스(character class)인 [ ] 입니다.

문자 클래스로 만들어진 정규식은 [ 과 ] 사이의 문자들과 매치하는 것 이라는 의미를 가집니다.

즉, [abc] 라는 정규 표현식이 있다면 해당 표현식의 의미는 'a, b, c 중 한개의 문자와 매치되는 것'이라는 의미를 가집니다.

예를 들어 본다면 [abc]는 문자열 "a", "before"와 매치되며 "dude"와는 매치되지 않습니다.


그리고 문자클래스 [ ] 안에서 하이픈(-)을 사용하게 되면 범위를 말하게 됩니다.

즉, [0-4] 는 [01234]와 같은 의미의 정규표현식이며 [a-e] 는 [abcde]와 같은 의미의 정규표현식 입니다.


또한 자주 사용되는 문자 클래스는 아래와 같이 별도의 표기법으로 표현할 수도 있습니다.


별도 표기법

정규 표현식

설명

\d

[0-9] 

모든 숫자와 매치되는 의미 

\D

[^0-9]

숫자가 아닌 것과 매치됨을 의미

\s

[ \t\n\r\f\v]

whitespace 문자와 매치되는 것을 의미

\S

[^ \t\n\r\f\v]

whitespace 문자가 아닌 것과 매치됨을 의미

\w

[a-zA-Z0-9]

문자+숫자와 매치 되는 것을 의미 

\W

[^a-zA-Z0-9]

문자+숫자가 아닌 것과 매치됨을 의미



두번째로, Dot(.)

정규 표현식의 Dot(.) 메타 문자는 줄바꿈 문자인 \n을 제외한 모든 문자와 매치됨을 의미합니다.

즉, a.b 는 a와 b사이에 줄바꿈 문자를 제외한 어떤 문자가 들어가도 모두 매치되는 것입니다.

하지만 주의할 점은 a와 b 사이에 어떤 문자라도 하나 이상은 꼭 들어가야 매치 됩니다.

예를 들어보면, a.b 정규식과 "aab"와 "a0b"는 매치되지만 "abc"는 매치되지 않습니다. 문자 a와 b 사이에 어떤 문자가 최소 하나 존재하지 않기 때문입니다.


추가적으로, a[.]b 라는 정규식은 "a.b"와 매치되는 정규식입니다.



세번째, 반복(*)

go*gle 이라는 정규식을 보겠습니다.

여기서 반복의 의미를 가진 메타문자 * 는 해당 메타문자 앞의 문자가 0번이상 무한대로 반복될 수 있음을 의미합니다.

즉, go*gle 이라는 정규식은, "ggle", "gogle", "google", "goooooooogle" 과 모두 매치됩니다.



네번째, 반복(+)

반복을 나타내는 메타문자는 하나 더 있습니다. 바로 + 인데 *와 다른 점은, + 메타문자는 반복 회수가 최소 1번이상이어야 합니다.

즉, go+gle 이라는 정규식에 대해 "ggle"은 매치되지 않습니다.



다섯번째, 반복({m,n})

그런데, 반복 회수를 정하고 싶다면 어떻게 해야될까요?

무한번 반복까지 매치되는 것이 아니라, 예를 들어, 3번 또는 2번만 반복되는 문자열만 매치되게 하고 싶다면?

이럴떈 { } 메타문자를 이용하면 됩니다.

{m, n} 정규식을 사용하면 반복 횟수가 m부터 n까지 인 것을 매칭할 수 있습니다. 또한 m 이나 n 둘중 하나를 생략할 수 있습니다. 즉, {,3} 이라면 반복회수가 3이하인 것을 의미합니다.

이를 통한 몇가지 예시를 보면 다음과 같습니다.

go{2}gle : 해당 정규식은 o가 반드시 2번 반복되는 문자열과 매치됩니다.

go{2,4}gle : 해당 정규식은 o가 반드시 2번이상, 4번이하 반복되는 문자열과 매치됩니다.



여섯번째, 반복(?)

마지막으로 알아볼 메타문자는 ? 입니다.

? 가 의미하는 메타문자는 {0,1} 입니다.

즉 0번~1번 반복되는 것을 의미합니다.


이렇게 해서 정규식에 대한 기본적인 개념과 몇가지 메타문자에 대해 알아보았습니다.

다음 포스팅에서는 파이썬에서 정규 표현식을 지원하는 re 모듈에 대해 알아보도록 하겠습니다.

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc



안녕하세요.

이번 포스팅에서는 파이썬의 내장함수 및 외장함수에 대해서 알아보도록 하겠습니다.


1. 파이썬 내장 함수


이번에는 파이썬의 내장 함수 몇가지에 대해서 알아보도록 하겠습니다.


여기서 언급하는 내장함수들 이외에도 매우 많은 내장함수가 있으니, 추가적으로 찾아보면서 공부하시면 좋을 것 같습니다.


all



all(x)는 반복 가능한(iterable) 자료형 x를 입력 인수로 받아서 x가 모두 참이면 True를, 거짓이 하나라도 있으면 False를 반환합니다.



any



any(x)는 반복 가능한(iterable) 자료형 x를 입력 인수로 받아서 x 중 하나라도 참이면 True를, 하나라도 없으면 False를 반환합니다.



dir



dir은 객체가 자체적으로 가지고 있는 변수나 함수를 보여줍니다. 위의 예는 리스트, 딕셔너리 자료형 객체의 관련 함수들을 보여줍니다.



eval



eval()는 실행가능한 문자열을 입력으로 받아서 그 문자열을 실행한 결과값을 반환하는 함수 입니다.

이때 실행가능한 문자열이란 위의 코드에서와 같이, 실행될 수 있는 문장이지만 문자열로 되어있는 것들을 말합니다.



input



input()은 사용자의 입력을 받는 함수 입니다. 입력 인수로 문자열을 주면 프롬프트에서 그 문자열이 출력되고 그 뒤에 이어서 사용자가 이어서 입력할 수 있게 됩니다.

또한 위 코드의 세번째 처럼 input()에 대해 변수를 지정하여 사용자가 입력한 것을 문자열로 받아 변수에 저장할 수 있습니다.



map



map(f, iterable)은 함수(f)와 반복 가능한(iterable) 자료형을 입력으로 받습니다. map은 입력 받은 자료형의 각 요소가 함수 f에 의해 수행된 결과를 묶어서 리턴하는 함수이다.

map에 의해 리턴된 개체는 map 개체로써, 이를 리스트 등으로 변환하기 위해서는 따로 함수를 취해주어야 합니다.

위의 코드에서는 세개의 유리수를 map함수와 int함수를 통해 모두 정수화 시킨다음 리스트로 출력한 결과입니다.



2. 파이썬 외장 함수


파이썬 외장함수는, 파이썬 라이브러리를 사용하는 것입니다.

파이썬 라이브러리는 말그대로 도서관 처럼 매우 많은 정보와 기능들이 있는데 이것을 모두 자세히 알 필요는 없습니다.

자신이 필요할 때 어떤 라이브러리를 사용해야하는지 정도를 알면됩니다.

이번에도 몇가지만 진행해보겠습니다.


sys


sys모듈은 파이썬 인터프리터가 제공하는 변수들과 함수들을 직접 제어할 수 있게 해주는 모듈입니다.

sys 모듈에는 매우 다양한 기능이 있지만, 하나만 소개해 드린다면, sys.path 입니다.



sys 라는 모듈을 import 문으로 불러오고, sys.path를 입력하면 현재 파이썬 모듈들이 저장되어 있는 경로를 반환해줍니다.



os


OS모듈은 환경 변수나 디텍터리, 파일 등의 OS 자원을 제어할 수 있게 해주는 모듈입니다.

몇가지 유용한 함수들에 대해 소개해 드리면,

os.mkdir(<디텍터리 명>) 은 입력한 디텍터리 명으로 폴더를 생성합니다.

os.unlink(<파일이름>) 은 입력한 파일이름을 삭제합니다.



shutil


shutil은 파일을 복사해주는 파이썬 모듈입니다.

shutil(A, B)

라는 식으로 사용되며, A파일을 B라는 이름으로 파일을 복사합니다.



time


시간과 관련된 time 모듈또한 존재합니다.

가장 유용한 몇가지는 아래와 같습니다.



time.time()은 UTC를 이용하여 현재 시간을 실수 형태로 리턴하는 함수입니다.




time.localtime() 은 연도, 달, 월, 시, 분, 초의 형태로 바꾸어 주는 함수입니다.



random


random은 난수(규칙이 없는 임의의 수)를 발생시키는 모듈입니다.


random.random()



random() 함수는 0.0부터 1.0 까지의 난수를 발생하고 하나를 반환합니다.



이렇게 해서 파이썬의 내장함수와 외장함수에 대해서도 알아보았습니다.

제가 설명드린 것들을 제외하고도 매우 많은 내장함수와 외장함수가 존재하니 한번 찾아보시면서 손에 익혀보세요 :)

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

오늘은 파이썬에서 예외처리를 하는 방법에 대해서 알아보도록 하겠습니다.


1. 예외 처리(Exception)


우리가 파이썬을 통해(또는 다른 프로그래밍 언어를 통해) 프로그램을 제작할 때 수없이 많은 오류가 발생할 수 있습니다.

물론 그러한 오류를 발생시키지 않도록 하는 것이 좋을 수 있으나 때로는 특정 오류를 그냥 무시하게끔 하는 것이 필요할 때도 있습니다.

이러한 것을 하기 위해 파이썬에서는 예외(오류)처리를 할 수 있도록 try, except문을 이용합니다.



2. 오류는 언제 발생할까?


우리가 직접적으로 오류를 처리해보기 전에 어떠한 오류들이 어떻게 발생하는지 몇가지만 간단히 알아보겠습니다.


먼저, 우리가 해당 경로에 존재하지 않는 파일을 열려고 했을 때 발생하는 오류입니다.



위의 코드에서 오류난 것을 살펴보면 FileNotFoundError 라는 것을 반환해주고 있습니다.



두번째는 숫자를 0으로 나눴을 때 발생하는 오류입니다.



위의 코드에서는 ZeroDivisionError를 반환해줍니다.



마지막으로는 리스트의 인덱스 범위를 벗어났을때 오류입니다.



위의 코드를 보면, list는 0번째, 1번째, 2번째 요소값만 가지고 있었는데 3번째 값을 요청하니 IndexError를 반환합니다.



3. 오류 예외 처리 하기


그럼 위에서 간단히 알아본 오류들을 어떻게 처리하는지 살펴보겠습니다.

처음에 간단히 언급하였듯이 파이썬에서는 예외처리를 위해 try, except 문을 이용합니다.

먼저 해당 try, except 문에 대한 기본적인 구조는 아래와 같습니다.


try:

<실행할 문장1>

<실행할 문장2>

<실행할 문장3>

...

except [발생오류[as 오류 메세지 변수]]:

<오류를 무시하고 실행할 문장1>

<오류를 무시하고 실행할 문장2>

<오류를 무시하고 실행할 문장3>

...


위의 구조를 살펴보면, 먼저 try 이하에서 특정 코드(들)를 실행합니다.

그리고 우리가 except에서 걸어준 발생오류가 발생하면 프로그램을 정지시키지 않고 except 이하의 코드를 실행합니다.

여기서 except 문 오른쪽에 대괄호( [, ] )로 묶인 이유는 생략이 가능하기 때문입니다.

즉, 특정한 오류에 대해 그 오류명을 지정하여 그에 대해서만 예외처리가 가능하며 어찌되었든 오류가 발생했을때의 상황에 대한 예외처리도 가능합니다.

또한 as를 사용함으로써 오류메세지의 내용까지 확인할 수 있습니다.


간단하게 0으로 나누는 코드에서 오류메세지의 내용을 출력해보는 코드는 아래와 같습니다.



또한 추가적으로 try문은 else절을 지원합니다. 

else 절은 예외가 발생하지 않은 경우에만 실행이 되며 except 절 바로 다음에 위치해야 합니다.



즉 위의 코드는 test.txt 라는 파일이 있을때는 그 내용을 읽어서 data라는 변수에 저장하지만, 파일이 존재하지 않을때는 오류메세지를 출력합니다.


또한 try문에서는 finally절을 지원합니다.

finally절은 else절과 다르게, 오류 발생여부에 상관없이 항상 수행됩니다. 



4. 오류 회피하기



오류를 회피하는 방법으로는 위 코드와 같이 try, except 문을 이용하여 오류를 잡아주고 except절 이하에서 단순히 pass 처리를 하면됩니다.



5. 오류 발생시키기


지금까지는 오류를 어떻게 처리하는지, 회피하는지 알아보았는데 프로그래밍을 하다보면 일부러 오류를 발생시켜야 하는 경우도 있습니다. 이럴때는 raise 라는 명령어를 통해서 오류를 발생시키면 됩니다.



위의 코드 처럼 raise 뒤에 적절한 오류명을 적어줌으로써 오류를 발생시킬 수 있습니다.

추가적으로 해당 오류명뒤에 괄호를 통해 오류내용을 함께 포함시킬 수 있습니다.

이때, 정의되어있지 않은 오류명은 NameError 라는 다른 오류를 발생시킵니다.



이렇게 해서 파이썬에서 오류(예외)를 처리하는 방법에 대해서 알아보았습니다.

잘 해결되지 않거나 추가적인 궁금사항은 댓글을 이용해주세요 :)

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요.

이번 포스팅에서는 파이썬에서 모듈과 패키지이 무엇인지, 그리고 어떻게 사용하는지 알아보도록 하겠습니다.


1. 모듈(Module)


모듈이란, 함수나 변수 또는 클래스 들을 모아놓은 파일을 말합니다.

즉, A.py 이라는 파일에 F1, F2 라는 함수와 C1, C2 라는 클래스를 만들었을때, B.py라는 파일에서 A.py를 모듈로써 사용하여 F1, F2 함수 또는 C1, C2 클래스를 사용할 수 있는 것입니다.

이러한 모듈을 통해 우리는 다른사람이 만들어 놓은 모듈을 사용하여 함수나 클래스를 사용할 수 있게됩니다.

그럼 간단한 모듈을 직접 만들어 보도록 하겠습니다.



위의 코드와 같은 파일을 module1.py 라고 저장하였습니다.

그리고 위의 파일을 모듈로써 사용하기 위해 우리는 import 를 사용합니다.

아래 코드에서 import를 통해 module1을 가져오고, module1에 있는 함수를 사용합니다.



위의 코드를 CMD에서 실행시키면 아래와 같이 올바른 결과가 출력됩니다.



import를 사용할때는, 


import 파일이름


와 같은 식으로 사용하며 파일이름 뒤에 있는 .py 라는 확장자는 생략합니다.



2. 모듈 사용 응용하기


모듈을 사용할때, 몇 가지 추가적인 방법이 있습니다.

먼저,


from 모듈이름 import 모듈함수


와 같은 방법입니다.

우리는 위의 코드에서 module1의 sum 함수를 사용하기 위해 module1.sum() 이라는 식으로 호출을 하였습니다.

하지만, from module1 import sum 과 같이 사용하면 sum함수를 이름 그대로 호출할 수 있습니다.



또한 두번째로, import문 맨 뒤에 as를 통해 자신이 함수이름을 다르게 설정할 수도 있습니다.

예를 들어, sum함수를 불러오는데 plus라는 이름의 함수로 사용하고 싶다면,


from module1 import sum as plus


와 같은 식으로 사용하면 됩니다.



세번째로 알아볼 내용은

if __name__ == "__main__":

입니다.

이를 제대로 확인하기 위해 먼저 module1.py 의 코드를 아래와 같이 수정합니다.



위의 코드와 같이 수정하고 다시 CMD창에서 module1.py를 사용하는 파일을 실행하면 다음과 같이 출력이 됩니다.



그런데, 우리는 prac.py에서 단순히 module1.py 의 함수만 사용하고 싶은데, module1.py에 있는 print()문 까지 함께 실행이 되어버렸습니다.

이러한 경우 우리는 if __name__ == "__main__": 를 통해 모듈을 호출할때 해당 파일의 함수나 클래스, 변수만 가져오도록 할 수 있습니다.

module1.py의 코드를 아래와 같이 수정합니다.



위의 코드처럼 수정하고 다시 prac.py를 실행하면 module1.py의 print()문은 실행되지 않는 것을 볼 수 있습니다.


if __name__ == "__main__": 에 대해서 간단히 살펴보면

이는 직접 해당 파일을 실행시켰을 때는 if 문이 참이되어 그 이하 문장이 실행되지만, 단순히 모듈로써 불러서 사용하는 경우에는 if문이 거짓이 되어 이하 문장이 실행되지 않는 구조입니다.


위에서는 주로 함수를 예로 들어 모듈에 대해서 알아보았는데 클래스나 변수 또한 함수와 같은 방식으로 사용할 수 있습니다.



3. 패키지


패키지는 간단히 말해, 여러개의 모듈을 묶은 집합입니다.

예를 들어 아래의 파일구조와 같이 package 라는 폴더에 module1.py module2.py 를 만들고 package라는 폴더와 같은 위치에 prac.py 라는 파일이 있다고 합시다.



이때 우리는 package라는 폴더를 하나의 패키지라고 합니다.

이러한 패키지를 이용하는 방법은 모듈에서 사용한 방법과 매우 유사합니다.

prac.py 에서 package라는 패키지에 있는 moduel1.py를 이용하고 싶을땐,


from package.module1 import sum


과 같은 방식으로 사용하면 됩니다.


이렇게 해서 파이썬에서 모듈과 패키지에 대해서 알아보았습니다.

잘 진행이 되지 않거나 추가적으로 궁금한 사항은 언제든지 댓글을 이용해주세요.


블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 파이썬에서 클래스의 상속(Inheritance)에 대해서 알아보도록 하겠습니다.


1. 상속(Inheritance)


상속(Inheritance)이란, 다들 아시다시피 '물려받다'라는 의미를 가지고 있습니다.

클래스의 상속은 이러한 의미가 적용됩니다.

즉, B라는 클래스를 만들때 이미 만들어져 있던 A라는 클래스의 기능을 물려받는 것 입니다.

보다 쉽게 이해하기 위해 아래와 같은 Univ 클래스를 구성하였습니다.



Univ class에서는 기본적으로 University를 '서울시립대학교'로 지정하고, __init__함수에서 학년을 설정하게됩니다.

그리고 hello()함수를 통해 자신의 학교, 학년, 이름을 말하게 됩니다.


이제 상속을 사용해보도록 합니다.

ECE라는 클래스를 만드는데 Univ에게 상속을 받으며 University를 '서울시립대학교 전자전기컴퓨터공학부'로 바꾸겠습니다.



위의 코드와 같이 ECE 클래스를 구성하여 해당 파일을 실행시키면 아래와 같은 결과가 나옵니다.



ECE 클래스에서는 hello() 함수를 따로 선언하지 않았지만, Univ 클래스에게 상속받음으로써 이를 사용할 수 있는 것입니다.


위와 같이 상속은 아래와 같은 구조를 가지게 됩니다.


class 상속받을 클래스명(상속할 클래스명):

<내용 1>

<내용 2>

...



2. 매서드 오버라이딩(Method overriding)


상속에 개념중에서 알아야할 또 다른 개념은 매서드 오버라이딩(Method overriding)입니다.

이는 상속받은 함수를 새롭게 구현하는 것입니다.

예를 들어, 위의 ECE 클래스에서 다른 방식으로 인사를 해야한다면 아래와 같이 매서드 오버라이딩을 하면 됩니다.



위의 코드에서 11,12번 라인을 보면 hello()함수를 새롭게 구현한 것을 보실 수 있습니다.

이러한 것이 매서드 오버라이딩입니다.



3. 연산자 오버로딩(overloading)


연산자 오버로딩이란 연산자(+, -, *, /, ... )를 객체끼리 사용할 수 있게 하도록 하는 것입니다.

즉 연산자를 새롭게 구현하는 것입니다.

연산자 오버로딩을 통해 다음과 같은 것을 구현할 수 있습니다.



코드에서 13,14라인을 보시면 __add__라는 함수를 구현한 것을 볼 수 있습니다.

위와 같은 것이 연산자 오버로딩입니다.


이렇게 해서 파이썬에서 클래스에 대한 개념에 대해 두번의 포스팅으로 알아보았습니다.

다음 포스팅에서는 '모듈'에 대해서 알아보겠습니다.



블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 파이썬에서의 클래스(Class)에 대해서 알아보도록 하겠습니다.


1. 클래스(Class)는 왜 필요할까?


클래스는 도대체 무엇이고, 왜 필요할까요?

먼저 하나의 예시를 들어서, 보다 쉽게 이해해보도록 하겠습니다.


계산기 기능을 하는 adder라는 프로그램이 있습니다. 

보다 쉬운 이해를 위해 단순히 덧셈만 계산한다고 가정합니다.

계산기는 단순히 두개 또는 세개의 숫자만 더하는 것이 아닙니다. 제가 입력하는 모든 숫자들의 합을 구해야합니다.

따라서 아래와 같은 모습을 가지게 될 것입니다.



위의 계산기 adder에서는 전역변수로 선언된, 초기값 0을 가진 result를 가져와 주어진 값을 더합니다.

따라서 해당 코드가 실행된 후에 result 값을 확인하면, 3+6+12 = 21의 값을 갖고 있을 것입니다.


그런데 특정 상황에 의해, adder라는 계산기가 두개 필요하다고 생각해봅시다.

예를 들어, 3+4+5 라는 연산과 9+10 이라는 연산을 한번에 진행해야 하는 것입니다.

이러한 상황을 고려해보면, adder라는 함수 하나보다는 adder_1과 adder_2가 필요합니다.

따라서 아래와 같은 코드가 구현될 것입니다.



네, 여기까지는 문제가 없는 것 같습니다.

그런데 위와 같은 adder라는 계산기가 5개, 10개가 필요할때는 어떡할까요?

2개를 구현했던 것처럼 하나하나 모두 직접 함수를 구현해야 할까요?


클래스의 개념을 익히면 위와 같은 상황을 매우 쉽게 해결할 수 있습니다.


위의 예시를 보시면서 어느정도 감히 잡혔을지 모르지만,

많은 곳들에서 클래스를 틀, 공장 등으로 비유하는 경우가 많습니다.


말 그대로 클래스는 틀 또는 공장과 같은 성격을 가지고 있습니다.

위의 상황에 이어서, Adder라는 클래스(class)가 있다고 가정합시다.

그럼 Adder는 덧셈을 구현하는 계산기를 만들어내는 틀 또는 공장이 되는 것 입니다.


이것을 코드로 나타내보면 아래와 같습니다.



위의 코드를 보시면 먼저 class Adder가 만들어 집니다.

__init__ 함수에 대해서는 조금 더 뒤에서 설명드리니 일단 넘어갑니다.

Adder 클래스를 확인하면 adder라는 함수가 있습니다.

해당 함수에서는 입력받은 num 값을 result에 더해서 반환하는 역할입니다.


이러한 클래스를 통해 그 아래에서 3개의 계산기를 손쉽게 만들어 냈습니다.


이렇게 클래스(class)는 틀, 공장과 같은 역할을 해서 자신의 형태와 같은 결과물(인스턴스)를 만들어 냅니다.



2. 클래스(Class)에서 self와 __init__


그럼 위의 코드에서 self는 무엇이고 __init__은 무엇일까요?


먼저 self는 단어 그대로 자기자신이라고 생각하시면 됩니다.

즉 위에서 생성된 adder_1, adder_2, adder_3 객체 모두 result라는 요소를 가지고 있습니다.

그런데 우리가 adder_2의 result가 궁금할 때 어떻게 호출할까요?


adder_2.result


를 호출함으로써 알 수 있게 됩니다.

또한, adder_2에서 adder라는 함수가 실행될 때 어떤 result를 참조하는지를 self를 통해 자기자신의 result를 참조한다고 알려줍니다.

그런데 이는 객체를 통해 함수나 변수를 호출할 때 생략될 수 있습니다. 때문에 adder라는 함수에서 self를 포함해 입력 인자2개를 받지만, 객체 자신을 통해서 해당 함수를 호출하면 self를 생략할 수 있습니다.

따라서 아래의 두 문장은 서로 일치하는 문장입니다.


Adder.(adder_2, 3) == adder_2(3)



그럼 두번째로, __init__ 은 무엇일까요?

간단하게 한 문장으로 말씀드리면,

인스턴스가 생성될 때 항상 실행되는 것입니다.

즉, 위의 Adder라는 클래스를 통해 adder_1, adder_2, adder_3 라는 세개의 인스턴스가 생성되었는데 각 인스턴스가 생성될 때 마다 __init__이라는 함수가 실행되어 각각의 인스턴스 모두 self.result = 0 이라는 문장을 실행한 것입니다.



또한 클래스(Class)에는 클래스 상속(Inheritance)과 오버로딩(Overloadging) 이라는 개념이 존재합니다.

하지만 이러한 것들 또한 위에서 설명된 내용들을 잘 이해한다면 쉽게 이해하실 수 있는 내용이기에 따로 설명은 생략하겠습니다.


이렇게해서 파이썬에서의 클래스(Class)에 대해서 알아보았습니다.

클래스는 프로그래밍을 하면서 매우 유용하게, 자주 사용되므로 꼭 직접 코드를 작성해보시면서 이해하시면 좋을 것 같습니다.

막히는 부분이 있거나 잘못된 부분이 있다면 언제든 말씀해주세요 :)


블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc