2023-07-10
2023.07.07 - [LG 헬로비전 DX DATA SCHOOL/Python] - Python - 제어문과 함수
Python - 제어문과 함수
2023-07-07 이전 Python 기초 내용을 보고싶으신 분은 아래를 클릭하세요! 2023.07.06 - [LG 헬로비전 DX DATA SCHOOL/Python] - Python 기초 Python 기초 2023-07-06 Python 파이썬은 프로그래밍언어 작성 후, 컴파일이 아
dxdata.tistory.com
앞의 제어문과 함수의 내용을 보실 분들은 윗 글을 눌러주세요.
오늘은 파이썬 함수에 대해 추가적으로 알아보도록 하겠습니다.
Python
일을 시킬 때 -> 함수가 좋다
저장을 할 때 -> 객체가 좋다
따라서, 처리와 일에는 파이썬/ 에코 시스템 제작은 자바가 좋다.
파이썬은 람다(메모리에 남겨놓지 않을 함수)를 한 줄로 밖에 작성이 불가하다. <-> 자바는 람다 사용에 유리함.
CI/CD는 무중단이 핵심이다.
map : 변환
filter : True/False 인 조건에 맞는 데이터
Function
1. 함수형 프로그래밍 관련 함수
1) map
- 데이터를 변환하기 위한 함수
- 이 함수에 하나의 매개변수를 갖고 하나의 데이터를 리턴하는 함수를 대입하면 리턴하는 데이터들을 모아서 리턴합니다.
- 반복문을 이용해서 직접 변환하는 것도 속도가 훨씬 빠릅니다.
li = [i for i in range(10000)] # 0부터 9999까지의 숫자를 가지고 list 생성
temp = [] #반복문을 이용한 변환
for x in li :
temp.append(x * x)
print(temp)
def f(x) :
return x*x
#li의 모든 요소에 f 함수를 적용해서 변환한 결과를 temp에 대입
temp = list(map(f, li)) # map을 이용한 변환
print(temp)
#람다 사용
#함수의 내용이 한 줄 이므로 람다로 처리
temp = list(map(lambda x : x*x , li))
2) filter
-
컬렉션과 리턴 타입이 bool 인 함수를 매개변수로 받아서 컬렉션의 모든 데이터를 함수의 매개변수로 대입해서 리턴되는 결과가 True인 경우만 iterator 인스턴스로 리턴하는 함수
-
대입되는 함수는 하나의 매개변수를 받아서 bool 을 리턴하는 함수 이어야 함
print(None in ar)
#이름이 3자 이상인 데이터만 출력
#None 확인 및 제거
def f1(x) :
return x != None
ar = list(filter(f1, ar))
print(ar)
def f2(x) :
return len(x) >= 3
result = list(filter(f2, ar))
print(result)
ar = list(filter(lambda x : x != None , ar))
print(ar)
result = list(filter(lambda x : len(x) >= 3, ar))
print(result)
result = list(filter(lambda x : x[0] >= "아" and x[0]< "자" , ar))
print(result)
3) reduce
- 데이터의 모임을 가지고 연산을 수행해서 하나의 결과를 만들어내는 작업
- 파이썬에서는 예전에는 기본함수였으나, 지금은 functools 내 함수로 변경이 됨. -> 매개변수가 2개이고 하나의 결과를 만들어내는 함수를 대입해야함.
4) zip(내장함수)
- 여러 개의 데이터 모임을 받아서 하나의 데이터로 묶어주는 함수
- 데이터는 tuple로 묶어줍니다.
- 데이터의 모임에 데이터 개수가 일치해야 합니다.
value = ["만재국민학교", "광주서중", "명덕고등학교"]
print(list(zip(key, value)))
print(dict(zip(key, value)))
5) High Order Function(고위 함수)
- 함수를 매개변수로 받거나 함수를 리턴하는 함수
6) 중첩 함수
- 파이썬에서는 함수 내부에 함수를 만들 수 있습니다.
- 파이썬의 함수는 기본적으로 함수 외부에 직접 접근하는 것은 불가능. => 함수 내부에서 변수를 만들면 무조건 지역 변수로 생성.
- 내부에 만든 함수는 자신을 포함한 함수의 데이터에 접근하는 것이 가능합니다.
- 외부 함수는 내부 함수의 데이터에 접근하는 것이 안됨
- 내부 함수는 함수 외부에서 직접 호출이 안됨
- 함수 내부에서 데이터를 읽기만 하는 경우는 자신에게서 생성안되어 있는 경우에는 외부에서 변수를 찾아서 읽기를 수행하는데, 함수 내부에서 데이터를 생성(대입하는 연산자를 사용)하는 경우에는 내부의 데이터를 사용하는데 이 경우에는 반드시 먼저 생성하는 문장이 있어야 합니다.
- 함수를 만들어서 호출을 하면 먼저 함수 내부를 확인해서 함수 내부에 대입문이 있으면 대입문에 사용된 이름들을 로컬 변수로 간주를 하고 함수를 호출할 때 변수의 이름만 사용하면 로컬에 있는 변수를 호출하는 문장으로 해석하고 로컬 변수가 아닌 변수 이름을 사용하면 함수 외부에서 만든 것으로 간주합니다.
Global : 모든 곳에서 사용가능한 데이터 블럭 외부에서 생성
Member : Class 내부에 선언해서 Instance가 사용
Local : 함수 내부에서 함수 내부에서만 사용이 가능한
outer_data = "외부 함수의 데이터"
def inner () :
inner_data = "내부 함수의 데이터"
#local.outer_data를 inner에 쓸려면 있어야 할 위치
print(outer_data) #local.outer_data
#outer_data = "내부에서 외부 함수 변경" #local variable 'outer_data' referenced before assignment
print(outer_data) #local.outer_data
inner()
print(outer_data)
7) nonlocal 과 global
- 함수 내부에 nonlocal 이나 global 이라는 키워드와 함께 변수 이름을 기재하면 함수 내부에서 변수 이름을 이용해서 지역 변수를 만들 수 없게 되고 nonlocal 을 기재한 경우는 자신의 외부에서부터 데이터를 찾아가게 되고 global을 붙이면 최상위 레벨의 데이터를 사용합니다.
outer_data = "외부 함수의 데이터"
def inner () :
nonlocal outer_data #함수 완전 밖에 변수가 존재할 시, global로 바꾸면 됨
print(outer_data) #nonlocal.outer_data
print(outer_data) #nonlocal.outer_data
inner()
print(outer_data)
outer()
a = outer()
- 동일한 이름의 변수가 최상위 레벨에 존재하는 경우는 nonlocal이 아니고 global로 만들어야 한다.
- 동일한 이름의 변수를 여러 번 사용하면 이러한 문제가 발생할 수 있기 때문에 변수의 이름을 중첩되지 않게 잘 만들어야 하는데 예전에는 이 문제를 유효 범위를 표시해서 해결했는데 로컬 변수의 이름 앞에는 _, 멤버 변수의 이름 앞에는 m_, 전역 변수의 앞에는 g_를 붙이기도 했다.
8) closure
함수 내부에서 만든 함수를 리턴해서 함수 외부에서 함수 내부의 데이터를 변경할 목적으로 사용
- 함수 안에서 만든 데이터는 함수를 호출하고 나면 소멸됨.
- 함수 내부와 외부에서 데이터를 공유하고자 하는 경우 전역 변수를 만들어서 사용할 수 있는데 구조적 프로그래밍이나 객체 지향 프로그래밍에서는 전역 변수를 만드는 것을 권장하지 않습니다.
- 이런 경우 closure를 이용해서 사용하기를 권장합니다.
amore = "아모르파티"
#자신을 감싸고 있는 함수의 데이터를 수정하는 함수
def inner() :
nonlocal amore
amore = amore + "아모르"
print(amore)
#함수 내부의 데이터를 수정하는 함수를 리턴하는 함수를 closure 라고 한다.
return inner
closure = outer() #함수를 호출해, 리턴하는 함수를 변수에 저장
closure()
Business Logic
: 실제 업무
Common Concern(공통 관심 사항)
: 업무와 직접적인 관련이 없는 (로그인, 로깅 등)
위 두개를 분리해서 프로그래밍을 하고, 추후에 결합하자!
2. Decorator
- 로직을 수행하기 전이나 수행한 후에 해야 할 일을 별도의 메서드로 만들어두고 @함수이름으로 대신하도록 하는 것
- 생성 작업이 복잡하거나 알 필요가 없는 경우 또는 business logic(업무 로직)과 common concern(공통 관심 사항-로깅이나 벤치마크를 위한 테스트 코드 등)을 분리하고자 하는 경우 사용한다.
func()
print("로깅")
@amore
def businessLogic():
print("비지니스 로직")
businessLogic()
- decorator를 만들 때 대부분의 경우는 함수를 리턴해서 리턴한 함수가 수행되도록 합니다.
- decorator에 전달된 매개변수를 이용해서 함수의 이름이나 전달된 인수 그리고 리턴 값도 확인할 수 있습니다.
- 함수를 호출할 때 마다 실행에 걸린 시간, 인수, 리턴 값을 출력하는 decorator를 생성
def clock(func) :
#decorator 가 적용된 함수가 호출되면 수행될 실제 함수
def clocked(*args) :
#업무 로직 함수를 호출
start = time.time() #현재 시간을 기록
result = func(*args)
end = time.time()
elapsed = end - start #함수의 수행시간
print("수행시간 :", elapsed)
#매개변수 확인
print("매개변수 :", args)
#리턴값
print("리턴값 :", result)
return result
return clocked
@clock
def myfunc(n) :
a = "dx "
b = "data \n"
result = (a+b) * n
return result
myfunc(10)
%%decorator는 매우 중요%%
- 표준 라이브러리에서 제공하는 데코레이터
- functools 패키지에서 제공하는 lru_cache() 라는 데코레이터를 이용하면 중복된 함수 호출이 있는 경우 함수를 호출하지 않고 결과를 재사용할 수 있다.
- lru는 무한정 캐싱되는 현상을 방지하기 위해서 오랫동안 사용하지 않은 데이터를 캐시에서 제거하는 알고리즘
3. OOP(Object Oriented Programming - 객체 지향 프로그래밍)
개요
1) 3대 특징
- Encapsulation(캡슐화)
불필요한 정보는 숨기고 중요한 정보 만을 표현해서 프로그램을 간단하게 만드는 것(인터페이스를 간단하게 만드는 것)
- Inheritance(상속)
하위 클래스가 상위 클래스의 모든 요소를 물려받는 것
- Polumorphism(다형성)
동일한 메시지에 대하여 다르게 반응하는 성질
2) 용어
- Object(객체) : 프로그램에 사용되는 모든 것
- Class : 사용자 정의 자료형
동일한 목적을 달성하기 위해 모인 속성(데이터)과 메서드(기능 - 함수)의 집합
정적(static) : 한 번 만들면 변경되지 않는
- Instance : Class를 기반으로 메모리 할당을 받은 객체
동적(Dynamic): 변경 가능한
- 정적 바인딩과 동적 바인딩
정적 바인딩은 실행 전에 결정되는 것 - 변수를 만들 때 자료형을 명시적으로 작성하거나 암묵적으로 결정해두고 사용하기 때문에 실행 중에 변수에 다른 종류의 데이터를 삽입할 수 없음.
동적 바인딩은 실행 중에 결정 가능한 것 - 참조형 데이터만 존재하고 변수는 데이터의 참조를 저장하기 때문에 실행 중에도 다른 종류의 데이터를 대입할 수 있음.
- 속성(attribute) : Instance를 구성하는 데이터
- method : Class 안에 만들어진 기능(함수)
- property : 속성처럼 사용하는데 실제로는 method를 호출하는 것
- record 나 structure(구조체) : 하나의 행을 의미, Instance를 구성하는 속성의 집합
- python의 모든 데이터는 기본적으로 instance
- Information Hiding(정보 은닉) : 불필요한 부분을 숨기는 것
3) Class 와 Instance
1))클래스 생성
class 클래스 이름 :
초기화 메서드 생성
메서드 생성
2))인스턴스 생성
- 인스턴스 이름 = 초기화 메서드(매개변수) -> 초기화 메서드의 이름은 클래스 이름
- 인스턴스를 생성하는 메서드를 호출하면 인스턴스를 생성하고 그 참조를 리턴
3))인스턴스나 클래스를 이용한 멤버 호출
- 인스턴스나 클래스.속성
- 인스턴스나 클래스.메서드(매개변수)
4)) Method
- 인스턴스가 있어야 만 호출되는 메서드와 인스턴스가 없어도 호출되는 메서드(static, class)로 구분
- 인스턴스가 없어야 하는 메서드 생성
def 메서드 이름(인스턴스를 참조를 저장할 매개변수[, 매개변수 나열]) :
내용
관례상 인스턴스 참조를 저장할 매개변수의 이름은 self
- 인스턴스가 있어야 하는 메서드 호출
클래스 이름.메서드 이름(인스턴스, 매개변수) : Unbound 호출
인스턴스.메서드 이름(매개변수) : Bound 호출
클래스 내부의 다른 메서드에서 호출 : self.메서드이름(매개변수)
5) 인스턴스의 속성 만들기
- 파이썬에서 인스턴스의 속성을 만들고자 하는 경우에는 인스턴스가 있어야 호출되는 메서드 안에서 self.속성명으로 데이터를 대입하면 만들어 집니다.
- 클래스 외부에서 인스턴스.속성이름 = 데이터 코드를 작성하면 속성이 존재하면 속성의 값을 변경하는 것이고 속성이 존재하지 않으면, 속성이 생성된다.
6) 클래스 속성 만들기
- class 내부 그리고 method 외부에 변수를 생성해서 데이터를 대입하면 class 속성이 됩니다.
- class 의 속성은 클래스와 인스턴스 모두 접근이 가능하다.
- 인스턴스를 이용해서 접근할 때 그 속성이 인스턴스 내부에 없으면 class 속성을 호출하지만 인스턴스 내부에 존재하면 인스턴스의 속성을 호출합니다.
- 대입문을 이용하면 인스턴스의 속성을 생성해서 사용한다.
- 클래스 속성은 인스턴스를 이용해서 접근하는 것을 권장하지 않는다.
7) is 연산자
- python의 변수는 데이터를 저장하고 그 데이터의 id를 저장하는 개념
- == 연산자는 목적이 id를 비교하는 것이 아닙니다. 파이썬에서는 == 연산자는 내부에 만든 __eq__ 메서드를 호출해서 그 결과를 리턴하는 연산자입니다.
- id를 비교하는 연산자는 is 연산자이며, 오버로딩이 안되기 때문에 명확하게 id를 비교한다고 할 수 있습니다.
class_data = "클래스의 속성"
#인스턴스 생성해서 대입
stu1 = Student()
#인스턴스 생성해서 대입
stu2 = Student()
#stu1 의 데이터를 대입 : stu1 이 참조하고 있는 데이터의 참조를 stu3가 참조합니다.
stu3 = stu1
print(stu1 == stu2) #내부의 데이터가 같은지 확인
print(stu1 is stu2) #id가 같은지 확인
print(stu1 is stu3)# true
print(stu1 == stu3)# true
8) Accessor - 접근자 메서드
- 객체 지향 언어에서는 인스턴스를 가지고 속성에 직접 접근하는 것을 권장하지 않는다.
- 속성에 접근하는 메서드를 이용해서 속성의 값을 가져다가 사용하고 수정하도록 한다.
속성의 값을 리턴하는 메서드를 getter 라고 하며, 속성의 값을 수정하는 메서드를 setter 라고 한다.
- getter
이름은 get속성이름으로 하고 매개변수는 일반적으로 없고 속성을 리턴하기만 합니다.
속성의 자료형이 bool 인 경우 get 대신에 is를 붙인다.
속성의 이름의 첫글자는 대문자로 표기하는데 파이썬에서는 대문자 대신에 _를 사용하는 경우가 있다.
- setter
이름은 set 속성이름으로 하고 매개변수는 속성과 동일한 자료형의 데이터 1개로 생성
내용은 매개변수로 받은 데이터를 속성에 대입합니다.
- 속성의 자료형이 Sequence(list) 인 경우
인덱스를 받아서 인덱스 번째 데이터를 리턴하는 getter를 추가로 생성하고 인덱스 와 데이터 1개를 받아서 인덱스 번째 데이터를 수정하는 setter를 생성하기도 한다.
class Student :
def getName(self): #매개변수 없음
return self.name
def setName(self, name): #자료형과 동일한 매개변수 1개
self.name = name
def getScore(self):
return self.score
def setScore(self, score):
self.score = score
#인스턴스 생성
stu1 = Student()
#setter를 이용한 속성 생성과 설정
stu1.setName("애니")
stu1.setScore(98)
#getter를 이용한 속성 사용
print(stu1.getName())
print(stu1.getScore())
#최근 등장 IDE는 대부분 getter 와 setter를 만드는 유틸을 제공합니다
수고하셨습니다!
ps) 인스턴스란, 어떤 클래스에 속하는 각 객체들을 지칭하는 말이다. (객체 지향 프로그래밍)
'LG 헬로비전 DX DATA SCHOOL > Python' 카테고리의 다른 글
Python 예외처리 / File handling (0) | 2023.07.14 |
---|---|
파이썬 Data Type 및 처리 (0) | 2023.07.11 |
객체 지향 프로그래밍 (OOP) (0) | 2023.07.11 |
Python - 제어문과 함수 (0) | 2023.07.07 |
Python 기초 (0) | 2023.07.06 |