1. 파이썬 홈페이지 이미지 추출

 

 

 

 

📌  이미지 위에 우클릭 ▶️ 이미지 주소 복사 버튼 클릭하면 url을 가져올 수 있다

 

 

 

 

 


 

🥑 os.path : 경로명과 파일명에 대한 유용한 함수를 제공하는 모듈

import requests
import os.path

# 1. 파이썬 공식 홈페이지에서 이미지 링크 가져옴
url = 'https://www.python.org/static/img/python-logo@2x.png'

resp = requests.get(url)

 

🥑  os.path.basename() : 입력받은 경로의 파일명을 반환

# 2. 파일 이름 가지고 오기
image_file_name = os.path.basename(url)  # 파일 이름 가져오기
print(image_file_name)  # python-logo@2x.png

 

# 3. 파일 저장.
with open(f'./output_image/{image_file_name}', 'wb') as image_file:
    image_file.write(resp.content)
    print("이미지 파일로 저장하였습니다.")

 

2. 야후 이미지 검색 페이지 추출

🥑 https://www.yahoo.com/ 에서 이미지 검색을 한 후 url을 들고 올 것

import requests
from bs4 import BeautifulSoup as bs
import pprint

# 1. 이미지 태그 가져오기
url = 'https://images.search.yahoo.com/search/images;_ylt=Awrg1fJPpOplRwQAMU5XNyoA;_ylu=Y29sbwNncTEEcG9zAzEEdnRpZAMEc2VjA3BpdnM-?p=bts&fr2=piv-web&fr=yfp-t'
resp = requests.get(url)
soup = bs(resp.text, 'html.parser')

tag_images = soup.select('li.ld a > img')
pprint.pprint(tag_images)

실행 결과


 

# 2. 이미지 저장
dir_save = './output_image/yahoo/'  # 저장 경로

for idx, tag in enumerate(tag_images):
    #print(tag.get('data-src'))
    resp = requests.get(tag.get('data-src'))
    with open(f'{dir_save}{idx + 1}.png', 'wb') as image_file:
        image_file.write(resp.content)
        #print(f'{idx+1} / {len(tag_images)}')  # 진행 상황 확인

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  select_one() 

🥑  find가 원하는 태그를 찾는게 목적이라면 select는 CSS selector로 tag 객체를 찾아 반환
🥑  select_one()은 원하는 태그 하나만 가져오고, 태그가 많은 경우에는 맨 앞의 것만 가져옴

 

    🐰 select 계열의 메소드는 css selector 이용 가능
    🐰  '.' -> class 속성 /  '#' -> id 속성
    🐰 class : 하나의 html 에서 여러 태그에 중복 사용 가능
    🐰 id : 하나의 html에서 한번만 사용. 권장사항

# 요소 내 text 가져오기
title = soup.select_one('title')

print(title.string)  # 선택된 요소 text만
print(title.text)
print(title.get_text())
# text, get_text는 하위 text 까지 같이

 

 

1)  select_one('태그명') 사용 예제

# 다음 > 뉴스 > IT > 오늘의 연재의 첫번째 글 제목과 신문사 들고오기
url = 'https://news.daum.net/digital#1'
resp = requests.get(url)
soup = bs(resp.text, 'html.parser')

html 소스

 

tag_series = soup.select_one(('.list_todayseries li'))
pprint.pprint(tag_series)

tag_series_title = tag_series.select_one('.link_txt').text
print(f'제목: {tag_series_title}')
# 제목: 전자사전으로 인기 끌던 '샤프'...최근엔 AI 아바타와 함께

tag_series_press = tag_series.select_one('.txt_info').text
print(f'신문사: {tag_series_press}')
# 신문사: 전자신문

tag_series 실행결과

 


 

2)  select_one('CSS선택자') 예제

 

import requests
from bs4 import BeautifulSoup as bs
import pprint

# 할리스 커피 : 매장 검색
url = 'https://www.hollys.co.kr/store/korea/korStore2.do'
resp = requests.get(url)
soup = bs(resp.text, 'html.parser')

매장 테이블의 html 소스

 

# 매장 테이블 가져오기
stores = soup.select_one('#contents > div.content > fieldset > fieldset > div.tableType01 > table')
pprint.pprint(stores)

  

 

 

 

 

📌  왼쪽은 css selector로 가져온 결과이다

      ➡️ selector 소스를 가져오는 방법은 html 소스코드 중 해당 태그 위에 커서를 가져다 놓고 우클릭 ▶️ 복사 ▶️ selector 복사 버튼을 클릭하면 된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

# 첫 번째 가게 관련
first_store = stores.select_one('#contents > div.content > fieldset > fieldset > div.tableType01 > table > tbody > tr:nth-child(1)')
pprint.pprint(first_store)

 

first_store 결과

 

# td:nth-child(1) -> td 태그중 첫번째
second_store_name = first_store.select_one('td:nth-child(2)')
print(second_store_name.text)
# 부산사상광장점

# td:nth-child(1) -> td 태그중 4번째
second_store_addr = first_store.select_one('td:nth-child(4)')
print(second_store_addr.text)
# 부산광역시 사상구 광장로 22 (괘법동) 2층 사상구 괘법동 565-2

 


 

2. select()

🥑  CSS selector로 지정한 태그들을 모두 가져오는 메소드로 가져온 태그들은 모두 리스트에 보관

# 네이버 환율 크롤링
# 네이버에서 '환율' 검색 후 '환율 더보기'

url = 'https://finance.naver.com/marketindex'
resp = requests.get(url)
soup = bs(resp.text, 'html.parser')
pprint.pprint(soup)

실행결과

 

# 환전고시 국가 가져오기
nations = soup.select('#exchangeList > li > a.head > h3 > span')
print(nations)  # 리스트로 반환

실행결과

 

# 나라별 환율 가져오기
exchange_rates = soup.select('#exchangeList > li > a.head > div > span.value')
print(exchange_rates)

 

# 나라별 화폐 단위와 환율 같이 출력하기
for idx, item in enumerate(nations):
    print(f'{item.text} : {exchange_rates[idx].text}')
  
'''
실행결과)
미국 USD : 1,317.50
일본 JPY(100엔) : 895.98
유럽연합 EUR : 1,440.55
중국 CNY : 182.99
'''

 


 

3. CSS selector 

 

1) 태그명 선택    ex. li, a

test = soup.select('a')

 

 

2) 하위 태그 선택   ex. ul a / ul > a

# 상위 태그 > 하위 태그
test = soup.select('li a')
test = soup.select('li > a')

 

3) 클래스 이름으로 선택   ex. li.course / .course / li.course.paid

# 태그.클래스명
test = soup.select('li.value')
# .클래스명
test = soup.select('.value')
# 태그.클래스명.클래스명 (여러 클래스가 있는 경우)
test = soup.select('li.value.fieldset')

 

 

4) id 이름으로 선택   ex. #start

# '#id이름'
test = soup.select('#list50')
# '태그명#id이름'
test = soup.select('tr#list50')

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  BeautifulSoup

🍯  구문을 분석해서 필요한 내용만 추출 할 수 있는 기능을 가지고 있는 패키지

        ➡️  xml or html을 수프객체로 만들어서 추출하기 쉽게 만들어 준다.

from bs4 import BeautifulSoup as bs  # bs4 라이브러리에서 Beautiful Soup를 import
import requests
import pprint

# html 파일 가져오기
with open('./sample.html', 'r', encoding='utf-8') as file:
    html = file.read()

# html.parser : html 코드를 사용하기 쉽게 BeautifulSoup의 객체로 분석
soup = bs(html, 'html.parser')  
# 첫번째 인자: 분석할 내용 전달
# 두번째 인자: "html"로 분석한다는 것을 명시

print(type(soup))  # <class 'bs4.BeautifulSoup'>
print(soup)  # (html 출력)

print(soup.find('title').text)  # This is title
print(soup.find('div').text)  # Division의 약자로, 레이아웃을 나누는데 사용.
print(soup.find('h1').text.strip())  # This is heading1 text.

 


 

1) find ()

🥑  지정된 태그들 중에서 가장 첫 번째 태그만 가져오는 메소드(하나의 값만 반환)로 문자열 형태로 반환
       ➡️  일반적으로 하나의 태그만 존재하는 경우에 사용  만약 여러 태그가 있으면 첫 번째 태그만 가져옴

 

# 속성값 가져오는 경우 형식 (find, find_all 동일)
find(태그명['속성명'])
find(태그명.attrs['속성명'])
find(태그명).get(속성명)
find_all('태그명', attrs={'속성명':'값'})
# 위키피디아 '대구광역시' 페이지
url = 'https://ko.wikipedia.org/wiki/%EB%8C%80%EA%B5%AC%EA%B4%91%EC%97%AD%EC%8B%9C'
resp = requests.get(url)
soup = bs(resp.text, 'html.parser')

first_img = soup.find(name='img')  # img 태그 중에 제일 먼저 나오는 것
print(type(first_img))  # <class 'bs4.element.Tag'>
print(first_img)  
# <img alt="" aria-hidden="true" class="mw-logo-icon" height="50" 
# src="/static/images/icons/wikipedia.png" width="50"/>

target_img = soup.find(name='img', attrs={'alt': 'Daedongyeojido (Gyujanggak) 17-02.jpg'})
print(target_img)
# <img alt="Daedongyeojido (Gyujanggak) 17-02.jpg" class="mw-file-element" 
# data-file-height="3005" data-file-width="4000" decoding="async" height="376" 
# src="//upload.wikimedia.org/wikipedia/commons/thumb/c/c5/
# Daedongyeojido_%28Gyujanggak%29_17-02.jpg/500px-Daedongyeojido_%28Gyujanggak%29_17-02.
# jpg" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Daedongyeojido_
# %28Gyujanggak%29_17-02.jpg/750px-Daedongyeojido_%28Gyujanggak%29_17-02.jpg 1.5x, 
# //upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Daedongyeojido_%28Gyujanggak%
# 29_17-02.jpg/1000px-Daedongyeojido_%28Gyujanggak%29_17-02.jpg 2x" width="500"/>


 

2)  find_all() 

🥑  지정한 태그들을 모두 가져오는 메소드로 가져온 태그들은 모두 리스트에 보관

# 네이버 스포츠 페이지에서 박스 뉴스 제목 들고 옴
url = 'https://sports.news.naver.com/index.nhn'
response = requests.get(url)
soup = bs(response.text, 'html.parser')

today_list = soup.find('ul', {'class': 'today_list'})
print(today_list)

today_list_title = today_list.find_all('strong', {'class', 'title'})
pprint.pprint(today_list_title)  # 리스트로 반환

for title in today_list_title:
    print(title.text.strip())

1. today_list 결과
2. today_list_title 결과
3. 반복문 실행결과

 


 

3) find_all 사용 예제

a. 다음 뉴스 사이트 html 분석

url = 'https://news.daum.net/'
response = requests.get(url)
soup = bs(response.text, 'html.parser')


 

b. a 태그의 갯수 출력

 

   👾  html의 'a' 태그 : 다른 콘텐츠와 연결되는 하이퍼링크(hyperlink)를 정의

print('1. a 태그의 갯수')
print(len(soup.find_all('a')))  # 124

 

c. a 태그 20개만 출력

print('2. a 태그 20개만 출력')
for news in soup.find_all('a')[:20]:
    print(news.text.strip())

실행결과


 

d.  a 태그 링크 5개 출력

print('3. a 태그 링크 5개 출력')
for i in soup.find_all('a')[:5]:
    print(i.attrs['href'])
    print(i.get('href'))
    # -> 둘 중 하나만 쓰면 된다.
print("=" * 20)

 

실행결과


 

e.  특정 클래스 속성을 출력하기

print('4. 특정 클래스 속성을 출력')
print(soup.find_all('div', {'class': 'item_issue'}))
print("=" * 20)

실행결과


f.  링크를 텍스트 파일로 저장

print('5. 링크를 텍스트 파일로 저장')
file = open('../output_02/links.txt', 'w')  # 쓰기 전용 파일 생성

for i in soup.find_all('div', {'class': 'item_issue'}):
    file.write(i.find('a').get('href') + '\n')
file.close()

실행결과

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  url을 이용해서 HTML를 가져오는 방법

 

🚀  크롤링할 때 url을 이용해서 HTML를 가져오는 방법은 크게 2가지
      a. 내장 모듈인 urllib를 사용 
      b. 외장 모듈인 requests를 사용

 

1) urllib를 사용한 경우

# 정상 접속
url = "https://www.python.org/"
code = request.urlopen(url)
print(code)  # <http.client.HTTPResponse object at 0x103f16b30>

# 비정상 접속. 비정상일 경우 에러 발생.
url = "https://www.python.org/1"
code = request.urlopen(url)
print(code)

비정상 접속인 경우 실행 결과

 


 

2) requests를 사용한 경우

# 정상 접속인 경우
url = "https://www.python.org/"
response = requests.get(url)
print(response)  # <Response [200]>. 정상적인 통신이 이루어짐.

# 페이지가 없는 경우에도 에러가 발생하지 않고, Response [404]를 리턴.
url = "https://www.python.org/1"
response = requests.get(url)
print(response)  # <Response [404]>. 해당 페이지를 찾을 수 없음

 

  👾  requests 를 사용하면 urllib 를 사용한 경우와 달리 비정상 접속인 경우 에러가 발생하지 않고 응답코드를 준다

 

    📌  응답코드 : 서버에서 클라이언트로 보내는 코드
          a. 1XX : 요청을 받았고, 작업 진행 중
          b. 2XX : 사용자의 요청이 성공적으로 수행 됨
          c. 3XX : 요청은 완료 되었으나, 리다이렉션이 필요
          d. 4XX : 사용자의 요청이 잘못됨
          e. 5XX : 서버에 오류가 발생함

 


 

2. requests 사용법

 

🚀  서버로 요청을 할 때 브라우저의 정보(User-Agent)가 같이 전달됨
        ➡️ 요청 받은 서버에서는 브라우저의 정보를 가지고 접속자가 bot인지 일반 사용자임을 구분
        ➡️ 특정 사이트의 경우 요청하는 브라우저의 정보가 일반 사용자가 아니면 접속을 막는 경우가 있음
        ➡️ requests의 경우 브라우저의 헤더 정보를 수정해서 일반 브라우저 처럼 접속할 수 있게 함

 

# requests 사용법

url = 'https://www.naver.com/'
response = requests.get(url)  # get() 또는 post() 메서드를 이용해서 html 정보를 받아옴

html = response.text  # response 객체의 text 속성을 지정하면 html 정보 반환.
print(html)  # html 소스가 출력

headers = response.headers  
print(headers)  # response 객체의 headers 속성 지정하면 헤더 정보 반환.

 

 

1) 헤더 정보 확인하기

 

  👾  requests를 이용해서 url 접속을 하면 브라우저의 정보(User-Agent)가 requests의 모듈 정보로 나옴
          ➡️ 서버에서 해당 정보를 보고 크롤링을 판단할 수 있음

from bs4 import BeautifulSoup as bs
import requests

url = 'https://planet-trade.kr/header_info.php'

response = requests.get(url)  # 브라우저 접속 역할을 파이썬 requests가 해줌
soup = bs(response.text, 'html.parser')
print(soup)
# 접속 IP : 58.149.46.252
# 접속 정보 : python-requests/2.31.0

url 주소로 접속했을 때 브라우저의 정보

 


 

2) requests에서 헤더 정보를 변경

request_headers = {
    'User-Agent': ('(url 주소로 들어갔을 때 나오는 브라우저 접속 정보)'),
    'Referer': '',
}

resp = requests.get(url, headers=request_headers) # 변경된 헤더로 접속, 정보 가져옴
soup = bs(resp.text, 'html.parser')
print(soup)

# 접속 IP : 58.149.46.252
# 접속 정보 : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
# (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36

 


 

2. 크롤링 할 때 운영자 의사 확인

 

🚀  모든 크롤링이 불법은 아니지만 하지만 운영자의 의사에 상관없이 무단으로 크롤링하는 것은 불법
🚀  운영자의 크롤링 허용 여부를 알 수 있는 방법은 'robot.txt' 로 확인
        ➡️ allow는 허용, disallow는 검색 불가

 

    💡  robots.txt 설정 정보 안내 사이트

           https://searchadvisor.naver.com/guide/seo-basic-robots
           https://developers.google.com/search/docs/advanced/robots/intro?hl=ko

 

robots.txt 설정하기

robots.txt는 검색로봇에게 사이트 및 웹페이지를 수집할 수 있도록 허용하거나 제한하는 국제 권고안입니다. IETF에서 2022년 9월에 이에 대한 표준화 문서를 발행하였습니다. robots.txt 파일은 항상

searchadvisor.naver.com

 

robots.txt 소개 및 가이드 | Google 검색 센터  |  문서  |  Google for Developers

robots.txt는 크롤러 트래픽을 관리하는 데 사용됩니다. robots.txt 소개 가이드에서 robots.txt 파일의 정의와 사용 방법을 알아보세요.

developers.google.com

 

urls = ['https://www.naver.com/', 'https://ko.wikipedia.org/']
filename = 'robots.txt'

for url in urls:
    file_path = url + filename
    print(file_path)
    resp = requests.get(file_path)
    print(resp.text)
    print("\n")

실행 결과

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

 


 [ 측정소 정보 추출하기 ]

   📌  대구에 있는 측정소의 측정소 명, 측정소 주소, 위도, 경도, 설치년도를 csv 파일로 저장

 

import requests
import json

# 1. 초기값 설정
# 1) 서비스 키: requests 사용시 자동으로 인코딩되어 decoding된 키를 사용
service_key:str = 'uAhO32pV0qa7BDOmkJLhw2ZyOB9i5bGj7cMN8cuuHmKIwyyf29lHLjym8hBXdIaXyvAI1IyLvQZopk5HW233qQ=='

# 2) url 설정
url = 'http://apis.data.go.kr/B552584/MsrstnInfoInqireSvc/getMsrstnList'
parameter = f'?serviceKey={service_key}&returnType=json&numOfRows=100&pageNo=1&addr=대구'
print(url+parameter)

일반 인증키를 서비스 키로 가져온다

 

사이트에 올라와 있는 zip 파일에 서버에 소스 요청할 때 요구하는 메세지 형식이 나와있다.

 

 

# 2. 서버에서 요청값을 받은 후 파싱(parsing)(= 구문 분석)
# 딕셔너리 데이터를 분석해서 원하는 값을 추출
response = requests.get(url + parameter)
# requests.get() 메서드를 사용하여 url 주소로 GET 요청을 보내고, 응답을 response 변수에 저장
json_data = response.text
# head 값 외 text 값만 들고오기 위함
dict_data = json.loads(json_data)
# JSON 형식의 데이터를 파이썬 객체로 변환하여 data 변수에 저장

print(dict_data)
'''
실행결과)
{'response': {'body': {'totalCount': 28, 'items': 
[{'dmX': '35.859', 'item': 'SO2, CO, O3, NO2, PM10, PM2.5', 'mangName': '도시대기', 
'year': '2020', 'addr': '대구광역시 서구 서대구로3길 46 내당4동 행정복지센터 3층 옥상 (
... 생략...

'''

# 3. 필요 정보 추출

count_datas = dict_data['response']['body']['items']
#print(count_datas)

for k in range(len(count_datas)):
    count_data = count_datas[k]
    if count_data['addr'][0:2] == "대구":
        print(f'측정소 명 : {count_data["stationName"]}')
        print(f'측정소 주소 : {count_data["addr"]}')
        print(f'위도 : {count_data["dmX"]}')
        print(f'경도 : {count_data["dmY"]}')
        print(f'설치년도 : {count_data["year"]}')
        print('=' * 20)
'''
실행결과)
측정소 명 : 내당동
측정소 주소 : 대구광역시 서구 서대구로3길 46 내당4동 행정복지센터 3층 옥상 (내당동)
위도 : 35.859
경도 : 128.55183
설치년도 : 2020
====================
측정소 명 : 침산동
측정소 주소 : 대구광역시 북구 옥산로17길 21 대구일중학교 (침산동)
위도 : 35.88761
경도 : 128.58434
설치년도 : 2020

... 생략...

'''

 


# 4. csv 파일 저장
import csv

data_list: list[str] = ['측정소 명', '측정소 주소', '위도', '경도', '설치년도']
daegu_list:list[dict] = list()

for k in range(len(count_datas)):
    count_data = count_datas[k]
    if count_data['addr'][0:2] == "대구":
        new_data: dict = dict()
        new_data[data_list[0]] = count_data["stationName"]
        new_data[data_list[1]] = count_data["addr"]
        new_data[data_list[2]] = count_data["dmX"]
        new_data[data_list[3]] = count_data["dmY"]
        new_data[data_list[4]] = count_data["year"]

        daegu_list.append(new_data)

with open('../output_02/daegu_air_list.csv', 'w', newline='', encoding='UTF-8') as csvfile:
    csv_writer = csv.DictWriter(csvfile, data_list)
    csv_writer.writeheader()
    for data in daegu_list:
        data:dict
        csv_writer.writerow(data)

print(f'파일이 생성되었습니다.')

 

파일 생성 완료

 

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1. 클래스 변수

🚀  클래스를 구현할 때 인스턴스마다 서로 다른 값을 가지는 경우에는 인스턴스 변수를 사용
🚀  모든 인스턴스 변수들은 self 키워드를 붙여서 사용
🚀  모든 인스턴스가 동일한 값을 사용할 때는 클래스 변수로 처리해서 모든 인스턴스들이 공유하도록 처리하는 것이 좋음
        ➡️  하나의 값을 모든 인스턴스가 공유하기 때문에 메모리 공간의 낭비를 막을 수 있음

     ⚡️  self
         - 관례적으로 모든 메서드의 첫 번째 매개변수 이름을 self로 지정.
         - self라는 명칭은 관례적으로 사용하는 단어.

# 클래스 변수 만들기
class 클래스 이름:
    클래스 변수 = 값
# 클래스 변수 접근
클래스 이름.변수 이름
class Korean:
    country = '한국'  # 클래스 변수 country

    def __init__(self, name, age, address):
        self.name = name  # 인스턴스 변수
        self.age = age
        self.address = address

print(Korean.country)  # 객체 생성전에도 사용 가능.

man = Korean('홍길동', 35, '서울')
print(man.name)
# print(Korean.name)  # AttributeError: type object 'Korean' has no attribute 'name'

print(man.country)  # 인스턴스 man을 통한 클래스 변수 접근
print(Korean.country)  # 클래스 Korean을 통한 클래스 변수 접근

print('객체 property 생성과 동일한 이름의 클래스 변수')
man.country = '중국'  # 객체의 인스턴스 변수 생성
print(man.country)  # 중국. 
# 클래스 변수가 아니라 인스턴스 변수를 불러옴. 
# man 객체의 country 라는 인스턴스 변수와 country 클래스 변수
print(man.__class__.country)  # 한국. 객체를 사용해서 클래스 변수 불러오기.
print(Korean.country)  # 한국.

print('객체를 이용해서 클래스 변수 값 변경')
man.__class__.country = '영국'
print(Korean.country)  # 영국

print('클래스를 이용해서 클래스 변수 값 변경')
Korean.country = '미국'  # 클래스 변수를 변경
print(Korean.country)  # 미국

man2 = Korean('홍길동2', 35, '서울')
print(man2.country)  # 미국
print(Korean.country)  # 미국

# 클래스 변수는 클래스를 통해서 접근하는 것이 권장사항

 


 

2. 클래스 메소드

🚀  클래스 변수를 사용하는 메소드를 의미
 

   ⚡️ 주요 특징
         a. 인스턴스 혹은 클래스로 호출
         b. 생성된 인스턴스가 없어도 호출할 수 있음
         c. @classmethod 데코레이터 decorator를 표시하고 작성
         d. 매개변수 self를 사용하지 않고 cls를 사용
         e. 클래스 메소드는 self를 사용하지 않기 때문에 인스턴스 변수에 접근할 수 없지만 cls를 통해서 클래스 변수에 접근할 수 있음

class Korean:
    country = '한국'  # 클래스 변수 country

    @classmethod
    def trip(cls, country):
        if cls.country == country:
            print('국내여행입니다.')
        else:
            print('해외여행입니다.')

Korean.trip('한국')  # 국내여행입니다.
Korean.trip('미국')  # 해외여행입니다.

 


 

3. 정적 메소드

🚀  인스턴스 또는 클래스로 호출
🚀  생성된 인스턴스가 없어도 호출 가능
🚀  @staticmethod 데코레이터 decorator를 표시하고 작성
🚀  반드시 작성해야 할 매개변수가  없음

 

    ⚡️  self와 cls를 모두 사용하지 않기 때문에 인스턴스 변수와 클래스 변수를 모두 사용하지 않는 메소드를 정의하는 경우에 적절
    ⚡️  정적 메소드는 클래스에 소속이 되어 있지만, 인스턴스에는 영향을 주지 않고 또 인스턴스로부터 영향을 받지도 않음

class Korean:
    country = '한국'  # 클래스 변수 country

    @staticmethod
    def slogan():
        print('Imagine your Korea')

Korean.slogan()  # Imagine your Korea

 


 

4. 상속  inheritance

 

1) 상속이란?

👾  어떤 클래스가 가지고 있는 기능을 그대로 물려받아서 사용할 수 있는 클래스를 만들 수 있다.
👾  다른 클래스의 기능을 물려받을 때 상속받는다는 표현을 사용
👾  상속 관계에 있는 클래스를 표현할 때 '부모 클래스와 자식 클래스'라는 말을 사용

    ⚡️ 부모 클래스 : 상속해 주는 클래스 / 슈퍼 클래스 super class , 기반 클래스 base class
    ⚡️ 자식 클래스 : 상속 받는 클래스 / 서브 클래스 sub class, 파생 클래스 derived class


2) 상속 관계 구현

👾  기본적으로 두 클래스가 상속 관계에 놓이려면 IS-A 관계가 성립해야 한다
👾  IS-A 관계란 '~은 ~ 이다'로 해설할 수 있는 관계를 의미
        ex. '학생은 사람이다 Student is a Person'처럼 해석되는 것이 IS-A 관계
                이때 Student 는 서브 클래스가 되고, Person은 슈퍼 클래스가 됨

👾  has-a 관계는  '그릇이 스쿱을 갖는다 Bowl has-a Scoop'
👾  has-a 관계는 상속이 아니라 구성 Composition으로 구현함

# 상속의 기본적인 형식
class 슈퍼 클래스:
    본문

class 서브 클래스(슈퍼 클래스):
    본문


  ⚡️  서브 클래스를 구현할 때는 괄호 안에 어떤 슈퍼 클래스를 상속 받는지 명시
  ⚡️  상속 관계에 놓인 서브 클래스는 마치 자신의 것처럼 슈퍼 클래스의 기능을 사용할 수 있음

 

class Person:  # 슈퍼 클래스
    def __init__(self, name):
        self.name = name

    def eat(self, food: str) -> None:
        print(f'{self.name}가 {food}를 먹습니다.')

class Student(Person):  # 서브 클래스
    def __init__(self, name: str, school: str) -> None:
        super().__init__(name)  # 슈퍼 클래스의 생성자 실행
        self.school = school

    def study(self) -> None:
        print(f'{self.name}는 {self.school}에서 공부를 합니다.')

potter = Student('해리포터', '호그와트')
potter.eat('감자')  # 해리포터가 감자를 먹습니다.
potter.study()  # 해리포터는 호그와트에서 공부를 합니다.

 

3) 서브 클래스의  __init__()

👾  서브 클래스의 생성자를 구현할 때는 반드시 슈퍼 클래스의 생성자를 먼저 호출하는 코드를 작성해야 함
👾  super라는 키워드는 슈퍼 클래스를 의미

class Computer:  # 슈퍼 클래스
    def __init__(self):
        print('슈퍼 클래스의 생성자가 실행되었습니다.')

class NoteBook(Computer):  # 서브 클래스
    def __init__(self):
        super().__init__()
        print('서브 클래스의 생성자가 실행되었습니다.')

 


 

4) 서브 클래스의 인스턴스 자료형

👾  슈퍼 클래스 객체는 슈퍼 클래스의 인스턴스
👾  그에 비해 서브 클래스 객체는 서브 클래스의 인스턴스이면서 동시에 수퍼 클래스의 인스턴스

 

    ⚡️ 서브 클래스 Student의 객체는 서브 클래스 Student의 인스턴스 이면서 동시에 슈퍼 클래스 Person의 인스턴스

👾  어떤 객체가 어떤 클래스의 인스턴스인지 확인하기 위해서 isinstance() 함수를 사용
        ➡️  객체가 인스턴스일 경우에는 True 아니면 False 반환

# isinstance(객체, 클래스)
print(isinstance(potter, Student))  # True
print(isinstance(potter, Person))  # True

 

 

 

 

[ 내용 참고 : IT 학원 강의 ]

+ Recent posts