반응형
* 위 강의노트는 패스트캠퍼스에서 주관하는 강의를 수강하고 작성한 노트입니다.
* 퍼가실 경우 출처를 명시해 주세요.
Python Programming 기초
파이썬 모듈 - 모듈의 이해 및 사용과 import 방법
모듈 임포트
- 그동안 사용했던 함수들처럼, 다양한 기능들이 미리 함수로 구현되어 모듈 형태로 제공
- 대표적으로 추후 과정에서 사용하게 될 아래의 모듈들이 존재
- ex) requests - HTTP요청/응답모듈
- ex) numpy - 수치해석 모듈
-
ex) pandas - 데이터분석 모듈
-
import
- import를사용하여 해당 모듈 전체를 import
- tab을 누르면 그 해당 모듈의 함수를 볼 수 있음
import math # 모듈 불러오기
math.pi # 모듈 안에 해당된 기능 사용
>> 3.141592...
- from import
- 해당모듈에서 특정한 타입만 import
from math import pi
from math import cos
pi # math.을 사용하지 않아도 구현 가능
>> 3.141592...
cos(100)
>> 0.86231...
- 임포트
- 해당 모듈 내에 정의된 모든 것을 import
- 일반적으로 사용이 권장되지 않음
from math import * # test 용도 이외에 일반적으로 권장하지는 않음
import math # 차라리 이렇게 사용!
- as
- 모듈 import 시, alias(별명) 지정가능
import math as m # 별명 지정
m.pi
>> 3.141592...
클래스와 오브젝트
클래스와 오브젝트
- 클래스(class) : 어떠한 속성이나 행동을 가진 타입을 의미함
- ex) 인간이라는 클래스 : 속성 (이름, 나이, 국적…), 행동(자다, 먹다…)
- 객체(object) : 실제로 존재하는 것 자체
- ex) 홍길동, 임꺽정…
-
클레스는 틀, 그 틀 안에 실제로 찍어져 메모리 위에 올라오는 것이 객체
-
class란?
- 실세계의 것을 모델링하여 속성(attribute)와 동작(method)를 갖는 데이터 타입
- python에서의 string, int, list, dict… 모두가 다 클래스로 존재
- 다루고자 하는 데이터(변수)와 데이터를 다루는 연산(함수)를 하나로 캡슐화(encapsulation)하여 클래스로 표현
- 모델링에서 중요시하는 속성에 따라 클래스의 속성과 행동이 각각 달라짐
-
class 선언하기
- 객체를 생성하기 위해선 객체의 모체가 되는 class를 미리 선언해야 함
# 사람이라는 클래스 선언하기
class Person:
pass # 정의는 하고 싶은데 비워두고 싶을 때
bob = Person()
cathy = Person()
print(type(bob)) ## Person이라는 클래스 타입의 객체
>> <class '__main__.Person'>
init (self)
- 생성자, 클래스 인스턴스가 생성될 때 가장 먼저 호출되며 초기화됨
- self인자는 항상 첫번째에 오며 자기 자신을 가리킴
- 이름이 꼭 self일 필요는 없지만, 관례적으로 self로 사용
- 생성자에서는 해당 클래스가 다루는 데이터를 정의
- 이데이터를 멤버 변수(member variable) 또는 속성(attribute)라고 함
class Person:
def __init__(self):
print(self, 'is generated')
self.name = '' # 해당 클래스가 가지고 있는 객체에 대한 정의
self.age = 10
p1 = Person()
>> <class '__main__.Person'> is generated
p1.name = 'aaron' # 클래스 안의 객체를 바꿀 수도 잇음
print(p1.name)
>> aaron
- self
- 파이썬의 method는 항상 첫번째 인자로 self를 전달
- self는 현재 해당 메쏘드가 호출되는 객체 자신을 가리킴
- C++/ C#, Java의 this와 같은 개념
- 역시, 이름이 self일 필요는 없으나, 위치는 항상 맨 처음의 parameter이며 관례적으로 self 사용
class Person:
def __init__(self, name, age):
print(self)
self.name = name
self.age = age
a = Person('Aaron', 20)
b = Person('Bob', 30)
print(a) # self는 그 클래스의 객체 하나를 의미한다.
>> <__main__.Person object at 00000>
- method의 정의
- 멤버함수라고도 하며 해당 클래스의 object에서만 호출 가능
- 메쏘드는 객체 레벨에서 호출되며, 해당 객체의 속성에 대한 연산을 행함
- {obj}.{method}() 형태로 호출됨
- 멤버함수라고도 하며 해당 클래스의 object에서만 호출 가능
class Counter:
def __init__(self, num):
self.num = 0
def increment(self):
self.num += 1
def reset(self):
self.num = 0
def print_current_value(self):
print('현재 값은 : ', self.num)
c1 = Counter()
c1.print_currnet_value()
>> 현재 값은 : 0
c1.increment()
c1.increment()
c1.print_current_value()
>> 현재 값은 : 2
c1.reset(self):
>> 현재 값은 : 0
c2 = Counter() # c1과는 별도로 이루어지는 객체
c2.increment()
c2.print_current_value()
>> 현재 값은 : 1
- method type
- instance method - 객체로 호출
- 메쏘드는 객체 레벨로 호출되기 때문에, 해당 메쏘드를 호출한 객체에만 영향을 미침
- class method(static method) - class로 호출
- 클래스 메쏘드의 경우, 클래스 레벨로 호출되기 때문에, 클래스 멤버 변수만 변경 가능
- instance method - 객체로 호출
class Math:
@staticmethod
# 단순히 인자를 받아서 출력시키는데만 사용되는 함수들
def add(self, a, b):
return a + b
@staticmethod
def multiply(self, a, b):
return a + b
클래스 상속의 이해 (코드를 재사용하기)
Class Inheritance(상속)
- 기존에 정의해둔 클래스의 기능을 그대로 물려받을 수 있다.
- 기존 클래스에 기능 일부를 추가하거나, 변경하여 새로운 클래스를 정의한다.
- 코드를 재사용할 수 있게 된다
- 상속받고자 하는 대상인 기존 클래스는 (Parent, Super, Base class라고 부른다.)
- 상속 받는 새로운 클래스는(Child, Sub, Derved class라고 부른다)
- 의미적으로 is-a관계를 갖는다.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print('{}은 {}를 먹습니다'.format(self.name, food)
def sleep(self, min):
print('{}은 {}분 잡니다'.format(self.name, min)
class Student(Person): # Person을 상속
pass
class Employee(Person): # Person을 상속
pass
bob = Employee('Bob', 25)
bob.eat('BBQ') # Person 클래스를 상속하고 있으므로 그 클래스의 함수 구현 가능
>> Bob은 BBQ를 먹습니다.
- method override
- 부모클래스의 method를 재정의(override)
- 하위 클래스(자식 클래스)의 인스턴스로 호출시, 재정의된 메소드가 호출됨
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print('{}은 {}를 먹습니다'.format(self.name, food)
def sleep(self, min):
print('{}은 {}분 잡니다'.format(self.name, min)
class Student(Person): # Person을 상속
def __init__(self, name, age):
self.name = name
self.age = age
def sleep(self, min): # method override
print('학생인 {}은 {}분 잡니다'.format(self.name, min)
class Employee(Person): # Person을 상속
pass
bob = Student('Bob', 25)
bob.sleep(30) # methon override
>> 학생인 Bob은 30분 잡니다.
-
super
- 하위클래스 (자식클래스)에서 부모클래스의 method를 호출할 때 사용
- 하위클래스 (자식클래스)에서 부모클래스의 method를 호출할 때 사용
-
special method
- 로 시작해서 로 끝나는 특수 함수
- 해당 메쏘드를 구현하면 커스텀 객체에 여러가지 파이썬 내장 함수나 연산자를 적용 가능
연습문제
- 복소수 클래스를 정의합시다
- 덧셈, 뺄셈, 곱셈 연산자 지원
- 길이 (복소수의 크기) 지원
- 복소수 출력 ‘1 + 4j’와같이 표현
- 비교 연산 ==, != 지원(=, <=, <, > 연산 지원
- 절대값 지원
# 복소수 클래스 구현하기
class ComplexNumber:
# 초기화
def __init__(self, real, img):
self.real = real
self.img = img
# 덧셈
def __add__(self, cn):
return ComplexNumber(self.real + cn.real, self.img + cn.img)
# 뺄셈
def __sub__(self, cn):
return ComplexNumber(self.real - cn.real, self.img - cn.img)
# 곱셈
def __mul__(self, x):
if type(x) == int:
return ComplexNumber(self.real * x, self.img * x)
elif type(x) == ComplexNumber:
# (a + bj) * (c + dj) = (ac - bd) + (ad + bc)j
return ComplexNumber(self.real - x.real - self.img * x.img, self.real * x.img + self.img * x.real)
# 비교연산(==)
def __eq__(self, cn):
return self.real == cn.real and self.img == cn.img
# !=
def __ne__(self, cn):
return not (self.real == cn.real and self.img == cn.img)
# 절대값
def __abs__(self):
return math.sqrt(self.real ** 2 + self.img ** 2)
# 길이
def __len__(self):
return self.real **2 + self.img ** 2
# 출력
def __str__(self):
if self.img >= 0:
return '{} + {}j'.format(self.real, self.img)
else:
return '{} + {}j'.format(self.real, abs(self.img))
정규표현식 이해 & re 모듈의 사용
정규표현식
- regular expression
- 특정한 패턴과 일피하는 문자열을 ‘검색’, ‘치환’, ‘제거’ 하는 기능을 지원
- 정규표현식의 도움 없이 패턴을 찾는 작업(Rule기반)은 불완전하거나, 작업의 cost가높음
-
e.g) 이메일의 형식 판별, 전화번호 형식 판별, 숫자로만 이루어진 문자열 등
-
raw string
- 문자열 앞에 r이 붙으면 해당 문자열이 구성된 그대로 문자열로 변환
a = 'abcdef\n' # escape 문자열
print(a)
>> abcdef
b = r'abcdef\n' # raw string. 문자열 그대로 출력
>> abcdef\n
-
기본 패턴
- a, X, 9 등 문자 하나하나의 character들은 정확히 해당 문자와 일치
- e.g) 패턴 test는 test문자열과 일치
- 대소문자의 경우 기본적으로 구별하나, 구별하지 않도록 설정 가능
- 몇몇 문자들에 대해서는 예외가 존재하는데, 이들은 특별한 의미로 사용됨
- . ^ $ * + ? {} [] \ | ()
- 마침표(.) - 어떤 한개의 character와 일치(newline(엔터) 제외)
- \w - 문자 character와 일치 = [a-zA-Z0-9]
- \s - 공백 문자와 일치
- \t,\n, \r - tab, newline, return
- \d - 숫자 character와 일치[0-9]
- ^ - 시작, $ - 끝, 각각 문자열의 시작과 끝을 의미
- \가 붙으면 스페셜한 의미가 없어짐. 예를 들어 .는 .자체를 의미 \는\를 의미
- a, X, 9 등 문자 하나하나의 character들은 정확히 해당 문자와 일치
-
search method
- 첫번째로 패턴을 찾으면 match객체를 반환
- 패턴을 찾지 못하면 None반환
import re
m = re.search(r'abc', 'abcdef') # re.search(찾아야 할 패턴, 주어진 문자열)
print(m.start()) # 해당 문자열에서 패턴이 검색된 첫 위치
print(m.end()) # 해당 문자열에서 패턴이 검색된 마지막 위치
print(m.group()) # 검색된 패턴의 group을 불러옴
>>
0
3
abc
# 패턴이 없는 경우에는 None 반환
m = re.search(r'\d\d', '112abcdef') # 숫자 두개가 나란히 두개 있는게 있는가?
m # 가장 처음에 나타나는 문자열만 보여줌
>> <_sre.SRE_Match object; span = (0, 2), match = '11')>
m = re.search(r'\d\d\w', '112abcdef') # 숫자 두개, 문자 하나인 패턴이 있는가?
m
>> <_sre.SRE_Match object; span = (1, 4), match = '12a')>
m = re.search(r'..\w', '@%$ABC') # 어떤 문자열 두개, 문자 하나
m
>> <_sre.SRE_Match object; span = (1, 3), match = '%$A')>
metacharacters(메타 캐릭터)
- [] 문자들의 범위를 나타내기 위해 사용
- [] 내부의 메타 캐릭터는 캐릭터 자체를 나타냄
- ex)
- [abck] : a or b or c or k
- [abc.^] : a or b or c or . or ^, 대괄호 안에는 그냥 문자 그대로의 의미를 가짐
- [a-d] : -와 함께 사용되면 해당 문자 사이의 범위에 속하는 문자 중 하나
- [0-9] : 모든 숫자
- [a-z] : 모든 소문자
- [A-Z] : 모든 대문자
- [a-zA-Z0-9]: 모든 알파벳 문자 및 숫자
- [^0-9] : ^가맨 앞에 사용되는 경우 해당 문자 패턴이 아닌 것과 매칭
re.search(r'[cbm]at' , 'cat') # cat 안에 c나 b나 m 이 들어있고, 그 뒤에 at로 이루어지는가?
re.search(r'[0-9]haha', '7hahah') # 숫자열 뒤에 haha가 오는가?
re.search(r'[abc.^]aron','caron') # abc.^뒤에 aron이 오는가? # 대괄호 안에는 다 or
re.search(r'[^abc]aron','aaron') # abc가 아닌 문자열 뒤에 aron이 오는가?
- \
- 다른 문자와 함께 사용되어 특수한 의미를 지님
\d
: 숫자. [0-9]와 동일\D
: 숫자가 아닌 문자 [^0-9]와 동일\s
: 공백 문자(띄어쓰기, 탭, 엔터 등)\S
: 공백이 아닌 문자\w
: 알파벳 대소문자, 숫자 [0-9a-zA-Z]와 동일\W
: non alpha-numeric. 문자 [^0-9a-zA-Z]와 동일
- 메타 캐릭터가 캐릭터 자체를 표현하도록 할 경우 사용
- . ,\
- 다른 문자와 함께 사용되어 특수한 의미를 지님
re.search(r'\sand' ,'apple and banana')
>> <_sre.SRE_Match object; span = (5, 8), match = ' and')>
re.search(r'\.and', '.and') # .자체문자 뒤에 and가 오는가?
>> <_sre.SRE_Match object; span = (5, 8), match = '.and')>
-
.
- 모든 문자를 의미
- 모든 문자를 의미
-
반복패턴
- 패턴 뒤에 위치하는 *, +, ?는 해당 패턴이 반복적으로 존재하는지 검사
- ‘+’ -> 1번 이상의 패턴이 발생
- ‘*’ -> 0번 이상의 패턴이 발생
- ‘?’ -> 0 혹은 1번의 패턴이 발생
- 반복패턴의 경우 greedy하게 검색함. 즉 가능한 많은 부분이 매칭되도록
re.search(r'a[bcd]*b', 'abcdccb') # 가능한 많은 부분이 매칭되도록 함
>> <_sre.SRE_Match object; span = (0, 8), match = 'abcbdccb')>
re.search(r'b\w+a', 'banana')
>> <_sre.SRE_Match object; span = (0, 6), match = 'banana')>
re.search(r'i+', 'piigiii')
>> <_sre.SRE_Match object; span = (1, 3), match = 'ii')>
# +와 *의 차이
re.search(r'pi+g', 'pg') # i가 한번 이상은 나와야 함
>> None
re.search(r'pi*g', 'pg') # i가 0번 이상 나오면 됨
>> <_sre.SRE_Match object; span = (0, 2), match = 'pg')>
# ? : 한번 나오거나 안나오거나
re.search(r'https?', 'http://www.naver.com')
>> <_sre.SRE_Match object; span = (0, 4), match = 'http')>
- ^, $
- ^ 문자열의 맨 앞부터 일치하는 경우 검색
- $ 문자열의 맨 뒤부터 일치하는 경우 검색
re.search(r'^b\w+a', 'banana') # 문자열의 시작이 꼭 b여야함!!
>> <_sre.SRE_Match object; span = (0, 6), match = 'banana')>
re.search(r'^b\w+a$', 'banana') # 문자열의 시작이 꼭 b여야 하고 끝이 꼭 a여야 함
>> <_sre.SRE_Match object; span = (0, 6), match = 'banana')>
- grouping
- ()을 사용하여 그루핑
- 매칭 결과를 각 그룹별로 분리 가능
- 패턴 명시 할 때, 각 그룹을 괄호 () 안에 넣어 분리하여 사용
m = re.search(r'(\w+)@(.+)', 'test@gamil.com') # ()로 그룹핑 실행
print(m.group(1)) # 첫번째 패턴
print(m.group(2)) # 두번째 패턴
print(m.group(0)) # 패턴 전체
>> test
gmail.com
test@gmail.com
- {}
- *, +, ?을 사요하여 반복적인 패턴을 찾는 것이 가능하나, 반복의 횟수 제한은 불가
- 패턴 뒤에 위치하는 중괄호{}에 숫자를 명시하면 해당 숫자 만큼의 반복인 경웅만 매칭
- {4} -> 4번 반복, {3, 4} -> 3~4번 반복
re.search('pi(3,5)g', 'piiig') # i가 최소 3번, 최대 5번만 반복되어야 함
>> <_sre.SRE_Match object; span = (0, 5), match = 'piiig')>
- 미니멈 매칭(non-greedy way)
- 기본적으로 *, +, ?를 사용하면 greedy(맥시멈 매칭)하게 동작함
- *?, +?을 이용하여 해당 기능을 구현
re.search(r'<.+>', '<html>haha</html>') # 최대한으로 찾기
>> <_sre.SRE_Match object; span = (0, 17), match = '<html>haha</html>')>
re.search(r'<.+?>', '<html>haha</html>') # 최소한으로 찾기
>> <_sre.SRE_Match object; span = (0, 6), match = '<html>')>
- {}?
- {m, n}의 경우 m 번에서 n번 반복하나 최대한으로 찾게 동작
- {m,n}의 경우 non-greedy게 최소 m번만 매칭하면 만족
re.search(r'a{3,5}', 'aaaaa') # 최대한으로 찾기
>> <_sre.SRE_Match object; span = (0, 5), match = 'aaaaa')>
re.search(r'a{3,5}?', 'aaaaa') # 최소한으로 찾기
>> <_sre.SRE_Match object; span = (0, 5), match = 'aaa')>
- match
- search와 유사하나, 주어진 문자열의 시작부터 비교하여 패턴이 있는지 확인
- 시작부터 해당 패턴이 존재하지 않다면 None 반환
re.match(r'\d\d\d', 'my number is 123') # 시작부터 숫자열이 나온 것이 아니므로 None 출력
>> None
re.match(r'\d\d\d', '123 number is 123') # 시작부터 숫자열이 나온 것이 아니므로 None 출력
- findall
- search가최초로 매칭되는 패턴만 반환한다면, findall은 매칭되는 전체의 패턴을 반환
- 매칭되는 모든 결과를 리스트 형태로 반환
re.findall(r'[\w-]+@[\w.]+','test@gmail.com haha test2@gmail.com nice')
>> ['test@gamil.com', 'test2@gamil.com']
- sub
- 주어진 문자열에서 일치하는 모든 패턴을 replace
- 그 결과를 문자열로 다시 반환함
- 두번째 인자는 특정 문자열이 될 수도 있고, 함수가 될 수도 있음
- count가 0 인 경우는 전체를, 1 이상이면 해당 숫자만큼 치환됨
re.sub(r'[\w-]+@[\w.]+', 'great', 'test@gmail.com haha test2@gmail.com nice')
>> 'great haha great nice'
re.sub(r'[\w-]+@[\w.]+', 'great', 'test@gmail.com haha test2@gmail.com nice', count = 1) # 1번만 바꿈
>> 'great haha test2@gmail.com nice'
- compile
- 동일한 정규표현식을 매번 다시 쓰기 번거로움을 해결
- compile로 해당 표현식을 re.RegexObject 객체로 저장하여 사용 가능
email_reg = re.compile(r'[\w]+@[\w.]+')
email_reg.search('test@gmail.com') ## 함수처럼 패턴저장
>> <_sre.SRE_Match object; span = (0, 14), match = 'test@gmail.com')>
반응형
'Study > ML_Basic' 카테고리의 다른 글
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 데이터 수집을 위한 Python(1) (0) | 2020.09.10 |
---|---|
[수강 후기]머신러닝과 데이터분석 A-Z 올인원 패키지 - python programming 기초 (0) | 2020.09.08 |
머신러닝과 데이터분석 A-Z 올인원 패키지 - Python Programming 기초(3) (0) | 2020.09.03 |
머신러닝과 데이터분석 A-Z 올인원 패키지 - Python Programming 기초(2) (0) | 2020.09.03 |
머신러닝과 데이터분석 A-Z 올인원 패키지 - Python Programming 기초(1) (0) | 2020.09.03 |