=======================
학습내용
Python Object Oriented Programming
파이썬 함수/변수 이름에는 snake_case
파이썬 Class에는 CamelCase
- Attribute 추가는 __init__, self와 함께
__init__은 객체 초기화 예약 함수
- __는 특수한 예약 함수나 변수 그리고 함수명 변경(맨글링)으로 사용
예) __main__ , __add__ , __str__ , __eq__
class SoccerPlayer(object):
def __init__(self, name, position, back_number):
# self는 나중에 생성할 인스턴스 자신의 주소. 함수마다 앞에 꼭 붙여야됨.
self.name = name
self.position = position
self.back_number = back_number
def change_back_number(self, new_number):
print("선수의 등번호를 변경합니다 : From %d to %d" % \
(self. back_number, new_number))
self.back_number = new_number
def __str__(self):
return "Hello, My name is %s. My back number is %d" % \
(self.name, self.back_number)
def __add__(self, other):
return self.name + other.name
abc = SoccerPlayer("son", "FW", 7)
park = SoccerPlayer("park", "WF", 13)
abc + pack # 'sonpark'
print(abc) # "Hello, My name is abc. My back numer is 7"
abc.back_number # 7
OOP characteristics
Inheritance 상속, Polymorphism 다형성, Visibility 가시성
상속
class Person(object): # 또는 class Person: # 부모 클래스 선언
def __init__(self, name, age):
self.name = name
self.age = age
class Korean(Person):
pass
first_korean = Korean("Sungchul", 35)
print(first_korean.name)
Sungchul
class Person(object): # 또는 class Person: # 부모 클래스 선언
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def about_me(self):
print(f"저의 이름은 {self.name}이구요, 제 나이는 {self.age}살 입니다.")
def __str__(self):
print(f"저의 이름은 {self.name}이구요, 제 나이는 {self.age}살 입니다.")
class Empolyee(Person): # 부모 클래스 Person으로 부터 상속
def __init__(self, name, age, gender, salary, hire_date):
super().__init__(name, age, gender) # 부모객체 사용
self.salary = salary
self.hire_date = hire_date
def do_work(self):
print("열심히 일을 합니다.")
def about_me(self):
super().about_me()
print(f"제 급여는 {self.salary}원 이구요, 제 입사일은 {self.hire_date} 입니다.")
myPerson = Person("John", 34, "Male")
myEmployee = Empolyee("Daeho", 34, "Male", 30000, "2012/03/01")
myPerson.about_me()
myEmployee.about_me()
저의 이름은 John이구요, 제 나이는 34살 입니다.
저의 이름은 Daeho이구요, 제 나이는 34살 입니다.
제 급여는 30000원 이구요, 제 입사일은 2012/03/01 입니다.
Polymorphism 다형성
- 같은 이름의 메소드의 내부 로직을 다르게 작성
- Dynamic Typing 특성으로 인해 파이썬에서는 같은 부모클래스의 상속에서 주로 발생함
- 중요한 OOP의 개념 그러나 너무 깊이 알 필요X
자바의 오버라이딩 같은거인듯
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Cat('Mr. Mistoffeless'),
Dog('Lassie')]
for animal in animals:
print(animal.name + ": " + animal.talk())
Missy: Meow!
Mr. Mistoffeless: Meow!
Lassie: Woof! Woof!
Visibility 가시성
- 객체의 정보를 볼 수 있는 레벨을 조절하는 것
- 누구나 객체 안에 모든 변수를 볼 필요가 없음
Encapsulation
캡슐화 또는 정보 은닉 (Information Hiding)
Decorator
- first-class objects
- inner function ★
- decorator ★
first-class objects
- 일등함수 또는 일급 객체
- 변수나 데이터 구조에 할당이 가능한 객체
- 파라메터로 전달이 가능 + 리턴 값으로 사용
파이썬의 모든 함수는 일급함수
map(f, ex)
def square(x):
return x*x
f = square # 함수를 변수로 사용
f(5)
def square(x):
return x*x
def cube(x):
return x*x*x
def formula(method, argument_list):
return [method(value) for value in argument_list]
a = [1, 2, 3, 4, 5]
print(formula(square, a))
print(formula(cube, a))
[1, 4, 9, 16, 25]
[1, 8, 27, 64, 125]
inner function ★
- 함수 내에 또 다른 함수가 존재
def print_msg(msg):
def printer():
print(msg)
printer()
print_msg("Hello, Python")
Hello, Python
- closures : inner function을 return값으로 반환
def func():
def printhi():
print("hi")
return printhi
hiin = func()
hiin()
hi
def print_msg(msg):
def printer():
print(msg)
return printer() ## 에러 !!! ! !!!!
another = print_msg("Hello, Python")
another()
TypeError: 'NoneType' object is not callable
def print_msg(msg):
def printer():
print(msg)
return printer
another = print_msg("Hello, Python")
another()
Hello, Python
def tag_func(tag, text):
tag = tag
text = text
def inner_func():
return '<{0}>{1}<{0}>'.format(tag, text)
return inner_func
h1_func = tag_func('title', 'This is python class')
p_func = tag_func('p', 'Data Academy')
print(h1_func)
print(h1_func())
print(p_func)
print(p_func())
<function tag_func.<locals>.inner_func at 0x000001E19238B0D0>
<title>This is python class<title>
<function tag_func.<locals>.inner_func at 0x000001E19238B160>
<p>Data Academy<p>
decorator function
- 복잡한 클로져 함수를 간단하게! (사실 더복잡함)
def star(func): # func는 printer(msg)
def inner(*args, **kwargs):
print("*" * 30)
func(*args, **kwargs)
print("*" * 30)
return inner
# @star를 썻기때문에 def star(func)의 func는 printer(msg)
@star
def printer(msg):
print(msg)
printer("Hello")
******************************
Hello
******************************
def star(func): # func는 printer(msg, mark)
def inner(*args, **kwargs):
print(args[1] * 30)
func(*args, **kwargs)
print(args[1] * 30)
return inner
# @star를 썻기때문에 def star(func)의 func는 printer(msg, mark)
@star
def printer(msg, mark):
print(msg)
printer("Hello", "&")
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
Hello
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
def star(func): # func는 printer(msg)
def inner(*args, **kwargs):
print('*' * 30)
func(*args, **kwargs)
# func 는
# @percent
# printer("Hello")
print('*' * 30)
return inner
def percent(func):
def inner(*args, **kwargs):
print('%' * 30)
func(*args, **kwargs)
# func 는
# printer("Hello")
print('%' * 30)
return inner
# 그냥 @는 위에서부터 차례대로 실행된다고 생각하면 편할듯
@star
@percent
def printer(msg):
print(msg)
printer("Hello")
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
그 다음은 조금 복잡한 함수를 볼거에요 ( = 아주 복잡하다 )
def generate_power(exponent):
def wrapper(f): # @에 매개변수 넣고 싶으면 한번 더 감싸야 한다.
print("in wrapper f : ", f)
def inner(*args):
print("in inner args : ", args)
result = f(*args) # 7**2
return exponent**result # 2**7**2
return inner
return wrapper
@generate_power(2)
def raise_two(n):
return n**2
print(raise_two)
print("----")
print(raise_two(7))
in wrapper f : <function raise_two at 0x0000018D9027B160>
<function generate_power.<locals>.wrapper.<locals>.inner at 0x0000018D9027B1F0>
----
in inner args : (7,)
562949953421312
Module and Project
패키지 안에 모듈
모듈은 프로그램에서 작은 프로그램 조각들, 조각들을 모아서 프로그램을 작성함.
패키지를 오픈소스에 공개! 한다는건 프로그램을 공개
모듈 만들기
- 파이썬의 Module == py 파일을 의미
- 같은 폴더에 Module에 해당하는 .py파일과
사용하는 .py을 저장한 후
- import 문을 사용해서 module을 호출
함수명을 불러서 쓸 수 있다.
namespace
- 모듈을 호출할 때 범위 정하는 방법
- 모듈 안에는 함수와 클래스 등이 존재 가능
- 필요한 내용만 골라서 호출 할 수 있음
- from과 import 키워드 사용함
Alias 별칭 설정하기
import fah_converter as fah
print(fah.convert_c_to_f(41.6)) # 어디서 왔는지 밝힐 수 있음
모듈에서 특정 함수 또는 클래스만 호출하기
from fah_converter import convert_c_to_f
print(covert_c_to_f(41.6)) # 원래 print(fah_converter.covert_c_to_f(41.6)) 해야했음.
모듈에서 모든 함수 또는 클래스를 호출하기
from fah_converter import *
print(covert_c_to_f(41.6))
파이썬 내장 함수 random, time, urllib.request 등이 있음.
패키지
- 하나의 대형 프로젝트를 만드는 코드의 묶음
- 다양한 모듈들의 합, 폴더로 연결됨
- __init__, __main__ 등 키워드 파일명이 사용됨
- 다양한 오픈 소스들이 모두 패키지로 관리됨
각각의 폴더 안에 __init__.py 라는 파일이 있어야 함.
각각 __init__.py 안에
__all__ = [사용할 파일이름, 사용할 파일 이름, ..]
from . import 사용할 파일이름
from . import 사용할 파일이름
..
그다음 루트폴더에 __main__.py 만들고
from sound import echo
if __name__ == '__main__':
print("hello game")
오픈소스 라이브러리 사용하기
두개 이상의 프로젝트를 불러오면 충돌할 수도 있다...
가상환경 설정하기
프로젝트 진행 시 필요한 패키지만 설치하는 환경
다양한 패키지 관리도구 사용 virtualenv, conda 등
conda create -n my_project python=3.8
conda activate my_project
conda install matplotlib
conda install tqdm
conda install jupyter
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()
===============================
과제
이번 모스부호 과제는 아니고 전 baseball 과제였는데 while문을 너무 많이 넣어서 딱 봐도 너무 복잡해 보인다.
딱 봐도 개판이다.
다른 피어분껄 봤는데, 각 경우를 함수로 빼내 사용했다고 한다. 그러니까
flag = False
for i in range(N):
for j in range(N):
if (어쩌구):
flag = True
break
if flag :
break
같은 걸 안했단 것 같다. 나도 이런거 하기 싫어 함수로 만들어 빼낸적이 몇번 있으니까 활용해야 될 것 같다.
=================================
피어세션
데코레이션이 어려워서 어떻게 보면 될지 회의했다. 난 함수 자체를 리턴해서 뒤에 괄호 () 를 붙여 실행시키는 걸로 결론지었다.
예를들면
def a():
return b
def b():
print("here")
a()()
하면
here
이 콘솔에 출력되고 끝난다. 그래서 B = a() 로 하면
a()() == B() 가 되는 개념.
댓글 없음:
댓글 쓰기