지금은마라톤중

멋사 AI스쿨 TIL - (7) 본문

멋쟁이사자처럼/Python

멋사 AI스쿨 TIL - (7)

달리는중 2023. 1. 6. 17:31

2023.01.06


7. class  ..ing

 

4) getter, setter

-객체의 내부 변수에 접근할  특정 메서드를 거쳐서 접근할  있도록 하는 방법

class Person:

    def __init__(self, pw):
        self.hidden_pw = pw
    
    # getter : 데이터를 가져올(출력) 때 사용
    # 가져올 때 뒤에 ***로 나오게 만듬
    @property
    def pw(self):
        print('getter')
        return self.hidden_pw

    
    # setter : 변수를 설정(수정)할 때  사용
    # pw 변경 시 기존에 있던 pw 입력해야 할 수 있는 설정
    @pw.setter
    def pw(self, new_pw):
        print('setter')
        input_pw = input('insert password : ')
        if input_pw == self.hidden_pw :
            new_pw = input('insert password : ')
            self.hidden_pw = new_pw
            self.hidden_pw = pw
        else:
            print('wrong password!')



person = Person( 'abcd')
person.pw # 출력 :getter \n  abcd
person.pw = 'qwer' # pw 입력란 뜨고 기존 pw와 맞으면 변경할 pw 입력하라고 뜸

 

 * non public

- mangling : 변수에 직접적으로 접근하는 것을 막는 방법

  - 사용법 : 변수명 앞에 __를 붙임

- 직접 설정은 안되고 setter를 통해서만 설정이 가능하다.

# 함수를 이용해서 getter, setter 구현하는 방법 
# 개인적인 차이지만 이 방법이 더 가독성이 좋다.
# mangling : hidden_pw 앞에 __ 써줌.
class Person:

    def __init__(self, pw):
        self.__hidden_pw = pw # __ : mangling

    def getter(self):
        print('getter')
        return self.__hidden_pw

    def setter(self, new_pw):
        print('setter')
        input_pw = input('insert password : ')
        if input_pw == self.__hidden_pw:
            self.__hidden_pw = new_pw
        else:
            print('wrong password!')

    pw = property(getter, setter)


person = Person('abcd')

# 출력 1 함수 이용한 getter, setter
# person.pw # 출력 :getter \n  abcd
# person.pw = 'qwer' # pw 입력란 뜨고 기존 pw와 맞으면 변경할 pw 입력하라고 뜸
# person.pw  

# 출력 2 mangling
person = Person('abcd')
person.__hidden_pw = 'qqqq'
person.pw # 출력 :getter \n  abcd

person.__hidden_pw = 'qqqq' # X
person.pw = 'wwww' # O

 

5) 메서드 종류

- 인스턴스 메서드 : 파라미터 self : 객체를 이용하여 메서드 호출

- 클래스 메서드 : 파라미터 cls : 클래스를 이용하여 메서드 호출 : 객체로 생성된 초기 변수값을 모두 수정

- 스태틱 메서드 : 파라미터 x : 객체를 선언하지 않고 메서드 호출 : 일반적인 함수라고 생각하면 됨

# 메서드 종류 설명
class Account:
    interest = 1.01 # 이자율 1%

    def __init__(self, asset=10000):
        self.asset = asset

    def __show_asset(self) : 
        print('total asset', self.asset)

    def deposit(self, amount):
        self.asset += amount
    
    def withdraw(self, amount):
        if self.asset >= amount:
            self.asset -= amount
        else:
            __show_asset(self)

    def add_interest(self):
        self.asset = int(self.asset * self.interest)
        __show_asset(self)


    # 인스턴스 메서드
    def change_interest(self, interest):
        if interest < 1.10:
            self.interest = interest
        else:
            print('이자율을 10% 미만으로 설정해주세요.')

    # 클래스 메서드
    @classmethod
    def cls_change_interest(cls, interest):
        if interest < 1.10:
            cls.interest = interest
        else:
            print('이자율을 10% 미만으로 설정해주세요.')

    # 스태틱 메서드
    @staticmethod
    def interest_grade(interest):
        if interest > 1.05:
            print('high interest')
        elif interest > 1.02:
            print('middle interest')
        else:
            print('low interest')
account1 = Account(10000)
account2 = Account(20000)
account3 = Account(30000)


# 인스턴스 메서드 사용
account1.change_interest(1.09)      # account1 객체를 쓴다.
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
# 출력 :(10000, 20000, 30000, 1.09, 1.01, 1.01)
# \를 쓰면 둘 줄의 코드를 한 줄로 출력 가능
# \ 이렇게 뒤에 공백을 두면 오류 나니 주의!

# 클래스 메서드 사용
# 해당 클래스로부터 만들어진 객체의 변수를 한번에 변경할 때 사용
Account.cls_change_interest(1.04)    #Account 클래스를 쓴다.
account1.asset, account2.asset, account3.asset,\
account1.interest, account2.interest, account3.interest
# 출력 :(10000, 20000, 30000, 1.09, 1.04, 1.04)

# 스태틱 메서드 사용
# 클래스 메서드와 스태틱 메서드 차이 : 클래스 메서드는 클래스이 변수에 접근이 가능
Account.interest_grade(account1.interest) # 출력 : high interest
Account.interest_grade(account2.interest) # 출력 : middle interest

* dir(account1)[:5] : dir을 이용하면 메소드 안의 변수들을 다 볼 수 있다.

 

 

6) 클래스 설계

- is a, has a 개념

- is a : A is a B : 상속을 이용해서 클래스 설계

- has a : A has a B : 객체를 객체에 넣어서 클래스 설계

- 두가지 방법을 혼용해서 클래스 설계

# is a
class Info:
    def __init__(self, name, email):
        self.name = name
        self.email = email


class Person(Info):
    def show(self):
        print(self.name, self.email)

person = Person('peter', 'peter@gmail.com')
person.name, person.email # 출력 : ('peter', 'peter@gmail.com')
# has a
class Name:
    def __init__(self, name):
        self.name_str = name

class Email:
    def __init__(self, email):
        self.email_str = email

class Person:
    def __init__(self, name_obj, email_obj):
        self.name = name_obj
        self.email = email_obj
    def show(self):
        print(self.name.name_str, self.email.email_str)

name_obj = Name('peter')
email_obj = Email('peter@gmail.com')

person = Person(name_obj, email_obj)
person.show() # 출력 : peter peter@gmail.com

 

8. 입출력

- RAM > SSD(HDD), RAM < SSD(HDD)

- RAM > 직렬화(byte()) > SSD(HDD)

- pickle : 직렬화, 입출력 속도 빠름

 

- 상관계수 과제 풀이 및 모델링 예제

# 상관계수 과제 풀이
with open('sales.pkl', 'rb') as file:
    data = pickle.load(file)
# 상관계수 구하기
import numpy as np
np.corrcoef(data['meeting_count'], data['sales'])[0, 1],\
np.corrcoef(data['meeting_time'], data['sales'])[0, 1]
# 모델링 : 미팅 횟수, 미팅 시간으로 매출을 예측 모델
import pandas as pd
features = pd.DataFrame({
    'meeting_count': data['meeting_count'],
    'meeting_time': data['meeting_time'],
})
target = data['sales']
features[:2]


from sklearn.linear_model import LinearRegression
model = LinearRegression().fit(features, target)


model.predict([[200, 20]])
# RAM > SSD
with open('model.pkl', 'wb') as file:
    pickle.dump(model, file)

# SSD > RAM
with open('model.pkl', 'rb') as file:
    load_model = pickle.load(file)

# warnings 메세지 안 보는 설정
import warnings
warnings.filterwarnings('ignore')

load_model.predict([[100, 10]]) # 출력 :array([10.9072636])

 

9. 모듈. 패키지

1) 모듈 : 변수, 함수, 클래스를 하나의 파일(.py)로 모아서 코드 작성

# 모듈 만들기

%%writefile ai_school.py

data = 'python'

def echo(msg):
    print('ai school : ', msg)

# 여기서 쉘을 나눠서 사용해야한다. 아니면 모듈 앞에 들어가는 구조가 된다.

# 모듈 사용
# import, from, as 

import ai_school

%cat ai_school.py

ai_school.data # 출력 : python
ai_school.echo('fighting!') # 출력 : ai school : fighting!
from ai_school import data, echo # data,echo를 앞에 모듈을 쓰지 않고 쓸 수 있다.
from ai_school import * # *을 쓰면 모든 함수에 적용한다.​

 2) 패키지 : 여러개의 모듈 파일을 디렉토리로 구분하여 코드를 작성하는 방법 : 버전정보

- tree :  디렉토리의 구조를 출력하는 우분투(os) 패키지

- 패키지 구조 만들기

  1) mkdir : 디렉토리 만들기

  2) -p : 상위 디렉토리를 만들면서 디렉토리를 만들기

  3) touch : 빈 파일 생성

!apt-get install tree -y # tree 패키지를 설치

!rm - rf stock # stock이라는 디렉토리를 모두 삭제한다.
!mkdir -p stock/kor
!mkdir -p stock/usa
!touch stock/__init__.py
!touch stock/kor/__init__.py
!touch stock/usa/__init__.py

!tree stock

stock : 패키지, kor과 usa : 디렉토리, 그 하위는 파일

 

# 모듈파일 추가
%%writefile stock/kor/kospi.py
def crawl_kospi():
    print('crawl_kospi')
%%writefile stock/usa/snp500.py
def crawl_snp500():
    print('crawl_snp500')
%%writefile stock/usa/nasdaq.py
def crawl_nasdaq():
    print('crawl_nasdaq')

* 디렉토리는 마지막에 오면 안된다. 모듈, 함수, 변수가 마지막에 와야한다.

# import 패키지
import stock.kor.kospi as skk

skk.crawl_kospi()  # 출력 : crawl_kospi

# 아래 코드는 다른 표현법
# from stock.kor import kospi

# kospi.crawl_kospi()

 

* __init__.py

- 패키지에 있는 디렉토리의 모듈을 설정하는 파일

- __init__.py python 3.x 버전부터는 쓰지 않아도 문제 x

- 하위버전 호환성을 이유로 __init__.py를 써주는 것이 좋다.

 

* 모듈이나 패키지 코드를 수정하면 런타임 다시시작을 해야 적용된다.

 

 

* 디렉토리 이동

- ./ : 현재 디렉토리 (생략가능)

- ../ : 상위 디렉토리

- ~/ : 현재 로그인 되어있는 계정의 최상위 디렉토리

 

# 만든 패키지 설치
!pip install -e stock   # stock이라는 패키지를 설치

!pip list | grep stock  #stock        0.0.1       /content/stock

 

10. 예외처리

- 코드의 에러를 처리하는 방법, 문법

- try, except, finally, raise

try:
    print('connet database') # 리소스 사용
    print(1/0)
except Exception as e:
    print(e)
finally: # try 구문에 에러가 있던 없던 항상 코드 실행하는 구문
    print('disconnect') # 리소스 반납
print('python')

# # 출력 : 
# connet database
# division by zero
# disconnect
# python
#raise : 강제로 에러를 발생
#에러만들기
class LowNumber(Exception) :
    def __str__(self):
        return 'insert number grater then 10!'

# 함수의 파라미터에 10이하의 데이터가 넘어오면 에러(LowNumber)발생
def input_number(number):
    if number <= 10:
        raise LowNumber()
    print(number)

input_number(5) # 에러 발생

 

'멋쟁이사자처럼 > Python' 카테고리의 다른 글

멋사 AI스쿨 WIL - (9)  (0) 2023.01.19
멋사 AI스쿨 WIL - (8)  (0) 2023.01.12
멋사 AI스쿨 TIL - (6)  (2) 2023.01.05
멋사 AI스쿨 TIL - (5)  (0) 2023.01.04
멋사 AI스쿨 TIL - (4)  (1) 2023.01.03
Comments