TIL#28 import error 상대경로 절대경로

상대경로와 절대경로에서 어떤 경우에 import에러가 나타나는지 살펴보자. import os print(os.path.abspath('.')) #현재 폴더의 절대경로를 물어보는 것 C:\Users\Jaesang Choi\Desktop\CALC #현재 폴더의 절..

higher77.tistory.com

 

 

 

 

 

main.py

from calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))

 

multiplication.py

def multiply(a,b):
return(a*b)

 

add_and_multiply.py

from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)

 

 

 

 

 

 

 

 

 

 

하위폴더 파일 import하기

<메인모듈 상관없음>

 

main.py를 기준으로 설명.

 

from calculator.add_and_multiply import add_and_multiply #함수를 가져옴
if __name__ == '__main__':
print(add_and_multiply(1,2))
from calculator import add_and_multiply #모듈을 가져옴
if __name__ == '__main__':
print(add_and_multiply.add_and_multiply(1,2))

 

 

 

 

 

 

 

 

동일폴더 파일 import하기

 

 

1) <메인모듈: main.py>일때 

 

add_and_multiply.py가 multiplication.py를 import한다.

 

 

 

 

add_and_multiply.py

from calculator import multiplication #절대경로 모듈
def add_and_multiply(a,b):
return multiplication.multiply(a,b) + (a+b)
from calculator.multiplication import multiply #절대경로 함수
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)

<메인모듈이 main.py>일 때는 os.getcwd()의 값이

 

C:\Users\Jaesang Choi\Desktop\CALC으로 나와서 calculator부터 절대경로를 설정해줘야한다.

 

 

 

 

from .multiplication import multiply #상대경로 함수
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
from . import multiplication #상대경로 모듈
def add_and_multiply(a,b):
return multiplication.multiply(a,b) + (a+b)

 

 

 

 

 

 

2) <메인모듈: add_and_multiply.py>일때 

 

add_and_multiply.py가 multiplication.py를 import한다.

 

 

import multiplication #모듈
def add_and_multiply(a,b):
return multiplication.multiply(a,b) + (a+b)
from multiplication import multiply #함수
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)

<메인모듈: add_and_multiply.py> os.getcwd()의 값도

 

C:\Users\Jaesang Choi\Desktop\CALC으로 나오지만 그건 atom으로 폴더를 열 때

CALC를 열어서 그렇게 나오는 것이다.

 

atom으로 새창에서 add_and_multiply.py가 있는 calculator폴더를 열면

os.getcwd()의 값이 

C:\Users\Jaesang Choi\Desktop\CALC\calculator로 제대로 나온다.

 

그래서 바로 multiplication을 적는 것이다.

 

 

 

 

 

 

상위폴더 파일 import하기

 

 

 

 

 

<메인모듈 상관없음>

multiplication.py를 기준으로 설명.

 

 

devide.py를 추가했다.

def devi(a,b):
return(a/b)

 

 

 

 

 

calculator폴더 안의 mutuplication.py에서 devide.py를 불러오고 싶을 때

#def multiply(a,b):
# return(a*b)
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
import devide #모듈
print(devide.devi(6,2)) #3.0
#def multiply(a,b):
# return(a*b)
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from devide import devi #함수
print(devide.devi(6,2)) #3.0

 

실행파일 경로의 1단계 상위 폴더를 구하는 코드는 os.path.dirname(os.path.abspath(os.path.dirname(__file__))) 이다.

 

2단계 상위 폴더는

os.path.dirname(os.path.abspath(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))))이다.

 

 

 

 

 

 

 

 

 

 

calculator/mutuplication.py에서 calculator2/devide.py를 불러오고 싶을 때

#def multiply(a,b):
# return(a*b)
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from calculator2 import devide #모듈
print(devide.devi(6,2)) #3.0
#def multiply(a,b):
# return(a*b)
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from calculator2.devide import devi #함수
print(devi(6,2)) #3.0

 

 

 

 

 

 

 

 

 

 

 

다른경로의 파일 import

 

 

다른경로의 파일을 import할 경우

import sys
sys.path.append(다른 경로의 파일)

sys.path.append에 다른경로의 path를 넣어주면 된다.

 

 

 

 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

sys.path.append를 사용하지 않고 하는 방법은 

시스템의 환경변수 PYTHONPATH에 프로젝트를 추가하는 방법이 있다.

 

이 방법은 모든 파이썬 프로젝트에서 built-in모듈을 그냥 import 할 수 있는 것과 마찬가지의 원리로

시스템의 파이썬 컴파일러가 기본적으로 참조하게 될 패키지 모듈에 자신의 프로젝트를 추가하는 형태이다.

 

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

 

 

 

os.path.dirname(os.path.abspath(os.path.dirname(__file__)))의미

print(os.path.dirname(__file__))
print(os.path.abspath(os.path.dirname(__file__)))
print(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
C:\Users\Jaesang Choi\Desktop\CALC\calculator
C:\Users\Jaesang Choi\Desktop\CALC\calculator
C:\Users\Jaesang Choi\Desktop\CALC
경로 중 디렉토리명만 얻기
os.path.dirname("C:/Python35/Scripts/pip.exe") # "C:/Python35/Scripts"
특정 경로에 대해 절대 경로 얻기
os.path.abspath(".\Scripts") #"C:\Python35\Scripts"
os.path.abspath(".") #점(.)은 현재 디렉토리(작업 폴더)를 의미함으로 이것은 현재 디렉토리의 절대 경로를 얻는것이다.
현재 수행중인 코드를 담고 있는 파일의 위치 path
__file__

 

 

 

 

 

 

 

 

'Python > Today I learned' 카테고리의 다른 글

TIL#35 객체, 클래스, 인스턴스 관계정리(매우 중요)  (0) 2021.05.20
TIL#34 클래스 self  (0) 2021.05.20
TIL#33 CSV 파일 읽기 및쓰기  (0) 2021.05.19
TIL#32 파일 읽기 및 쓰기  (0) 2021.05.19
TIL#31 외장함수  (0) 2021.05.19

 

 

 

 

 

객체(object)라는 개념을 구성하는 2개의 단어는 

 

클래스(Class)인스턴스(instance)이다.

 

클래스는 그룹,분류,교실과 같은 뜻으로 쓰이고 

인스턴스는 구체적인 사례, 예제라는 뜻으로 쓴다.

 

포유류는 클래스로 볼 수 있고

구체적인 사례인 개,고양이,사자는 인스턴스라고 볼 수 있다.

 

 

 

클래스와 인스턴스의 개념의 관계를 더 자세히 살펴보자.

 

 

클래스는 프로그램에서 서로 연관있는 변수와 함수들을 그룹핑한 묶음 또는 수납공간으로 보면 된다.

 

 

 

 

 

 

클래스를 복제해서 만든 것들을 인스턴스라고 부른다.

 

인스턴스는 클래스를 복제해서 만들었기 때문에 클래스와 똑같은 변수와 똑같은 함수를 갖게된다.

 

 

 

 

 

 

 

 

각각의 인스턴스들은 클래스를 복제했기 때문에 클래스가 가지고 있는 변수와 함수를 가지고 있다.

 

 

이 중에서 각각의 인스턴스들이 갖고 있는 함수의 내용은 똑같다.

그러나 인스턴스마다 변수에 담겨있는 값이 다를 수 있다.

 

 

 

 

 

두 가지다 문자열을 만드는 똑같은 방법이다.

 

문자열을 만들 때마다 밑에처럼 하면 너무 불편하기 때문에 

그냥 "egoing"이라고 하면 egoing이라는 값을 가진 객체가 생성된다.

 

 

 

str은 class이고

 

str("egoing")은 instance이다.

 

그리고 인스턴스는 name이라는 변수에 담기게 된다. 

 

 

 

 

name인스턴스와 name2인스턴스 안에는 어떤 이름의 변수가 있는지는 모르지만 

아무튼 변수를 가지고 있고 그 변수 안에는 name은 egoing이라는 값을 가지고 있고

name2는 k8805라는 값을 가지고 있다.

 

 

 

 

 

 

 

 

주어진 인스턴스가 특정 클래스(데이터 타입)인지 검사해주는 isinstance함수를 톻해서 

문자열 "egoing"이 str클래스(데이터 타입)의 인스턴스인지 확인해보고

다른 클래스(데이터 타입)도 확인해 보자.

 

# str 인스턴스인지 검사
result = isinstance("egoing", str)
print(result) #True
# int 인스턴스인지 검사
result = isinstance(1, int)
print(result) #True
# float 인스턴스인지 검사
result = isinstance(1.345, float)
print(result) #True
# dict 인스턴스인지 검사
result = isinstance({'최재상':27,'최재현':30}, dict)
print(result) #True
# list 인스턴스인지 검사
result = isinstance([1,2,3], list)
print(result) #True
class Programmer:
pass
# Class 검사
Jaesang = Programmer()
result = isinstance(Jaesang, Programmer)
print(result) #True

 

 

 

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

객체지향 프로그래밍의 맥락에서는

 

함수라는 말 대신에 메소드라는 말을 쓴다.

 

변수라는 말은 변수도 쓸 수 있고 속성,필드,상태라고 부를 수 있다.

 

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

아래 내용은 객체,인스턴스의 차이를 말해주는 내용.

 

 

 

 

객체와 인스턴스의 차이를 알아보니 블로그마다 말이 다르다.

어떤 블로거는 인스턴스는 객체와 같지만, 관계적인 측면에서 이야기할 때 객체 대신 인스턴스라는 말을 쓴다고 하고, 또 어떤 블로거는 메모리 상에 할당되어야만 객체가 인스턴스가 된다고 한다.

이해 가는 내용이지만, 정확하지는 않다고 본다.

 

 


결국에는 영어 사이트를 검색했고, 가장 납득이 가는 설명이 담긴 블로그를 찾았다.

https://alfredjava.wordpress.com/2008/07/08/class-vs-object-vs-instance/

 

 


이 블로그의 설명에 따르면 객체(Object) 소프트웨어 세계에 구현할 대상이고, 이를 구현하기 위한 설계도 클래스(Class)이며, 이 설계도에 따라 소프트웨어 세계에 구현된 실체 인스턴스(Instance)이다.

 

객체(Object)는 현실의 대상(Object)과 비슷하여, 상태나 행동 등을 가지지만, 소프트웨어 관점에서는 그저 콘셉(concept), 즉 사유의 결과일 뿐이다. 소프트웨어에서 객체를 구현하기 위해서는 콘셉 이상으로 많은 것들을 사고하여 구현해야 하므로, 이를 위한 설계도로 클래스를 작성한다. 설계도를 바탕으로 객체를 소프트웨어에 실체화 하면 그것이 인스턴스(Instance)가 되고, 이 과정을 인스턴스화(instantiation)라고 한다. 실체화된 인스턴스는 메모리에 할당된다. 

 

코딩을 할 때, 클래스 생성에 따라 메모리에 할당된 객체인 인스턴스를 객체라고 부르는데, 틀린 말이 아니다.

 

인스턴스라고 부르면 더 정확하지만, 개념적으로 인스턴스는 객체에 포함된다고 볼 수 있다. 물론 어디가 소프트웨어 세계에 더 가깝냐를 따지면 당연히 인스턴스이다. 잘 구분해서 쓴다면 프로빼쌰날(?) 하다는 소리를 들을 수 있을지도.

 

그러나 객체나 인스턴스를 클래스로, 혹은 클래스를 객체나 인스턴스라고 해선 안 된다. 건물의 설계도를 보고 건물이라고 하지 않고, 반대로 건물을 설계도라고 하지 않으니까~

 



출처: https://cerulean.kkennib.com/149 [kkennib]

 

 

 

 

객체(소프트웨어 세계에 구현할 대상)클래스(설계도) + 인스턴스(소프트웨어 세계에 구현된 실체)인 것이다.

 

 

 

 

 

 

 

 

 

 

 

'Python > Today I learned' 카테고리의 다른 글

TIL#36 하위,동일,상위폴더 파일 import하기  (0) 2021.05.20
TIL#34 클래스 self  (0) 2021.05.20
TIL#33 CSV 파일 읽기 및쓰기  (0) 2021.05.19
TIL#32 파일 읽기 및 쓰기  (0) 2021.05.19
TIL#31 외장함수  (0) 2021.05.19

 

 

 

 

TIL#25 클래스 와 인스턴스(중요)

클래스와 인스턴스 # 파이썬 클래스 # OOP(객체 지향 프로그래밍), Self, 인스턴스 메소드, 인스턴스 변수 # 클래스 and 인스턴스 차이 이해 # 네임스페이스 : 객체를 인스턴스화 할 때

higher77.tistory.com

위 내용의 보충설명을 위해 작성되었다.

 

 

 

 

 

 

class Cal:
def __init__(v1, v2):
print(v1,v2)
def add():
return v1 + v2
c1 = Cal(10,10)
print(c1.add())

 

만약 Cal클래스가 위와 같이 생겼다면 

 

v1과 v2는 __init__메소드의 지역변수(그 함수 안에서만 사용되는 변수)이기 때문에 

 

add메소드는 값을 구할 수 없고 에러가 나온다.

<#물론, __init__함수도 self 매개변수가 없기 때문에 실행안됨.>

 

 

 

그걸 해결하기 위해서 Self 매개변수를 사용해야한다.

 

 

 

////////////////////////////////////////////////////////////////////////////////////////

 

 

self는 뭘 의미하는 걸까?

class Person:
def __init__(self):
self.hello = '안녕하세요.'
def greeting(self):
print(self.hello)
james = Person()
james.greeting() # 안녕하세요.

 

 

self는 인스턴스 자기 자신을 의미한다. 

 

그래서 우리는 이 매개 변수를 이용해서 그 인스턴스에 소속되는 변수를 지정할 수 있게 된다.

인스턴스가 생성될 때 self.hello = '안녕하세요.'처럼 자기 자신에 속성(변수)을 추가했다.

self.hello = '안녕하세요. <- 이것을 인스턴스 속성(변수)라고 하는 것이다.

 

여기서 __init__의 매개변수 self에 들어가는 값은 Person()이라 할 수 있다.

그리고 self가 완성된 뒤 james에 할당된다.

 

 

 

greeting도 마찬가지다.

첫번째 인자로 self를 주면 self가 인스턴스를 가리키는 것이기 때문에 

self.hello를 통해서 인스턴스 변수 hello를 쓸 수 있게 되는 것이다.

(인스턴스 이용하면 이제 다른 메소드에서도 __init__변수를 사용할 수 있다!)

 

이 후 greeting메서드를 호출 하면 현재 인스턴스가 자동으로

매개변수 self에 들어와서 

 

james.greeting() # 안녕하세요. 를 출력할 수 있게 되는 것이다.

 

#여기서 첫번째 인자를 굳이 self로 안해도 된다. 그냥 dfsd이런식으로 마음대로 지정해도 된다.

#하지만 일종의 관례처럼 self를 쓴다.

 

 

 

/////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 

class Cal:
def __init__(self, v1, v2):
print(v1,v2)
self.v1 = v1
self.v2 = v2
def add(self):
return self.v1 + self.v2
c1 = Cal(10,10) #10 10
print(c1.add()) #20

 

전에 지역변수 때문에 사용하지 못했던 v1,v2를 인스턴스 속성(변수)로 선언함으로써 

add메소드에서도 v1,v2 정상적으로 가져와서 사용할 수 있게되었다!

 

 

 

 

 

 

 

 

 

 

 

CSV 파일 읽기 및 쓰기

 

 

 

 

 

# CSV 파일 읽기 및 쓰기

# CSV : MIME - text/csv
CSV -콤마(,)로 구분이 되어 있는 record set이라고 보면 된다. 꼭 꼼마 콤마로 구분할 필요는 없다.
  임의대로 우리가 원하는 예를들면 공백이나 합기호와 같은 것으로 구분할 수 있다. 다만, 콤마가 정석이다.

 

 


##파일 Write 실습(2)

csv 파일 설명
csv.reader
csv.DictReader
csv.writer
csv파일 전체 실습

 

 

test1.csv

Name,Code
Afghanistan,AF
Åland Islands,AX
Albania,AL
Algeria,DZ
American Samoa,AS
Andorra,AD
Angola,AO
Anguilla,AI
Antarctica,AQ
Antigua and Barbuda,AG
Argentina,AR
Armenia,AM
Aruba,AW
.
.
.

 

test2.csv

Name|Code
Afghanistan|AF
Åland Islands|AX
Albania|AL
Algeria|DZ
American Samoa|AS
Andorra|AD
Angola|AO
Anguilla|AI
Antarctica|AQ
Antigua and Barbuda|AG
.
.
.

 

 

 

import csv

 

 

 

# 예제1

with open('./resource/test1.csv', 'r') as f:
reader = csv.reader(f) #파일과 연결된 open함수에서의 변수를 reader에다가 인자로 넘겨주면 csv파일을 사용할 준비가 되었다는 것이다.
#next(reader) # Header Skip #test1의 Name,code를 생략하는것이다.
# 객체 확인
print(reader) #<_csv.reader object at 0x0000019B460F5100>
# 타입 확인
print(type(reader)) #<class '_csv.reader'>
# 속성 확인
print(dir(reader)) # __iter__ 반복문에서도 사용할 수 있다.
for c in reader:
# print(c)
['Name', 'Code']
['Afghanistan', 'AF']
['Åland Islands', 'AX']
.
.
.
# 타입 확인(리스트)
# print(type(c))
# list to str
print(' : '.join(c))#프린트의' : '을 join함수에 더해서 c를 하겠다.
Name : Code
Afghanistan : AF
Åland Islands : AX
Albania : AL
Algeria : DZ
American Samoa : AS
Andorra : AD
.
.
.

 

 

 



# 예제2

with open('./resource/test2.csv', 'r') as f:
reader = csv.reader(f, delimiter='|') # 구분자 선택
# 여기서 delimiter=','를 하면 ['spain|ES']처럼 리스트에 두 개의 원소로 나오지 않고 하나로 나온다.
# 왜냐하면 test2.csv의 구분자가 |이기 때문이다.
# next(reader) Header 스킵
for c in reader:
print(''.join(c))
NameCode
AfghanistanAF
Åland IslandsAX
AlbaniaAL
AlgeriaDZ
American SamoaAS
AndorraAD
.
.
.

 

 

 



# 예제3 (Dict 변환)

with open('./resource/test1.csv', 'r') as f:
reader = csv.DictReader(f)
# 확인
print(reader) #<csv.DictReader object at 0x000001C6F8E07B80>
print(type(reader)) #<class 'csv.DictReader'>
print(dir(reader)) # __iter__ 확인
for c in reader:
#print(c)
{'Name': 'Afghanistan', 'Code': 'AF'}
{'Name': 'Åland Islands', 'Code': 'AX'}
{'Name': 'Albania', 'Code': 'AL'}
{'Name': 'Algeria', 'Code': 'DZ'}
.
.
.
for k, v in c.items():
print(k, v)
print('-----')
Name Afghanistan
Code AF
-----
Name Åland Islands
Code AX
-----
Name Albania
Code AL
-----
Name Algeria
Code DZ
-----
Name American Samoa
Code AS
-----
Name Andorra
Code AD
-----
.
.
.




# 예제4

w = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20, 21]]
with open('./resource/write1.csv', 'w', encoding='utf-8') as f:
print(dir(csv)) #['Dialect', 'DictReader', 'DictWriter', 'Error', 'QUOTE_ALL',...]
wt = csv.writer(f)
# dir 확인 /어떤 메소드들이나 속성이 들어있는지 확인
print(dir(wt)) # ['__class__', '__delattr__', '__dir__', '__doc__'...]
# 타입 확인
print(type(wt)) #<class '_csv.writer'>
for v in w:
wt.writerow(v)
#list를 csv로 만들 때는, 하나의 list가 하나의 record가 된다.
#그래서 7개이기 때문에 7줄이 만들어진다.

 

write.csv

1,2,3
4,5,6
7,8,9
10,11,12
13,14,15
16,17,18
19,20,21

 

 



# 예제5

with open('./resource/write2.csv', 'w', newline='') as f:
# 필드명
fields = ['one', 'two', 'three']
# Dict Writer 선언
wt = csv.DictWriter(f, fieldnames=fields)
# Herder Write
wt.writeheader() #여기까지하면 write2.csv에 헤더 이름이 one,two,three로 내부적으로 작성된 상태이다.

 

write2.csv

one,two,three

 

 

 

 

 

with open('./resource/write2.csv', 'w', newline='') as f:
# 필드명
fields = ['one', 'two', 'three']
# Dict Writer 선언
wt = csv.DictWriter(f, fieldnames=fields)
# Herder Write
wt.writeheader() #여기까지하면 write2.csv에 헤더 이름이 one,two,three로 내부적으로 작성된 상태이다.
for v in w:
wt.writerow({'one': v[0], 'two': v[1], 'three': v[2]})

 

write2.csv

one,two,three
1,2,3
4,5,6
7,8,9
10,11,12
13,14,15
16,17,18
19,20,21

 

 

 

 

 

'Python > Today I learned' 카테고리의 다른 글

TIL#35 객체, 클래스, 인스턴스 관계정리(매우 중요)  (0) 2021.05.20
TIL#34 클래스 self  (0) 2021.05.20
TIL#32 파일 읽기 및 쓰기  (0) 2021.05.19
TIL#31 외장함수  (0) 2021.05.19
TIL#30 내장함수  (0) 2021.05.19

+ Recent posts