[파이썬 정리]

Yunny.Log ·2021년 1월 4일
0

Python

목록 보기
5/7
post-thumbnail

링크텍스트 => [나도코딩]님의 파이썬 문법 정리 유튜브영상을 통해 파이썬을 공부한 것을 다시 한번 복습하고 암기하기 위해 정리글을 써보기로 했다 :)

숫자처리 함수

  • pow(3,2) = 3^2
    #지수

  • round (2.1)= 2
    #반올림

  • round(1.2345,2) = 1.23
    #반올림할 범위를 지정

  • from math import*

    print(floor(2.2)) =2
    #내림

    print(ceil(2.2)) =3
    #올림

    print((squrt(4))=2
    #제곱근

  • 랜덤함수 :
    from random import *

    print(random())
    #0.0이상 1.0미만의 임의의 값

    print(int(random())
    #정수로 출력된다

    print(randrange(1,10))
    #1부터 10 미만의 임의의 값
    =>so 1부터 10까지 원하면 randrange(1,11)이렇게 해주면 됨

    print(randint(1,10))
    #1부터 10이하의 임의의 값

  • 숫자를 문자열로 나오게 하려면 앞에다가 str 붙여줘야 함

문장 출력시 줄바꿈

a='''
빵을 좋아해 나는
'''

print (a)=


빵을 좋아해 나는


이렇게 줄을 바꿔서 출력을 할 수 있음

슬라이싱

  • b=1234567
    -인덱스는 0부터 시작한다 , b는 인덱스가 0부터 7까지 있음
    -뒤에서부터 세면 -1(7),-2(6) 이렇게 -1부터 센다

    -print('빵종류 :' + b[1])
    =빵종류 : 2

    -print('빵수량 :' + b[2:5])
    =빵수량 : 345
    #[2:5] 는 인덱스 2이상 5미만을 가리킴 => 즉 인덱스 2부터 4까지

    -print('빵번호:'+b[:6])
    =빵번호 : 123456
    #[:6] 는 인덱스 0부터 6미만을 가리킴 => 즉 인덱스 0부터 5까지

    -print('빵지역:'+b[0:])
    =빵지역 : 1234567
    #[0:] 는 인덱스0부터 끝까지 =>즉 인덱스0부터 6까지,
    이것은 print(b[-7:]) 과 동일

    문자열 처리 함수

  • a=abca
    -print(a.upper()) =ABCA
    #대문자로

    -print(a.lower()) =abca
    #소문자로

    -print(a[1].isupper()) = Abca
    #인덱스 1만 대문자로

    -print(len(a)) =4
    #a의 길이

    -print(a.replace('c','d')) =abda
    #c를d로 바꿔라

    -index=a.index('a') / print(index) = 0

    -index('a',index+1)
    #a를 찾아라, index+1이후부터! =3 , 즉 0 이후부터 a를 찾아라니깐 3이 나온다

    -print(a.find(e))
    #얘는 찾는 문자가 없으면 그냥 -1을 출력한다 그리고 뒤에 있는 것도 자동 진행

    -print(a.index(e))
    #얘는 찾는 문자가 없으면 에러 뜨고 거기서 끝내버린다. 다음 것 진행 안됨

    -print(a.count('a'))
    #'a'가 a 안에서 몇번이나 등장하는가 나타내는 것이다.

문자열 포맷

(1) 문자열 대신 변수 이용 %
-print('강아지 사료 %d개' %5) = 강아지 사료5개

-print('강아지 이름%s' %'누룽지') = 강아지 이름 누룽지

-print('강아지 이름 첫글자 %c' %'누')

-%s는 여러 숫자 인식하는 %d, 한글자 인식하는 %c 대신 쓰이기 가능하다,
또 두개 이상의 변수를 받기도 가능하
(ex) print('옆집 강아지 이름은 %s, 울집 강쥐 이름은 %s' %('연탄', '룽지'))

(2) 문자열 대신 변수 이용 : {}
-print('강쥐 {}마리'.format(5)) = 강쥐 5마리

-print('옆집 강쥐{}마리, 울집 강쥐{}마리'.format('3','4'))
= 옆집 강쥐3마리 울집 강쥐 4마리

==print('옆집 강쥐{0}마리, 울집 강쥐{1}마리'.format('3','4'))
#대괄호 안에 format괄호 안의 인덱스 넣어줘도 가능

==print('옆집 강쥐{num}마리, 옆집 강쥐 이름은 {name}이당'.format(num=3, name='연탄')

-변수 미리 선언 & 값 나오게 하기

>num=3 / name='연탄'
print(f'옆집 강쥐{num}마리, 옆집 강쥐 이름은 {name}이다')

탈출문자

(1) \n = 줄바꿈
-문장 안에서 따옴표 살리고 싶으면 따옴표 잎에 역슬래쉬 넣어주기 (\'hi\')
print('내 \'생각대루\' 살랭') = 내 '생각대루' 살랭

(2) \ => 문장에선 하나의 \로 나오게 된다, 하나의 \나오길 원하면 \두번쓰면 됨

(3)\r => 커서를 맨 앞으로 이동하고 r뒤의 문자들이 그 자리 대체
print('누룽지밥 바보\r김누룽지') = 김누룽지 바보

(4) \b => 백스페이스 (앞에 한 글자 삭제)
print('누룽지이\b울집강쥐') = 누룽지울집강쥐

(5) \t = > 탭
print('누룽지\t울집강쥐') =
누룽지
울집강쥐

리스트

-a=['연탄', '룽지', '복자']
print(a) = ['연탄', '룽지' '복자']

-a.append('사랑이')
a 리스트에 맨뒤에 '사랑이' 추가

-a.insert(2, '붕어빵')
룽지와 복자 사이에 (인덱스 2가 될 자리에) 붕어빵 추가

-print(a.pop()) => 맨 뒤 애를 끄집어 내는 것 = 사랑이 출력
=>그리고 이후엔 사랑이가 리스트에서 빠지게 된다

-print(a.count('룽지'))=1

  • 숫자 리스트

    -num_list=[3,2,1]
    <<앞에 프린트는 생략>
    (1) 순서대로 정렬하기
    -num_list.sort() = [1,2,3]

    (2) 역순 정렬
    -num_list.reverse()=[3,2,1]

    (3) 리스트 비우기
    -num)list.clear=[ ]

    (4) 여러자료형 함께 사용가능
    -mix_list=['누룽지', 5, true]

    (5) 리스트 합치기 - extend
    dog_list=['룽지', '연탄']
    dog_list.extend(mix_list)
    print(dog_list) = ['룽지','연탄','누룽지', 5, true]

사전

-dog={1:'룽지', 100:'연탄'}
키 : 값, 키2: 값2 로 지정해주면 된다

(1) print(dog[1]) = 룽지
#첫번째 키의 값을 뽑아라
print(dog[100])=연탄
#백번째 키의 값을 뽑아라

(2) print(dog.get(1)) = 룽지
#첫번째 값을 데려와라

-대괄호로 없는 키 뽑으면 오류나고 거기서 종료됨, 그런데 get으로 가져오면 none이라고 나오고 뒤의 프로그램은 계속해서 이어진다
-print(a.get(5)) = None
-print(a.get(5), '없으면 출력되는 값')) = 없으면 출력되는 값

(3) 사전에 있는지 여부도 체크 가능
print(1 in a) =true
print(4 in a) =false

(5) 업데이트도 가능
새로운 강아지를 리스트에 추가 / 혹은 기존키를 업데이트 시켜주는 것
a[50] = '사랑이'

(6) 지우기도 가능
del a[100] = 연탄이 키라 값이 사라진다

(7) 키들만 출력하기
print(a.keys())

(8) 값들만 출력하기
print(a.values())

(9) 키, 값 둘다 출력
print(a.items())

(10) 다 삭제
a.clear()

튜플

  • 내용 변경 x 그 대신 속도가 fast

print(a[0]) = 누룽지
a.add('사랑이') = 오류, 튜플에는 내용 변경이 불가하기 때문이다

(옆집 강쥐, 울집 강쥐, 남친 강쥐) = ('연탄', '룽지', '사랑이')
print(옆집 강쥐, 울집 강쥐, 남친 강쥐) = 연탄, 룽지, 사랑이

세트

  • 중복이 안되고 순서가 없다
    set = {3,4,5,5,5}
    print(set) = {3,4,5}

-dog={'누룽','연탄','사랑이'}
olddog = set(['누룽','해피'])

(1) 교집합 (개면서 나이든 개)
print(dog&olddog) = {'누룽'}
print(dog.intersection(olddog)) = {'누룽'}

(2) 합집합
print(dog|olddog)

print(dog.union(olddog))

(3) 차집합
print(dog-olddog)

print(dog.difference(olddog))

(4) 요소 추가
dog.add('누룽지맘')

(5) 요소 빼기
dog.remove('누룽지맘')

set = {}
list = []
tuple =()

자료 구조 변경

dogs={'룽지','연탄','사랑'}
dogs=list(dogs)
dogs=tuple(dogs)
dogs=set(dogs)
=> 이렇게 하면 구조 변경이 되는 것

반복문

  • if
    if a==b :
    print(~)
    elif a==c :
    print(~)
    else :
    print(~)

  • for
    for dogsnum in [1,2,3,4] "
    print('강쥐번호 : {0}'.format(dogsnum))

    => 강쥐번호 : 1
    강쥐번호 : 2
    강쥐번호 : 3
    강쥐번호 : 4
    for dogsnum in range(4) : 0에서 4미만까지 / range(1:6) 은 1이상 6미만
    print('강쥐번호 :{0}'.format(dogsnum))

  • while

dog = '룽지'
   index = 3
   while index >=1 :
   	print('{0}야밥묵어, {1}번만 더 부른다'.format(dog,index))
    index-=1
    if index=0 : 
    	print('너 밥없는줄알어')
  dog = '룽지'
   different_dog = 'unknown'

 while dog != different_dog : 
 	print('{0}~밥먹어'.format(dog))
   stranger = input('이름표 확인 : ')

=>stranger 자리에 룽지가 오게되면 끝나는 while 문

  • Continue & Break

(1) CONTINUE

 absent = [2,5]

for student in range(1,20) :

    if student in absent :

        continue 

    print('{0}, 책을 읽어봐'.format(student))


 *** <continue 만나면 밑에 있는 문장을 실행하지 않고  다음 학생 순서로 넘어가서 반복문 마무리>
 

(2) BREAK

absent = [2,5]

no_book=[7]

for student in range(1,20) :

    if student in absent :

        continue 

   elif student in no_book : 

        print('오늘 수업 여기까지, {0}은/는 교무실로 따라와'.format(student))

        break

    print('{0}, 책을 읽어봐'.format(student))

=> 책이 없는 학생에 걸리게 되면 교무실로 따라와~ 라는 BREAK 직전 까지만 출력하고 반복문을 탈출하게 된다

(3) 한줄 FOR 문

students = [1,2,3,4,5]

students=[i+100 for i in students]

print(students) = [101,102,103,104,105]

개이름을 길이로 변환

dog = ['룽지','나는야연탄이','사랑이']

dog = [len(i) for i in dog]

print(dog) = [2,6,3]

학생 이름을 대문자로 변환

dog =['rungji','love']

dog =[i.upper() for i in dog]

print(dog) = [RUNGJI, LOVE]

함수

  • def 함수이름(전달값) : ~ return 반환값
  • 함수 정의

def open_account() :

  print('새로운 계좌')

-이렇게 하면 정의만 하는 것이다

-open_account() 했을 때 비로소 호출

  • 전달값 반환값

(1)

def deposit(balance, money): 

   print('입금이 완료되었습니다. 잔액은 {0}원입니다.'.format(balance-money))

   return balance - money
   
   #함수 정의
   
def withdraw(balance, money) : 
   if balance > money : 
    print('출금 완료, 잔액은 {0}원'format(balance-money))
    return balance-money
   else : 
    print('출금이 불가, 잔액은 {0}원'.format(balance)
    return balance
balance =  0
balance = deposit(balance,1000)
balance = withdraw(balance, 2000) #출금이 불가 잔액은 1000원
balance = withdraw(balance, 500) #출금 완료 잔액은 500원

===> 변수 = 함수 / 라고 설정이 되면 해당 변수는 그 함수의 반환값을 지정받는 것

(2) 여러개의 값을 반환하는 경우

def withdraw_night(balance, money) : 

    commission = 100

    return commission, balance - money - commission

balance = 0
balance = deposit(balance, 1000)
commission, balance = withdraw_night(balance, 500)
print('수수료: {0} 원이며, 잔액은 {1}원입니다.'.format(commission, balance ))

=> 수수료 100원이며, 잔액은 400원입니다.

(3) 기본값 설정
(기본값 설정하기 전, 받는 대로 출력할 때)

def profile(name, age, main) : 

   print('이름:{0}\t나이: {1}\t주 사용 언어:{2}'.format(name,age,main))


profile('유재석', 20, '파이썬')

=>이름 : 유재석 나이 : 20 주 사용 언어 : 파이썬

(기본값 설정 - 나이와 주사용언어 )

def profile(name, **age=17, main='파이썬'**) : 

   print('이름:{0}\t나이: {1}\t주 사용 언어:{2}'.format(name,age,main))

​

profile('유재석')

=> 이름 : 유재석 나이 : 17 주 사용 언어 : 파이썬

  • 가변인자
    (가변인자 설정 전)
def profile(name, age, main1,  main2, main3, main4, main5):

    print('이름 : {0}\t나이 : {1}\t format(name, age), end = " ")     
	print( main1, main2, main3, main4, main5)
   

profile ('유재석', 20, " 파이썬", "자바", "씨", "씨플플","씨샵")

profile('김태호', 25, "쿼틀린", "스위프트", "","","") 이런식으로 변수 넣어주어야 하는데 그때그때 마다 저 메인5개 채우려고 뒤에 빈칸 남겨두는 것 아주 비효율적

(가변인자 설정 후)
가변인자 : *변수

def profile(name, age, *language):

    print('이름 : {0}\t나이 : {1}\t format(name, age), end = " ")    

   for lang in language : 

       print(lang, end=" ")

   print()
  • 지역변수와 전역변수 :
    지역변수는 함수 내에서만 쓸 수 있는 것, 함수 호출될 때 불러왔다가 없어지면 끝
    전역변수는 모두에서 가능

(1) 지역변수 :

gun = 10

def checkpoint(soldiers) :

 gun = gun - soldiers

 print ("[함수 네] 남은 총 : {0}".format(gun))

print("전체 총 : {0}".format(gun)) => 10

checkpoint(2)

print("남은 총 : {0}".format(gun)) => 에러
왜냐면 총이 함수 안에서 정의가 안되었기 때문
따라서 에러를 피하기 위해서는 함수 안에서 gun 변수를 새로 설정해주어야 해

gun = 10

def checkpoint(soldiers) :

      gun = 20  # => 여기서 일케 초기화 해줘야 한다!! 

     gun = gun - soldiers

     print ("[함수 내] 남은 총 : {0}".format(gun))

print("전체 총 : {0}".format(gun)) => 10 [전역변수 참조]

checkpoint(2) =>18 [함수 내의 지역변수 참조]

print("남은 총 : {0}".format(gun)) =>10 [전역변수 참조]

(2) 전역변수

gun = 10

def checkpoint(soldiers) :

     **global** gun                      #=> 전역 공간에 있는 gun을 사용하겠다

     gun = gun - soldiers

     print ("[함수 네] 남은 총 : {0}".format(gun))

=> 근데 전역변수 많이 사용하면 별로 좋지는 않다 그러므로
전역변수를 함수의 전달값과 반환 값으로 ~

gun =10 #전역변수

def checkpoint_ret(gun,soldiers) : 

      gun = gun - soldiers

      print ("[함수 내] 남은 총 : {0}".format(gun))

      return gun

print("전체 총 : {0}".format(gun))
#전체 총 : 10-전역변수 값

gun = checkpoint_ret(gun,2)
#변수 gun에 함수에 전역변수 10과 & 솔져 2 값을 넣어 반환값을 지정

print("남은 총 : {0}".format(gun)) #<- 반환값이 입력된 건으로 출력이 된다
#남은 총 : 8

+++DEF~ : / IF~ : 일케 세미콜론을 꼭 찍어주자, 빼먹지 말자

1.표준 입출력

<입력인자로 구분자 sep / end / 출력 file 을 지정할 수 있다
(1)

  • sep=' 분리기준값'
    print ('python', 'java', 'javascript' , sep = ' vs ' )
    일케 하면 사이 사이에 vs로 분리한다는 뜻
    => python vs java vs javascript

  • end='' / 한 줄로 이어주기
    print ( '누룽지' , '연타니', sep=' , ' , end=' ? ' )
    print( '둘다 너무 귀여오!')
    => end 없으면 두개 엔터키 쳐서 등장하는데 end는 밑에 문장까지 한 문장으로 이어준당
    => 누룽지 , 연타니 ? 둘다 너무 귀여오!
    뒤에 문장이 연달아서 한 문장으로 출력됨

(2) 표준 출력
=>file의 기본값은 표준출력 (sys.stdout)

  • import sys
    print ( '누룽지' , '연타니', file = sys.stdout) # 표준출력: 정상인 것
    =>파란색으로 출력이 된당
    print ( '누룽지' , '연타니', file = sys.stderr) # 표준에러: 에러-고쳐야하는 것
    => 빨간색으로 출력이 된당

  • 출력 포맷 :
    -정렬 : 오른쪽 정렬 - .rjust() / 왼쪽 정렬 - .ljust()
    ()안에는 공간 확보 하고 싶은 숫자를 입력

scores={'수학':0, '영어':50, '코딩':100}

for subject, score in scores.items() : 

   print(subject, score)

=>
수학 : 0
영어 : 50
코딩 : 100

scores={'수학':0, '영어':50, '코딩':100}

for subject, score in scores.items() : 

  print(subject.ljust(8), str(score).rjust(4), sep=':')

=>ljust - 8만큼의 공간을 확보하고 왼쪽으로 붙어라 /
rjust - 4만큼의 공간을 확보하고 오른쪽으로 붙어라

-zfill

for num in range(1,21) : 

   print('대기번호 :' + str(num).zfill(3))

=>zfill(3) 은 3 만큼의 공간을 확보하고 남은 자리는 0으로 메꾸어라 라는 뜻이당

-표준 입력
: input으로 입력을 받으면 항상 문자열str형태로 받는것

2.다양한 출력 포맷

{0:>n} n만큼 공간 확보하고 오른쪽 정렬 / {0:<n} n만큼 공간 확보하고 왼쪽 정렬 /
{0:,} 세자리마다 콤마 찍어주기

1.빈자리는 빈공간으로 두고 오른쪽 정렬을 하되 총 10자리 공간을 확보
=> print('{0: >10}'.format(500))
= 500

  1. 양수일 땐 +로 표시 음수일 땐 -로
    => print('{0> +10}'.format(500))
    = +500

  2. 왼쪽 정렬하고 빈칸으로 _로 채움

=>print('{0:_<+10}'.format(500))
=+500__

  1. 세 자리마다 콤마 찍어주기
    print('{0:,}'.format(10000))
    =>100,000

  2. 세자리마다 콤마를 찍어주기 + , - 부호도 붙이기
    print('{0:+,}'.format(100000))
    =>+100,000

  3. 세자리마다 콤마를 찍어주기, 부호도 붙이고 자릿수도 확보하기 빈자리는 ^로 채워
    print('{0:^<+30,}'.format(100000))
    +100,000^^^^^^^^^^^^

  4. 소수점 출력
    print('{0:f}.format(5/3))
    1.66667

  5. 소수점 특정자리수 까지만 표시
    {0 :.2f} 소수점 3째 자리에서 반올림해서 둘째 자리까지만 표현
    print('{0: .2f}.format(5/3))
    1.67

3.파일 입출력

  • 파일 오픈 : open('파일명', '명령어', encoding = 'utf8')
  • 명령어 : w(덮어쓰기) , a(이어서 첨가해서 쓰기) , r(읽기)
  • 파일 닫기 : 파일명_file.close

<파일 출력해주기>

score_file = open('score_txt','w',encoding='utf8')
prinf('수학 : 0 ',file=score_file)
print('영어 : 50', file = score_file)
score_file.close

=> score_txt 파일에 수학 : 0 , 영어 : 50 이라는 것 입력됨

score_file = open('score.txt', 'a', encoding = 'utf8')
#a는 기존에 있던 거에 이어서 첨가해서 쓰는 것
score_file.write('과학 : 80')
score_file.write('\n코딩 : 100')  
# 여기선 따로 프린트 처럼 엔터되지 않기 때문에 앞에 \n 해주는 것
score_file,close

=> 처음에 수학,영어 점수만 존재 했던 파일에 과학이랑 코딩도 더해짐

score_file = open('score.txt', 'r', encoding = 'utf8')
print(score_file.read())
score_file.close()

=> 파일에 있는 거 쫘르륵 출력해준다

-readline 줄별로 읽어라! (read는 모든 내용 읽기)

score_file = open('score.txt', 'r', encoding = 'utf8')
print(score_file.readline()) #줄별로 읽기, 한줄 읽고 커서는 다음줄로 이동
print(score_file.readline())
print(score_file.readline())
print(score_file.readline())
score_file.close()
=> 
수학 :0

​

영어 : 50

​

과학 : 0

​

코딩 : 100

​

-이런식으로 한줄 씩 띄어서 나옴 이 띄어서 나오게 하기 싫으면 print(score_file.readline(),end ' ' )
하면 띄어쓰기 없어서 나옴

-근데 다른 사람 거라서 몇줄인지 알지 못하는 경우에선~~
(1) while 문 활용

score_file = open('score.txt', 'r', encoding = 'utf8')
while true :
   line = score_fie.readline()
   **if not line** : #읽어올 라인이 부재하면
     break       #반복문 끝내고 탈출
   print(line)
score_file.close()
  

(2) 리스트 활용

score_file = open('score.txt', 'r', encoding='utf8')
lines = score_file.readlines() #모든 라인을 가지고 와서 list 형태로 저장
for line in lines : 
  print(line, end = " ")
score.file.close()

4.Pickle :

-일반 텍스트를 파일로 저장할 때는 파일 입출력을 이용

-그러나 리스트나 클래스와 같은 텍스트가 아닌 자료형은 일반적 파일 입출력 방법으로는
데이터를 저장하거나 불러올 수 없다
-따라서 파이썬에서는 이러한 텍스트 이외 자료형을 파일로 저장하고자 pickle 사용

-이를 사용해서 원하는 데이터를 자료형의 변경 없이 파일로 저장해 그대로 로드 가능

-프로그램 상에서 사용하고 있는 데이터를 파일로 저장,
상대에게 받으면 상대도 피클을 사용해서 파일을 연다

-피클로 데이터 저장 / 불러올 때는 파일을 b(byte)형식으로 읽거나 써야한다
so 바이너리(binary)를 항상 정의

-모든 파이썬 데이터 객체를 저장하고 읽을 수 있다.

링크텍스트 - 에서 피클 개념 보완

(1) pickle.dump(data, file)
: 밑의 예시에서는 dump 를 통해 프로필 파일에 있는 정보를 파일에 저장

import pickle
profile_file = open('profile.pickle', '**wb**')
#w은 쓰기를 의미하는 거고 b는 binary type,피클 쓰려면 항상 
**바이너리 타입 지정**해주어야 한다 , 따로 인코딩은 필요 없음
profile = {'이름' : '박명수', '나이' : 30, '취미 : ['축구', '골프', '코딩]}
print(profile)
****pickle.dump** (profile, profile_file)**
**#프로필 파일에 있는 정보를 파일에 저장하는 것**/ 프로필을 먼저 적어주고 어떤 파일에 저장할건지..
#피클을 이용해서 이 데이터를 파일에다가 쓰는 것이 중요-덤프를 이용하면 된당
profile_file.close

=> 프로필 피클이 생겼다, 그럼 저 파일에서 데이터를 가지고 오는 것

(2) pickle.load(file)
-이를 통해서 파일 읽어오려면 pickle dump 사용해 데이터 입력한 파일이어야 한다
: 파일에 있는 정보를 불러오는 것
: 한줄씩 파일을 읽어오고 더이상 로드할 데이터 없으면 EOFError

import pickle
profile_file = open('profile.pickle', '**rb**')
profile = **pickle.load**(profile_file) 
**#파일에 있는 정보를 프로필에 불러오는 것**
print(profile)
profile_file.close()

-with :
지금까지는 파일 다룰 때 파일을 열고 처리하고 닫는 과정 =>
with 쓰면 더욱 편하게 이 과정 진행 가능

with open('profile.pickle', 'rb') as profile_file : 
    print(pickle.load(profile.file))

=> 위와 같이 따로 close 할 필요 없음

with open('study.txt', 'w', encoding='utf8') as study_file : 
study_file.write('파이썬을 열심히 공부하고 있어요.')
  

with open ('study.txt', 'r' , encoding = 'utf8') as study_file :
print(study_file.read())

=> 파일 쓰는 것도 두문장, 읽는 것도 두문장이면 되니 아주 편리

클래스

: 붕어빵의 틀과 같은 것, 틀 하나만으로도 여러개의 붕어빵을 만들 수 있다

name = '룽지'
hp = 40
damage = 5

print('{} 유닛이 생성되었습니다.' .format(name))
print('체력{0}, 공격력{1}\n'.format(hp,damage))

tank_name = '연탄'
tank_hp = 150
tank_damage = 35

print('{} 유닛이 생성되었습니다.' .format(tank_name))
print('체력{0}, 공격력{1}\n'.format(tank_hp,tank_damage))

def attack(name, location, damage) : 

   print('{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]'.format(name, location, damage))

attack(name, '1시', damage)
attack(tank_name, '1시', tank_damage)

-근데 이러한 상황에서 수억개의 탱크를 만들어내고 싶은 경우에,
이렇게 하나하나 만들면 엄청난 시간이 소요.. =>이때 클래스를 사용

-탱크 클래스 제작

class Unit : 
    def __init__(self, name, hp, damage) : 
        self.name=name
        self.hp = hp
        self damage = damage
        print('{0} 유닛이 생성되었습니다.'.format(self.name))
        print('체력 {0}, 공격력 {1}'.format(self.hp, self.damage))

-아래와 같이 클래스를 통해서 태어난 애들을 객체라고 한다
그리고 '마린', '탱크'와 같은 아이들을 인스턴스(붕어빵)라고 한다
실제 세계에 존재하는 실체(instance)를 객체(object)라고 하고, 객체들의 공통점을 간추려서 개념적으로 나타낸 것이 클래스(class)
(개념 보완 : https://wikidocs.net/86)

marine1 = Unit('마린', 40, 5)
marine2 = Unit('마린', 40, 5)
tank = Unit('탱크', 150, 35)
  • init :
    생성자, 파이썬에서 클래스의 생성자를 만들때 쓰이는 항상 동일한 규칙이다
    클래스의 인스턴스가 생성될 때 자동으로 호출되는 함수이다
    인스턴스를 만들때 실행되는 함수
def __init__(self), name, hp, damage) : 

=> 이때 self 제외하고 나머지애들 수에 맞게 입력값 넣어줘야 한다

marine3=Unit('마린',40) 이라고만 쓰면 에러나는 거임 - name,hp,damage 다 넣어줘야 한당

-self :
클래스에서 사용하는 함수의 첫번째 인자를 self로 사용하는 것이 원칙
marine1 = Unit('마린', 40, 5) 에서 생성자(init)을 이용해서
마린,name,hp,damage순으로 인자를 넣어서 인스턴스(마린)을 찍어낼거야

  • 멤버변수
    : 클래스 내에서 정의된 변수
    아래에서 self.name, self.hp와 같은 애들, 초기화해서 쓸 수도 있고 그냥 쓸 수도 있음
class Unit : 
	  def __init__(self, name, hp, damage) : 
        self.name=name
        self.hp = hp
        self damage = damage
        print('{0} 유닛이 생성되었습니다.'.format(self.name))
        print('체력 {0}, 공격력 {1}'.format(self.hp, self.damage))

=>멤버변수는 함수 내에서 뿐만 아니라 외부에서도 쓸 수 있다

wraith1 = Unit ('레이스, 80,5)
print('유닛 이름 : {0}, 공격력 : {1}'.format(wraith1.name, wraith1.damage)) 
#마인드 컨트롤 : 상대방 유닛을 내 것으로 만드든 것 (빼앗기_
wraith2= Unit(' 빼앗은 레이스 ', 80,5)
wraith2.clocking = True
***clocking 이라는 변수 존재하지 않는데 만들어 쓴 것이다
if wraith2.clocking == True :
   print('{0}는 현재 클로킹 상태입니다.'.format(wraith2.name))

=>근데 밑과 같이 하면 오류가 난다. wraith2에만 확장이 되었지 1까지는 확장되지 않아서

if wraith1.clocking == True :
   print('{0}는 현재 클로킹 상태입니다.'.format(wraith2.name))

메소드

:클래스에 포함되어 있는 함수 <class 아래 def들>

class Unit : 
    **def __init__(self, name, hp, damage) : **
        self.name=name
        self.hp = hp
        self damage = damage
        print('{0} 유닛이 생성되었습니다.'.format(self.name))
        print('체력 {0}, 공격력 {1}'.format(self.hp, self.damage))
  
  class AttackUnit:
   def __init__(self, name, hp, damage) : 
        self.name=name
        self.hp = hp
        self damage = damage
  
   def attack (self, location) :
        print('{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]'\
.format(self.name,self.location,self.damage))

def damaged(self. damage) : 
   print('{0} : {1} 데미지를 입었습니다. format(self.name, damage)
   delf.hp-=damage
    print('{0} : 현재 체력은 {1} 입니다.'.format(self.name, self. hp)
    if self.hp<=0
      print ('{0} : 파괴되었습니다.'.format(self.name))

# firebat  : 공격 유닛 화염방사기
firebat1 = AttackUnit('파이어뱃', 50, 16)
firebat.attack('5시')
#공격을 2번 받는다고 가정
firebat.damaged(25)
firebat.damaged(25)

상속

class Unit : 
    **def __init__(self, name, hp, damage) : **
        self.name=name
        self.hp = hp
        self damage = damage
        print('{0} 유닛이 생성되었습니다.'.format(self.name))
        print('체력 {0}, 공격력 {1}'.format(self.hp, self.damage))
  
  class AttackUnit:
   def __init__(self, name, hp, damage) : 
        self.name=name
        self.hp = hp
        self damage = damage
  
   def attack (self, location) :
        print('{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]'\
.format(self.name,self.location,self.damage))

위에서 Unit 클래스와 AttackUnit 함수의

    self.name=name
    self.hp = hp
    self damage = damage

부분이 same 하다, 이런 경우에

class Unit : 
    def __init__(self, name, hp, damage) : 
        self.name=name
        self.hp = hp            #이부분은 same 하니깐 상속
		self.damage = damage
class AttackUnit(Unit) :  #괄호 열고 상속 받고 싶은 유닛을 넣어주기
   def __init__(self, name, hp, damage) :
         self damage = damage
 #damage 부분까지 똑같은데 name이랑 hp만 부른 것은
 #일부만 불러오면 이렇다..보여주려고 했던 것일까..?? 
        

=>Unit과 같이 자신의 속성 상속해주는 애를 부모 클래스, 어택유닛은 자식 클래스라고 한다

이해가 잘 되지 않아서 링크텍스트에서 개념 보완..!

class animal() : 
      def walk(self) : 
                 print('걷기')
class dog() : 
      def walk(self) :
                 print('걷기')
      def wag(self) : 
                 print('꼬리를 흔들어')
class me() : 
      def walk(self) :
                 print('걷기')
      def shake(self) : 
                 print('악수') 
rungji = animal()
rungji.walk()
rungji.wag()
human = me()
human.walk()
human.shake()                 

걷기
꼬리를 흔들어
걷기
악수

위와 같이 출력된다 그런데 dog, me 둘다 공통된 부분 존재한다

따라서 animal 이라는 공통된 부분 넣어놓은 클래스 만들고
얘를 이 둘에게 상속해주면

class animal() : 
      def walk(self) : 
                 print('걷기')
class dog(animal) : 
                 def wag(self) : 
                 print('꼬리를 흔들어') 
class me(animal) : 
                 def shake(self) : 
                 print('악수') 
rungji = animal()
rungji.walk()
rungji.wag()
human = me()
human.walk()
human.shake()   

이렇게 되고 똑같은 결과가 출력된다

  • 다중상속
#날 수 있는 기능을 가진 클래스

class Flyable : 
   def __init__(self, flying speed) : 
      self.flying_speed = flying_speed
   def fly(self, name, location) : 
      print('{0} : {1} 방향으로 날아갑니다. (속도{2})'\
       .format(name, location,self.flyting_speed)

#공중 공격 유닛 클래스 - flyable 과 attackunit 모두의 속성을 지닌다
class FlyableAttackUnit(AttackUnit, Flyable) : 
   def __init__(self, name, hp, damage, flying_speed) : 
      AttackUnit.__init__(self, name, hp ,damage)
      Flyable.__init__(self, flying_speed)

#발키리 : 공중 공격 유닛, 한번에 14발미사일을 발사 
valkyrie = FlyableAttackUnit('발키리', 200, 6, 5)
valkyrie.fly(valkyrie.name, '3시')
  • 매소드 오버라이딩
    : 자식의 속성을 가지고 싶을 때,
    부모 클래스의 매소드를 자식 클래스에서 재정의 하는 것이다 = <매소드의 재정의>
class Unit : 
    def __init__(self, name, hp, speed) : 
        self.name=name
        self.hp = hp 
        self.speed = speed
   def move(self, location) : 
      print('[지상 유닛 이동]') 
      print('{0} : {1} 방향으로 이동합니다. [속도 {2}]'\
.format(self.name, location, self.speed))

class AttackUnit:(Unit)  
   def __init__(self, name, hp ,speed, damage) : 
          Unit.__init__(self, name, hp, speed) 
          self.damage = damage
   def attack (self, location) :
        print('{0} : {1} 방향으로 적군을 공격합니다. [공격력 {2}]'\
.format(self.name,self.location,self.damage))
def damaged(self. damage) : 
   print('{0} : {1} 데미지를 입었습니다. format(self.name, damage)
   delf.hp-=damage
    print('{0} : 현재 체력은 {1} 입니다.'.format(self.name, self. hp)
    if self.hp<=0
      print ('{0} : 파괴되었습니다.'.format(self.name))

#날 수 있는 기능을 가진 클래스

class Flyable : 
   def __init__(self, flying speed) : 
      self.flying_speed = flying_speed
   def fly(self, name, location) : 
      print('{0} : {1} 방향으로 날아갑니다. (속도{2})'\
       .format(name, location,self.flyting_speed)


#공중 공격 유닛 클래스

class FlyableAttackUnit(AttackUnit, Flyable) : 
   def __init__(self, name, hp, damage, flying_speed) : 
      AttackUnit.__init__(self, name, hp ,0, damage) 

#지상 스피드를 0으로 설정 왜냐하면 얘한테는 지상스피드가 필요없기 때문이다
Flyable.__init__(self, flying_speed)
#벌쳐: _지상_ 유닛, 기동성이 좋음
vulture = AtackUnit('벌쳐', 80,10,20)
#배틀크루저 : _공중_ 유닛, 체력도 굉장히 좋음, 공격력도 좋음
battlecruiser = FlyableAttackUnit('배틀크루저', 500, 25, 3)
                 
vulture.move('11시')
batlecruiser.fly(battlecruiser.name, '9시')
      self.fly(self.name, location)

-여기서 프라블럼은 지상은 무브, 공중은 플라이 써야하니 매번 확인을 해야한다는 점이다 너무 귀차나~ 그러니깐 오버라이딩 기능을 써서 무브만 써도 알아서 되게 하는 방법!!!!
-공중 공격 유닛 클래스 ☜ 얘에 손을 대주면 된당
#FLYABLE 에서

class FlyableAttackUnit(AttackUnit, Flyable) : 
   def __init__(self, name, hp, damage, flying_speed) : 
      AttackUnit.__init__(self, name, hp ,0, damage) 
      Flyable.__init__(self, flying_speed)
 def move(self,location) :  #얘를 추가해주는 것 !!
      print('[공중 유닛 이동]')

원래는 flyable에서 move함수는 없고 아래의 fly함수만 있었다.

def fly(self, name, location) :
print('{0} : {1} 방향으로 날아갑니다. (속도{2})'\
.format(name, location,self.flyting_speed)

그런데 이 부모 속성이 오히려 해가 되고 있으니, 부모속성을 수정해서 재정의해주는 것

  • pass : 아무것도 하지 않고 넘어간다, 실행할 코드가 없다는 것 의미
    (vs continue는 다음 순번의 루프를 돌도록 강제하는 것이다
    링크텍스트여기서 개념 참고해보자면 :
    pass 하게 되면 그 뒤의 작업은 수행되지만, continue 에서는 수행되지 않고 바로 다음 루프순번으로 돌게 된다. 코드에 아무 영향도 미치지 않는다
    쓰는 경우 : 함수를 선언은 해놨으나 아직 내용 정의 부분은 미구현인 경우, 아무것도 써주지 않으면 에러 나겠지만 pass 이용해 작성하였으되 아무것도 하지 않고 그냥 지나가는 역할 가능
for i in [1,2,3] : 
         if i : 
           print 'pass %d' %i
           pass
         print 'me pass' 
for i in [4,5,6] : 
         if i : 
           print 'pass %d' %i
           pass
         print 'me continue'                  
                 

실행결과 =
pass1
me pass
pass2
me pass
pass3
me pass
pass4
pass5
pass6

class BuildingUnit(Unit) : 
   def __init__(self, name, hp, location) : 
      pass
#서플라이 디폿이라는 건물 : 건물 1개, 건물 =8만큼의 유닛 생성 가능
supply_depot = BuildingUnit('서플라이 디폿', 500 , '7시')


#pass : 아무것도 하지않고 그냥 넘어간다
#<추가적인 예시>

def game_start() : 
   print('[알림] 새로운 게임을 시작합니다.')
def game_over() :
   pass
  • super
    : 자식 클래스에서 부모클래스의 내용을 사용하고 싶을 경우 사용/
    오버라이딩만으로는 충분x경우 있다 마치 like
    부모의 행동 그대로 따라하되 어떤 것을 끼워놓고 싶은 상황
class BuildingUnit(Unit) : 
   def __init__(self, name, hp, location) : 
      Unit.__init__(self, name, hp, 0)
      self.location = location
#슈퍼 사용하면 이렇게 초기화
class BuildingUnit(Unit) : 
   def __init__(self, name, hp, location) : 
      super().__init__(name, hp, 0) #super() 형식, 근데 self 정보는 보여주지 X
      self.location = location 

+개념 보완 위해서 링크텍스트 예시 참고

class Animal() : 
  def walk(self):
  	print('걷기')
  def greet(self) : 
  	print('반갑다')
 
 class Me(Animal) :
   def wave(self) :
   	print('손을 흔들어')
  def greet(self) :             #이와 같이 부모 속성의 greet을 여전히 사용하긴 할건데
  	self.wave()					 중간에 뭘 추가하고 싶다!라고 할 때 추가할 요소, 
    super().greet() 			 수정할 요소 넣어주고 다시 부모속성 불러와주기
 
person = Me()
person.greet()  

=손을 흔들어
반갑다
라고 위에는 자식에서 추가한 요소, 밑에는 super로 부모 속성 그대로 가져와준다.

class Animal() : 
  def __init__(self, name) : 
  	self.name = name
  def greet(self) :
    print('{0}이/가 인사한다.'.format(self.name))
class Me(Animal) : 
  def __init__(self, name, hand) : 
     super().__init__(name)     #이거는 간단한 예시지만 만약 부모속성이 name말고도
     self.hand = hand		     수많은 변수 포함할 때, 이 속성을 사용하면
  def wave(self) :			     그 중에서 원하는 변수만 데려와 사용하는 것가능
   	print('[}손을 흔들어'.format(self.hand))
  def greet(self) :
  	self.wave()
	super()
person = Me('누룽지', '왼')
person.greet()

= 왼손을 흔들어
누룽지가 인사한다

예외처리, 오류 예외 처리 기법

링크텍스트 => 참고해서 개념을 보완!

<try, except>

try : ~
except : [발생 오류 [as 오류 메시지 변수]] : 

-try 블록 수행 중 오류가 발생하면 except블록이 수행된다.
하지만 try블록에서 오류가 발생하지 않는다면 except블록은 수행되지 않는다

try : 
   print('나누기 전용 계산기입니다.')
   num1 = int(input('첫 번째 숫자를 입력하세요 : ')
   num2 = int(input('두 번째 숫자를 입력하세요 : ')
   print('{0} / {1} = {2}'. format(num1, num2, int(num1/num2)))
except ValueError : 
   print('에러! 잘못된 값을 입력하였습니다.')

-일케 처리하면 '삼' 이런거 넣어도 무시무시한 에러 사항이 뜨지 않고 저 말이 프린트 될 뿐이다 근데 삼 이런거 아니고 num2에 0을 넣으면 다시 길다란 에러가 뜬다용 =>또 except 처리 해주면 된다
아래의 except 문을 넣어주면 돈다

except ZeroDivisionError as err : #저 as err을 사용하면 구체적으로 어떤 에러가 났는지 알려줌
   print(err)   

그래서 num2에 0이 들어가면
=> zeroDivisioneError : division by zero / 이렇게 뜬다

근데 위의 두개 에러 사항 말고도 다른 에러사항들이 존재할 수 있다
그 나머지들을 한번에 한다고 하면

except : 
print('알 수 없는 에러가 발생했습니다.')

-이렇게 하면 다른 에러들 발생시에 저 프린트문이 나오게 되는 것
근데 구체적으로 어떤 에러가 났는지 알고 싶을 수 있다, 그러면
except Exception as err :
print('알 수 없는 에러가 발생했습니다.')
print(err)
=> 이렇게 하면 프린트문이 먼저 뜨고 그 밑에 이것이 어떤 에러인지 출력된다.

except 구문은 다음 세가지로 사용할 수 있다.
<try~ except>
1. try, except만 사용:
이 경우는 오류 종류에 상관없이 오류 발생시 except블록 수행

<try~ except발생오류 : >
2. 발생 오류만 포함한 except문 :
오류가 발생했을 시에 except문에 미리 정해놓은 오류 이름과 일치할 때만

<try~ : except 발생오류 as 오류메시지 변수 : >
3. 발생 오류와 오류 메시지 변수까지 포함한 except문 :
-이 경우는 두번째 경우에서 오류메시지의 냉용까지 알고 싶을 때 사용하는 방법
(ex)

try : 4/0
 except ZeroDivisionError as e :
  print(e)>

= 결과값 : division by zero

  • 에러 발생시키기 :
    필요할 때 의도적으로 에러를 발생시켜서 except 구문으로 빠지게 하는 것
    파이썬은 raise를 사용해 오류 가제로 발생시킬 수 있다
try : 
   print('한 자리 숫자 나누기 전용 계산기입니다.') 
   num1=int(input('첫 번째 숫자를 입력하세요 : '))
   num2=int(input('두 번째 숫자를 입력하세요 : '))
   if num1 > = 10 or num2 >=10 : 
      raise ValueError #필요할 떄 의도적으로 에러를 발생 except구문으로 빠지게함
  print ('{0} / {1} = {2}'. format(num1, num2, int(num1/num2))
except ValueError : 
   print('잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요')
  • 사용자 정의 예외처리 :
    위에서 사용한 ValueError 라던가 ZerodivisionError 같은 경우는 파이썬에서 규정하고
    있는 에러이다, 우리가 직접 정의해서 에러 만들기도 가능하다
class BigNumberError(Exception) : 
   pass
try : 
   print('한 자리 숫자 나누기 전용 계산기입니다.') 
   num1=int(input('첫 번째 숫자를 입력하세요 : '))
   num2=int(input('두 번째 숫자를 입력하세요 : '))
   if num1 > = 10 or num2 >=10 : 
      raise BigNumberError
  print ('{0} / {1} = {2}'. format(num1, num2, int(num1/num2))
except ValueError : 
   print('잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요')
except BigNumberError :
   print('에러가 발생했습니다. 한 자리 숫자만 입력하세요')

근데 만약 이에서 그치지 않고 빅넘버에러 발생에 대한 메시지를 넣으려는 경우에는

class BigNumberError(Exception) : 
   def __init__(self, msg) : 
      self.msg=msg
   def __str__(self) : 
      return self.msg

-이렇게 설정해주면 빅넘버에러가 입력받은 msg를 출력한다는 뜻이다. 따라서

try : 
   print('한 자리 숫자 나누기 전용 계산기입니다.') 
   num1=int(input('첫 번째 숫자를 입력하세요 : '))
   num2=int(input('두 번째 숫자를 입력하세요 : '))
   if num1 > = 10 or num2 >=10 : 
      raise BigNumberError("입력값 : {0] , {1}".format(num1, num2))
  print ('{0} / {1} = {2}'. format(num1, num2, int(num1/num2))
except ValueError : 
   print('잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요')
except BigNumberError as err :
   print('에러가 발생했습니다. 한 자리 숫자만 입력하세요')
   print (err)

-이렇게 만들고, num1 ,2에 각각 10과 5를 넣으면

에러가 발생했습니다. 한 자리 숫자만 입력하세요 
입력값 : 10, 5

라고 출력이 된다..!

  • 오류 회피하기 : 프로그래밍 하다 보면 특정 오류가 발생할 경우, 그냥 통과시켜야 할 때가 있다

<try~ finally> : 개념 보완 from 링크텍스트

: try 문에는 finally를 사용할 수 있다.
finally는 try문 수행 도중 예외 발생 여부에 상관없이 항상 수행된다
어떤 값을 넣건, 어떤 에러가 나던 간에 finally 속 구문은 꼬옥 출력이 된다
보통 finally 절은 사용한 리소스를 close 해야 할 때 사용

f = open('foo.txt', 'w')
try:
    # 무언가를 수행한다.
finally:
    f.close()
try : 
   print('한 자리 숫자 나누기 전용 계산기입니다.') 
   num1=int(input('첫 번째 숫자를 입력하세요 : '))
   num2=int(input('두 번째 숫자를 입력하세요 : '))
   if num1 > = 10 or num2 >=10 : 
      raise BigNumberError("입력값 : {0] , {1}".format(num1, num2))
  print ('{0} / {1} = {2}'. format(num1, num2, int(num1/num2))
except ValueError : 
   print('잘못된 값을 입력하였습니다. 한 자리 숫자만 입력하세요')
except BigNumberError as err :
   print('에러가 발생했습니다. 한 자리 숫자만 입력하세요')
   print (err)
finally :  #어떤 값을 넣든~ 어떤 에러가 나던 간에 이 구문은 꼬옥 출력이 된당
   print('계산기를 이용해 주셔서 감사합니다.')

모듈

: 필요한 것들끼리 부품처럼 잘 만들어진 파일

: 함수나 변수 또는 클래스를 모아 놓은 파일이다.
모듈은 다른 파이썬 프로그램에서 불러와 사용할 수 있게끔 만든 파이썬 파일
: 파이썬 확장자 .py로 만든 파이썬 파일은 모두 모듈이다

-->비쥬얼 스튜디오에서 theater_module이라는 파일 만들어서 여기다가 구문들 옮겨쓰기

#일반가격
def price(people) : 
print('{0}명 가격은 {1}원입니다.'.format(people, people*10000))
#조조할인 가격
def price_morning(people) : 
print('{0}명 조조 할인 가격은 {1}원입니다.'.format(people, people*6000))
def price_soldier(people) :
pring('{0}명 군인 할인 가격은 [1}원입니다.'.format(people, people*4000))

import 모듈이름 / 으로 불러오면 된다

다른 파일에서
import theater_module 
theater_module.price(3)                #3명이서 영화를 보러 갔을 때 가격
theater_module.price_morning(4)        #4명이서 조조할인 영화를 보러 갔을 때
theater_module.price_soldier(5)
#일케 하면 모듈에 있던 내용 불러와서 사용하는 것이 가능하게 된다
그런데 저거 너무 길다 쓰기ㅠㅠ 그래서 쉽게 쓰는 법이 존재한다 두둥
   
import theater_module as mv #모듈명 길면 줄여서 사용하는 것이 가능
mv.price(3)
mv.price_soldier(5)
   
#또 모듈명을 아예 생략하고 시프다면
from theater_module import * #일케 불러오면 된당
price(3)
price_morning(4)
price_soldier(5)

#근데 나는 전역을 한 상태라서 군인 할인 정보에 대해서는 알고 싶지 않다면
from theater_module import price, price_morning
# 이런 식으로 특정 애들만 가져와서 쓰기도 가능

링크텍스트에서 개념참조

  • ifname == 'main__' 을 사용하면 <C:\doit>python mod1.py> 처럼 직접 파일을 실행했을 때는 이것이 참이 되어 if문 다음 문장이 수행 / 반대로 대화영 인터프리터나 다른 파일에서 이 모듈 불러 사용할 때는 이것이 거짓이 되어 if문 다음 문장이 수행되지 않는다
# mod1.py 
def add(a, b): 
    return a+b
def sub(a, b): 
    return a-b
print(add(1, 4))
print(sub(4, 2))

이러한 함수를

C:\Users\pahkey> cd C:\doit
C:\doit> python
Type "help", "copyright", "credits" or "license" for more information.
>>> import mod1

이렇게 import하면 그냥 지 혼자 알아서 mod1.py가 실행이 된다,
그저 import 해서 add랑 sub함수만 사용하려고 했는데..
이런 문제 방지 위해서 mod1.py를 다음과 같이 수정

# mod1.py 
def add(a, b): 
    return a+b

def sub(a, b): 
    return a-b

if __name__ == "__main__":
    print(add(1, 4))```
코드를 입력하세요
print(sub(4, 2))

=> 이 경우는 직접적으로 수행을 할 경우에 name=main 이 참이 되어 if문장 수행 가능, 반대로 대화영 인터프리터나 다른 파일에서 이 모듈 불러서 사용할 시에 이는 거짓이 되어 if문 다음 문장이 수행되지 않음

  • 모듈 불러오는 방법 :

<#modest.py>

import mod2
result = mod2.add(3, 4)
print(result)

=> 이런 식으로 modest와 mod2가 동일한 디렉터리 위에 있으면 위는 정상적으로 실행

  • 모듈 불러오는 various ways : 디른 디렉토리에 있는 경우........ (1) 모듈을 저장한 디렉토리로 이동하지 않고 모듈을 불러와서 사용하는 방법
    <우선> 이전에 만든 mod2.py파일을 C:\doit\mymod 로 이동
        ```
    C:\Users\pahkey>cd C:\doit
    C:\doit>mkdir mymod
    C:\doit>move mod2.py mymod
    1개 파일을 이동했습니다.
        
  	  <1> sys.path.append 이용  
        - 먼저 sys 모듈 불러오기 : sys모듈은 파이썬 설치될 때 함께 설치되는 라이브러리 모듈, sys 사용하면 파이썬 라이브러리 설치되어 있는 디렉터리 확인 가능
        ```
C:\doit>python
>>> import sys
    - sys.path 입력하면 파이썬 라이브러리가 설치돼있는 디렉토리를 show
    ```

sys.path
['', 'C:\Windows\SYSTEM32\python37.zip', 'c:\Python37\DLLs',
'c:\Python37\lib', 'c:\Python37', 'c:\Python37\lib\site-packages']

만약 파이썬 모듈이 위 디렉토리에 들어있으면, 모듈이 저장된 디렉터리로 이동할 필요 없이 바로 불러서 사용할 수 있을 것. 그래서 sys.path에 C:\doit\mymod 디렉터리를 추가하면 아무데서나 불러 사용하기 가능할 것. sys.path 결과값은 리스트이므로

    ```

sys.path.append("C:/doit/mymod")
sys.path
['', 'C:\Windows\SYSTEM32\python37.zip', 'c:\Python37\DLLs',
'c:\Python37\lib', 'c:\Python37', 'c:\Python37\lib\site-packages',
'C:/doit/mymod']

이렇게 하면 이제 모듈 불러와서 사용하기 가능 -import mod2

<2> PYTHONPATH 환경 변수 사용하기
set명령어 이용해 pythonpath 환경 변수에 od2.py파일이 있는 C:\doit\mymod 디렉토리를 설정한다. 그럼 디렉터리 이동이나 별도의 추가 모듈 추가 안해도 mod2모듈 불러와서 사용 가능

패키지

: 모듈들을 모아놓은 집합 사용하기

도트(.)을 사용해 파이썬 모듈을 계층적으로 관리할 수 있게 해줌
파이썬 패키지는 디렉터리와 파이썬 모듈로 이루어진다
간단한 파이썬 프로그램이 아니라면 이렇게 패키지구조로 프로그램 만드는 것이 공동작업이나 유지보수 등 여러면서 유리

  • travel / 밑에 init.py랑 갈 국가인 Thailand, Vietnam .py 제작,내용도 입력 ,
  • 이때 init.py 파일이 없다면 패키지로 인식되지 않는다 / 파이썬 3.3부터는 init.py없어도 패키지로 인식 가능하기 시작 .. 하지만 하위 버전 호환을 위해 init.py 생성하는 것 안전
        
from travel import *
trip_to = vietnam.VietnamPackage()
trip_to.detail()

=> 이라고 하면 결과값으로 vietnam이 정의되지 않았다고 뜬다 모든것을 (*) import하는데 왜 안되는걸까? => 그거슨 바로바로 실제로는 개발자가 공개범위를 설정해주어야 한다 =>그래서 아까 만들어두었던 init 파일에 들어가서

__all__ = [ 'vietnam' ] 

해주면 정상적으로 뜬다, Thailand도 베트남 옆에 콤마로 이어서 써주면 Thailand만 불러와도 가능능능

class ThailandPackage :
   def detail(self) : 
      print('[태국 패키지 3박 5일] 방콕, 파타야 여행 (야시장 투어) 50만원 ]')

베트남 들어가서
class VietnamPackage :
      def detail(self) : 
         print('[베트남 패키지 3박 5일] 다날 효도 여행 60만원]')

그 다음에 실행을 하면

import travel.thailand
trip_to = travel.thailand.ThailandPackage()
trip_to.detail() 

이렇게 된다,
이때 주의할 점은 :
import travel.thailand
import 쓸 때 이 맨 뒷부분(thailand부분)은 항상 모듈이나 패키지만 가능하다, 클래스나 함수는 import를 바로 할 수 없다. (만약 import travel.Thailand.ThailandPackage
일케 불러오면 오류남)
그런데 from travel.thailand import Thailandpackage 에서는 또 가능

from travel.thailand import ThailandPackage
trip_to=ThailandPackage()
trip_to.detail()
  • all
from travel import *
trip_to = vietnam.VietnamPackage()
trip_to.detail()

이라고 하면 결과값으로 vietnam이 정의되지 않았다고 뜬다 모든것을 (*) import하는데 왜 안되는걸까?
그거슨 바로바로 실제로는 개발자가 공개범위를 설정해주어야 한다.
그래서 아까 만들어두었던 init 파일에 들어가서

__all__ = [ 'vietnam' ] 

하면 제대로 뜬다
근데 여기다가 타일랜드 하면 또 안됨 - 그래서 init 들어가서 all dml vietnam 옆에다가 , 'thailand'입력해주고 하면
타일랜드 잘 입력되어서 나온당

  • all 개념 보완 from 링크텍스트
    -특정 디렉터리의 모듈을 *를 사용하여 import할 때에는 다음과 같이 해당 디렉터리의 init.py 파일에 all 변수를 설정하고 import할 수 있는 모듈을 정의해 주어야 함!

모듈 직접 실행

모듈 직접 실행
class ThailandPackage :
   def detail(self) : 
      print('[태국 패키지 3박 5일] 방콕, 파타야 여행 (야시장 투어) 50만원 ]')

if __name__ == "__main__" :   #타일랜드.py 안에서 실행될 때는 이 구문이 출력된다
   print('Thailand 모듈을 직접 실행')
   print('이 문장은 모듈을 직접 실행할 때만 실행돼요')
   trip_to=ThailandPackage()
   trip_to.detail()

else :  # 다른 곳, practice.py같은 곳에서 호출을 하면 이게 출력된당
   print('Thailand 외부에서 모듈 호출')

pip

=> 파이썬으로 작성된 패키지 소프트웨어 설치하거나 관리하는 패키지 관리 시스템-
=> pipy라는 사이트에서 다양한 애들 있으니깐 필요한 애를 쳐서 들어가서 클립보드 복사해서 밑에 출력창에 입력하면 설치가 자동으로 된다 그러면 그 예제에 있는 위에 문장들 데려와서 사용가능.

내장함수

: [list of python bullitins]
따로 import할 필요 없이 파이썬 안에 내장되어 있는 함수
(더 다양한 내장함수 개념 보완 링크텍스트 )

#input 함수라던가

#dir 어떤 객체를 넘겨줬을 때 그 객체가 어떤 변수와 함수를 가지고 있는지 표시

print(dir())   
   
import random #외장 함수
print(dir())
   
import pickle
print (dir())

=> ['annotations', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'spec']

['annotations', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'spec', 'random']

['annotations', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'spec', 'pickle', 'random']

이렇게 출력된다.

import random #외장 함수
print (dir(random))

=> 이렇게 하면 랜덤 모듈 안에서 무엇을 사용할 수 있는지..
혹은
<lst = [1,2,3]/ print(dir(lst))> , <lst = [1,2,3]/ print(dir(lst))> => 이런식으로 한다면 각각 list, str에서 쓸 수 있는 것들 출력 (ex : add, class, dir 등등)

외장함수

: import 써서 불러와야 하는 것들 구글에 [list of python modules] 쓰기

0개의 댓글

관련 채용 정보