상세 컨텐츠

본문 제목

[PLAYDATA] 데이터 엔지니어링 8월 3주차 8/17

PLAYDATA/PLAYDATA데일리노트

by Na느님 2023. 8. 17. 15:54

본문

  • 8월 17일
오늘 3번째 수업이다. 오늘은 함수와 클래스 수업을 하는 날이다. 확실히 6개월 만에 많은 내용을 배울 예정이다 보니, 파이썬 문법은 확실히 빠르게 진도를 나가는게 느껴진다. 과거에 파이썬을 써 본적이 있었는데 지금은 복습한다는 개념으로 수업을 듣고 있다.

 

 

print함수
기본형: print(str)
str은 +나 ,로 묶인다. +의 경우는 str만 피연산자가 가능하고 공백이 없이 묶인다.
,의 경우는 다른 형식의 피연산자도 가능하고 공백이 자동으로 생긴다.

end 옵션이 있는데, end="" 옵션을 넣을 경우 줄바꿈을 하지 않는다.

c언어처럼 %를 이용하여 출력할 수 있다. 다만 형태는 좀 다르다.
형태:
print("%s는 나의 친구입니다." %name)
print("반지름: %d, 원주율: %f" %(r, pi))

curly bracket을 이용한 형식 지정
str 안에 {}을 넣고, 그 괄호가 들어간 str 바로 뒤에 .format을 붙이면 {} 부분에 문자열이 삽입된다.
삽입할 문자열이 여러개인 경우, 괄호 안에 번호를 지정하여 삽입할 수 있다. 생략시 순차적으로 삽입.
ex)
print("당신은 {}이군요.".format(yourName))
print("Animal: {1},{2},{0}".format(animal_0, animal_1, animal_2))
print("Animal: {}, {}, {}".format(animal_0, animal_1, animal_2))


파일 입출력
파일 입출력의 순서
open->r/w->close

(실습 결과, 윈도우10에서 txt파일은 파일을 close해야 그 내용이 실제로 기록된다)

File open 방법
f = open("pathname", 'mode')
f는 앞으로 해당 파일을 관리하기 위한 객체이다.
mode는 'r'은 read, 'w'는 write, 'a'는 append이며
'b'는 바이너리로 열기, 't'는 텍스트로 열기이다. (기본값은 'r'과 't')
ex) open("./test.txt", 'at')

File write 방법
f.write("str")

File read 방법
f.read() #전체 읽기
f.readline() #한줄 씩 읽기
f.readlines() #전체 읽기 후 각 line을 list형태로 저장

File close 방법
f.close()

with문
왜 with문을 사용하는가?
프로그래머가 잊어버리거나, 중간에 에러 등으로 인해 close가 호출되지 않는 경우가 발생할 수 있다.
close함수가 호출되지 않는다면 계속해서 메모리를 점유하고 있기 때문에 시스템에 불필요한 부하를 줄 수 있다.
따라서 특정 코드영역 밖으로 나오게 되면 자동으로 close를 해 주는 기능이 필요하고,그 기능을 해주는 문법이 with이다.

형태
with open(...) as fd:
    #codes


함수
함수의 형태
def name(arguments):
    #codes

만약 arguments 갯수가 유동적이라면 앞에 *를 붙여 *arguments로 한다.
-> arguments를 tuple로 묶어서 준다.
-> Packing에서 잠깐 언급된 내용이다. 단 argument가 여러개 있다면, 맨 뒤의 변수만 *을 붙일 수 있다.

argument의 초깃값
함수를 호출할 때 해당 argument를 지정하지 않은 경우, 초깃값이 지정된 argument는 알아서 그 값이 대입되어 사용된다.
초깃값이 지정된 parameters는 반드시 초깃값이 없는 parameters 뒤에 와야한다.

중첩 함수
함수 정의 안에 또다른 함수가 정의될 수 있다. 이것을 중첩함수 라고 한다.
중첩함수의 경우 inner function은 inner function이 정의된 함수 내부에서만 호출이 가능하다.

lambda 예약어
lambda는 매우 간단한 함수를 정의할 때 사용하는 예약어이다.

형태
func_name = lambda arg1, arg2, ... : expression
ex) add = lambda a, b: a+b
lambda함수는 return 예약어가 없어도 표현식의 결과값을 리턴한다.


클래스
클래스 구조
#=============================
class name:
    member_var = value

    def __init__(self, arg, ...):
        #codes
    
    def func_name(self, arg, ...):
        #codes
#=============================

함수 호출 방법
1. 먼저 객체를 만든다. obj_name = class_name(arg, ...) 형태로 obj_name이라는 객체를 생성한다.
2. obj_name.func_name(arg, ...) 형태로 멤버함수를 호출한다.
※이때 arguments를 대입할 때는 self를 생략하고 넣는다.
예를들면,
(class 내부)
def member_func(self, a, b)
(class 외부)
obj_name.member_func(1, 2)

객체, 멤버변수 삭제는 del obj_name 형태

self예약어
self는 클래스에서 '자기 자신'을 가리키는 예약어이다.
(중요!)객체를 통해 클래스의 함수를 호출하려고 한다면 반드시 함수의 첫 번째 인자는 self여야 한다!
self 인자가 없는 멤버함수는 클래스 이름을 통해 호출할 수 있다. 즉 C++의 static함수처럼 생각해도 된다.
(중요!)클래스 내부에서 어떤 함수 밖의 멤버함수, 멤버변수를 참조, 호출하려면 앞에 self를 붙여야 인식된다.

pass 예약어
비어있는 공간을 표현할 때 사용한다. 예를들어,
def func_name():
    pass
이 함수는 아무런 역할도 수행하지 않는다.

__init__ 함수
__init__ 함수는 생성자 역할을 하며, C++의 생성자를 생각하면 된다. 맨 처음 객체가 만들어질 때 바로 수행되는 함수이다.
하지만 C++과는 달리 생성자를 중복정의 하는건 원칙적으로 불가능하다. (만약 한 클래스에 생성자가 여러개 있으면 항상 제일 밑에 있는 생성자로 결정된다)

__del__ 함수
__del__ 함수는 소멸자 역할을 하며, 객체가 소멸되기 직전에 마지막 역할을 수행한다고 보면 된다.

 

 

Decorator
Decorator란 함수를 장식하는 기능으로, 함수를 수정하지 않고 함수에 추가 기능을 구현할 때 사용된다.

Decorator의 원리
어떤 함수가 정의될 때 decorator를 사용하기로 했으면(@로 지정), 정의된 코드 대신 decorator가 리턴한 함수 '이름'(소괄호를 사용하지 않음)에 해당하는 함수가 실행된다.
Decorator가 적용되었을 때 원래 함수의 코드를 실행하고 싶다면 decorator함수 내부의 함수 정의 공간에 argument로 받은 함수를 호출하면 된다.

Decorator 정의 구조: func_name은 장식 대상의 함수 이름이 들어간다.
Decorator의 대표적인 구조는 아래와 같다.
#==========================
def deco(func_name):
    def deco_func1(*args): #decorator 대상 함수의 arguments를 전부 tuple 형태로 수신
        #codes for decoration
        func_name() #원래 함수의 코드 실행
        #codes for decoration

    def deco_func2(*args): #decorator 대상 함수의 arguments를 전부 tuple 형태로 수신
        #codes for decoration
        func_name() #원래 함수의 코드 실행
        #codes for decoration

    if condition:
        return deco_func1
    else:
        return deco_func2
#==========================

Decorator 사용 방법: decorator 이름 앞에 @를 붙인다.
데코레이터는 2개 이상 적용할 수 있다. 이때 decorator 실행 순서는 위에서 아래이다.
ex)
@deco
def hello():
    print("hello")

Decorator 예시
#==========================

def deco(func):
    
    def internal(*args):
        args = list(args)
        print(func.__name__,"called!!")
        print("a is", args[0], "b is", args[1])
        args[2] = True
        func(*args)
        
    def internal2(*args):
        args = list(args)
        print(func.__name__,"called!!!!!!!!!")
        print("a is", args[0], "b is", args[1])
        args[2] = True
        func(*args)
        
    if True:
        return internal
    else:
        return internal2

@deco
def add(a, b, isdecorated):
    print(a+b)
    print("isdecorated =", isdecorated)
    
add(6, 8, False)


#==========================
(출력정보)
add called!!
a is 6 b is 8
14
isdecorated = True

 

상속
상속이란, 부모클래스의 멤버변수, 멤버함수를 자식클래스가 사용할 수 있도록 하는 기능이다.
상속 형태: 자식 클래스의 이름 옆에 괄호를 치고 그 안에 부모클래스를 기입
class ParentClass:
    #codes

class ChildClass(ParentClass):
    #codes


메소드 오버라이딩
자식 클래스에서 부모클래스와 이름이 동일한 멤버함수를 정의할 수 있다.
그러면 자식클래스로 만들어진 객체는 이름이 동일한 멤버함수가 있을 때, 자식클래스에서 정의된 함수가 호출된다.
만약 자식 클래스로 만들어진 객체에서 (오버라이딩된 함수 한정)부모클래스의 함수를 호출하고 싶다면 함수 이름 앞에 super(). 을 붙인다.

(주의!) super()함수는 클래스 정의 내부에서만 사용할 수 있다. 클래스 정의 밖에서 호출하면 error

관련글 더보기