python wecode TIL day-5

yo·2020년 5월 29일
0

09:30 in
1:30 out
16hrs

주절주절

-뭔가 이루기로 마음 먹었다면 반드시 할 수 있다고 믿는게 첫 번째다. -머니맨-
-decorator는 python학습을 단념시키기 위해 파이썬 개발자에 의해 고도로 설계된 것임이 틀림없다.
-티타임 중 이상록멘토님이 본인 수강생 시절 어떻게 살았는지를 들려주셨다.
-나름 열심히 하고 있다 생각했는데 그걸 듣고 아님을 알게 되었다.
-상록님은 새벽 5시에 일어나서 운동하고 여기로 오셨다고...안되면 새벽2,3시고 뭐고 될 때 까지.
-큰 동기부여가 되었다. 지나고 나서 "야씨 나 그때 진짜 열심히 했어" 라고 말할 수 있게 하자.
-멘토님들도 나랑 똑같이 도저히 이해가 안되는 것들이 있어서 너무 힘들었다는 얘기를 하셨는데, 위안이 되었다.
-첫 술에 배부를 수 없다, 씨를 뿌리자 마자 거둘 수 없다.
-보통 4년 이상 갈고 닦아 취직한다.
-최선을 다하되, 하루에 잠 1시간만 자고 3개월 한다 해도 여전히 beginner 임을 알고 인정하자.
-힘들지만 오늘도 재밌었다. 다행이다. 내가 재밌어 해서 다행이다.
-막차도 끊겼다. 택시다.

Generator

제너레이터: 시퀀스를 생성하는 객체
예)range()함수가 반환하는 객체
yield문 사용

def my_range(first=0, last=10, step=1):
  number = first
  while number < last:
    yield number
    number += step
ranger = my_range(1,5)
for x in ranger:
  print(x)
 
 #결과
 1
 2
 3
 4

Decorator

-하나의 함수를 취해서 다른 함수를 반환하는 함수

def document_it(func):
  def new_function(*args):
    print("실행 함수명:", func.__name__)
    print("args 인수",args)
    result = func(*args)
    print("함수호출결과:", result)
    return result
  return new_function
def add_ints(a,b):
  return a + b
cooler_add_ints = document_it(add_ints)
result = cooler_add_ints(3,5)
print(result)
    
#결과
실행 함수명: add_ints
args 인수 (3, 5)
함수호출결과: 8
8

위의 코드와 정확히 같은 내용의 코드를 데코레이터를 활용해 만들어 보자.

def document_it(func):
  def new_function(*args):
    print("실행 함수명:", func.__name__)
    print("args 인수",args)
    result = func(*args)
    print("함수호출결과:", result)
    return result
  return new_function


@document_it
def add_ints(a,b):
  return a + b
  
result = add_ints(3,5)
print(result)

#결과
실행 함수명: add_ints
args 인수 (3, 5)
함수호출결과: 8
8

데코레이터를 두 개 적용할 수도 있다.

def document_it(func):
  def new_function(*args):
    print("실행되는 함수명:", func.__name__)
    print("args인수:", args)
    result = func(*args)
    print("함수 호출 결과:", result)
    return result
  return new_function
  
def square_it(func):
  def new_function(*args):
    print("new_function")
    print("args 인수:", args)
    result = func(*args)
    return result * result
  return new_function

@square_it
@document_it
def add_int3(a, b):
  return a + b
  
result = add_int3(3,5)
print(result)

결과:
new_function
args 인수: (3, 5)
실행되는 함수명: add_int3
args인수: (3, 5)
함수 호출 결과: 8
64

데코레이터의 순서를 바꾸면 다른 결과가 도출된다.

def document_it(func):
def new_function(args):
print("실행되는 함수명:", func.name)
print("args인수:", args)
result = func(
args)
print("함수 호출 결과:", result)
return result
return new_function

def square_it(func):
def new_function(args):
print("new_function")
print("args 인수:", args)
result = func(
args)
return result * result
return new_function

@document_it
@square_it
def add_int3(a, b):
return a + b

result = add_int3(3,5)
print(result)


결과#
실행되는 함수명: new_function
args인수: (3, 5)
new_function
args 인수: (3, 5)
함수 호출 결과: 64
64

또 다른 데코레이터 예제

Scope

-범위
-프로그래밍에서 scope는 어떤 객체(변수, 함수 등)가 유효한 범위를 뜻한다.
-Python에서 범위는 항상 객체가 선언된 지점에서 위로는 상위객체까지, 아래로는 모든 하위객체들과 그 안에까지다.

크게 4가지 범위가 있다.
Local Scope
Enclosed Scope
Global Scope
Built-in Scope

Local Scope

Local scope을 가지고 있는 변수나 함수 혹은 객체는 이름 그대로 특정 범위에서만 유효합니다.
주로 함수 안에서 선언된 변수나 함수가 local scope을 가지고 있습니다. 그리고 이러한 변수들은 해당 함수 안에서만 유효합니다.

Enclosing Scope

Enclosing Scope는 중첩함수가 있을때 적용되는 scope입니다.
부모 함수에서 선언된 변수는 중첩함수 안에서도 유효한 범위를 가지고 있습니다.

Global Scope

Global scope은 함수 안에서 선언된것이 아닌 함수 밖에서 선언된 변수나 함수를 이야기 합니다.
본 강의에 앞부분에서 설명했듯이, 변수나 함수는 선언된 지점과 동일한 level의 지역, 그리고 더 안쪽의 지역들까지 범위가 유효합니다.

그리고 global scope을 가지고 있는 변수와 함수들은 선언된 지점이 해당 파일에서 가장 바깥쪽에서 선언되므로 해당 파일에서 선언된 지점 아래로는 다 유효한 범위를 가지고 있습니다. 그래서 "Global" scope 이라고 하는 것입니다.

Built-in Scope

Built-in scope은 scope중 가장 광범위한 scope입니다.
파이썬안에 내장되어 있는, 파이썬이 제공하는 함수 또는 속성들이 built-in scope를 가지고 있습니다.
그리고 built-in scope는 따로 선언이 없이도 모든 파이썬 파일에서 유효한 범위를 가지고 있습니다.
예를 들어, list등과 같은 자료구조의 element 총 개수를 리턴하는 len 함수가 바로 built-in scope를 가지고 있습니다.

Shadowing

파이썬은 변수나 함수의 정의를 찾을때 다음 순서의 scope들 안에서 찾습니다.

Local => Enclosing => Global => Built-in

즉 가장 좁은 유효범위 부터 시작 해서 넓은 범위로 나아가며 사용되는 변수나 함수의 정의를 찾습니다.
그러므로 만일 동일한 이름의 변수들이 서로 다른 scope에서 선언이 되면 더 좁은 범위에 있는 변수(혹은 함수)가 더 넓은 범위에 있는 변수를 가리는 (shadowing)효과가 나타납니다.

Class

-클래스 안에서 구현된 함수는 함수라 하지 않고 메서드라 지칭한다.
-파이썬 메서드의 첫 번째 매개변수 이름으로 self를 사용한다.(관례적)
-클래스 만들기 문법
-인스턴스와 객체의 차이점:
둘 다 비슷. 인스턴스는 클래스와 연관지어 말할 때 사용한다(이건 이 클래스의 인스턴스다).
a = list(range(10))
a는 객체고 list의 object다.
-매서드(def)만들면 무조건 parameter 처음값 self로 줘야한다.
-객체에서 메서드 호출할 때 <객체>.<메소드> 방식 사용하고, 이를 dot notation 방식이라 한다.

class 클래스이름:
    def 메서드이름(self):
        코드

-클래스의 instance 만들기

 인스턴스 이름 = 클래스()

-메서드 호출하기. (메서드는 클래스가 아니라 인스턴스를 통해 호출함
-이렇게 인스턴스를 통해 호출하는 메서드를 인스턴스 메서드라고 부른다.
인스턴스.메서드()

속성 만들기

__init__ 을 사용하여 만든다.
initialize라는 뜻으로 인스턴스(객체)를 초기화한다.
-앞뒤로 밑줄 두개가 붙은 메서드는 파이썬이 자동호출 해주는 스페셜메서드 또는 메직메서드라 부른다.
-속성은 init메서드 안에서 사용한다는 것과 self.hello처럼 self에 점을 붙여 사용한다는 것이 중요하다.
-self는 인스턴스 자기 자신을 의미

class Person:
  def __init__(self):
    self.hello = "안녕하세요"
    
  def greeting(self):
    print(self.hello)
    
Michael = Person()
print(Michael.greeting())

결과
안녕하세요

비공개속성

-중요한 값이라 바깥에서 함부로 바꾸지 못하게 할 때 사용.
문법

class 클래스이름:
    def __init__(self, 매개변수):
         self.__속성 = 값

-비공개 클래스 속성

def 클래스이름:
    __속성 = 값

비공개 속성 사용하여 메서드 만든 예시

class Person:
  def __init__(self, name, age, sex,wallet):
    self.hello = " hi"
    self.name = name
    self.age = age
    self.sex = sex
    self.__wallet = wallet
  def greeting(self):
    print(f"{self.hello} I'm {self.name}, {self.age}, {self.sex}")
    print(f"I only have {self.__wallet}")
    
  def money(self, pay):
    self.__wallet -= pay
    print(self.__wallet)
    
hi = Person("kim", 27, "male", 10000)
print(hi.greeting())
print("name:", hi.name)
print("age:", hi.age)
print("sex:", hi.sex)
print(hi.money(300))
print(hi.money(3000))

결과
 hi I'm kim, 27, male
I only have 10000
None
name: kim
age: 27
sex: male
9700
None
6700

클래스 속성과 인스턴스 속성

-클래스 속성: 모든 인스턴스가 공유. 인스턴스 전체가 사용해야 하는 값을 저장할 때 사용
-인스턴스 속성: 인스턴스별로 독립되어 있음. 각 인스턴스가 값을 따로 저장해야 할 때 사용



클래스 연습한 것들

class Person:
  def __init__(self, name, age, sex):
    self.hello = " hi"
    self.name = name
    self.age = age
    self.sex = sex
    
  def greeting(self):
    print(f"{self.hello} I'm {self.name}, {self.age}, {self.sex}")
    
hi = Person("kim", 27, "male")
print(hi.greeting())
print("name:", hi.name)
print("age:", hi.age)
print("sex:", hi.sex)

결과
hi I'm kim, 27, male
None
name: kim
age: 27
sex: male

Modules

-모듈 불러오기: import <모듈 이름>
-확장자인 ".py"는 제외하고 파일 이름만 적어야 함.
-모듈 import 후, 모듈의 원하는 변수/함수/클래스 사용하는 방법.
모듈이름.사용원하는 변수/함수/클래스 이름/

import my_module

print(my_module.my_module_var)

my_module.my_module_func()

my_module_class = my_module.MyModuleClass()

Alternative ways to import modules

문법

from <모듈 이름> import <함수/변수/클래스1>, <함수/변수/클래스2>, ..., <함수/변수/클래스N>

예시

from my_module import my_module_func, my_module_var

print(my_module_var)
my_module_func()

위 방법은 모듈에서 사용하는 것이 명확할 때 사용하면 편리하다.

*사용하기

*사용 시 해당 모듈의 모든 요소가 곧바로 import 된다.

from my_module import *

print(my_module_var)
my_module_func()

하지만 이 방법은 권장안한다. 왜냐면 local scope를 가지고 있는 다른 변수/함수/클래스 들과 이름 충돌이 날 수 있는데, 만일 이름 충돌이 발생할 경우 알기 쉽지 않을 수 있다.

Import as

모듈 import시 이름이 충돌할 수 있다(예.서로 다른 모듈에서 동일한 이름 가진 함수 호출). 혹은 모듈 요소 이름이 너무 길 수도 있다.
이럴 때 import as를 사용해 새 이름 부여할 수 있다.

from my_module  import my_func as f1
from my_module2 import my_func as f2
from my_module3 import function_with_name_too_long as f3

f1()
f2()
f3()

as로 모듈 자체 이름도 새롭게 할 수 있다.

import my_module as m1

m1.my_module_func()

Packages

-module처럼 다른 파일 불러오는 개념.
-module보다 크고 복잡한 개념.
-모듈이 소대라면 패키기는 중대, 뭐 이런 느낌?

Package는 파이썬 파일들로 이루어져 있는 디렉토리(directory)가 하나의 package가 됩니다. 그리고 디렉토리 이름이 package 이름이 됩니다.


-import할 때 "dot notation을 사용한다.

import pkg.mod1
from pkg.mod2 import func2

pkg.mod1.func2()
func2()

package Initialization

가끔은 package가 import될 때 초기 설정을 해줘야 할 때가 있다.
파이썬은 __init__.py 파일을 통해 package 초기 설정을 가능하게 해준다.

Package안에 __init__.py 파일이 있으면 package가 import될 때 __init__.py파일의 코드들이 자동으로 실행된다.
__init__.py로 할 수 있는 것들은 뭐가 있나?
1) Import 할때 경로의 총 길이 줄여주기
2)Package에서 import 할 수 있는 변수/함수/클래스 제한하기
3)그 외 package가 import될때 꼭 먼저 실행되어야 하는 코드들


profile
Never stop asking why

0개의 댓글