심볼 테이블 ( Symbol table )

파이썬에서 모든 데이터는 객체의 형태로 저장됩니다.

그리고 변수는 단지 객체의 이름일 뿐인데, 이를 심볼( Symbol )이라 합니다.

심볼은 파이썬에서만 있는 용어가 아닙니다.

Java로 따지면 실제 주소의 레퍼런스( hashcode() )가 심볼입니다.

 

파이썬에서는 이름과 레퍼런스를 저장하는 테이블이 따로 있는데, 이를 심볼 테이블( Symbol Table )이라 합니다.

심볼 테이블이란,

1) 변수의 이름과 데이터의 주소를 저장하는 테이블입니다.

2) 심볼 테이블의 내용을 살펴 보기 위해서는 globals(), locals() 내장 함수를 사용하며, 함수 호출로 반환된 테이블은 스코프( scope )를 나타냅니다.( global table , local table ) 그리고 테이블의 내용은 Dictionary 타입의 객체로 반환합니다.

 

 

심볼 테이블은 위와 같이 객체의 이름( 변수 )과 주소가 함께 저장되어 관계를 갖게 됩니다.

 

또한 객체마다 심볼 테이블이 존재하여 객체에서만 사용할 수 있는 변수를 정의할 수 있습니다.

예를들어 위 그림에서 전역으로 할당된 name, age , foo class 변수가 저장되어 있는 table을 Global Symbol table( 전역 심볼 테이블 )이라 하고,

foo 클래스를 인스턴스화한 객체는 또 다른 Symbol table이 생성되어 객체에서 사용 가능한 변수( i, j )들이 저장됩니다.

 

그리고 위 그림에서 등장하지 않았지만, 블록 단위에서 생성된 객체에 대해서는 Locals Symbol Table이 생성되고, 블록이 끝나면 테이블이 사라집니다.

 Local Symbol Table은 객체가 존재하는 동안 일시적으로 생성되었다가 사라지는 테이블입니다.

이 내용은 뒤에서 예제로 자세히 살펴보겠습니다.

 

 

심볼 테이블이 존재한다는 것은, 객체의 확장이 가능하다는 의미입니다.

당연하게도 내장 객체가 아닌, 개발자가 생성한 객체는 동적으로 변수를 추가할 수 있습니다.

반면, 내장 함수는 심볼 테이블이 존재하지 않으며, 내장 클래스의 객체( str, tuple, dict 등 )는 심볼 테이블이 존재하지만 확장이 불가능합니다.

print(print.__dict__) # AttributeError: 'builtin_function_or_method' object has no attribute '__dict__'
str.a = 'foo' # TypeError: can't set attributes of built-in/extension type 'str'

__dict__ 는 네임 스페이스를 확인하는 속성입니다.

내장 함수 print의 네임 스페이스를 확인하려 하니, __dict__라는 속성이 없다고 하며,

내장 객체 str에 a속성을 추가하려고 하니, 속성을 추가할 수 없다고 합니다.

 

심볼 테이블의 개념은 약간의 무리는 있지만, 자바스크립트의 prototype과 느낌이 비슷합니다.

차이점이라면 JS에서는 prototype을 이용해서 내장 객체를 확장할 수 있지만,

파이썬은 파이썬이 제공해주는 객체의 확장을 막아 놓았습니다.

 

 

참고로 Symbol Table과 name space( 네임 스페이스 )는 다릅니다. ( 스택 오버 플로우 - 링크 )

class foo:
goo = "hello"
print(goo) # symbol table로 접근

print(foo.goo) # name space로 접근

예를들어 foo 클래스의 goo 변수를 접근하기 위해서,

foo 클래스 내부에서는 " goo "로 직접 접근이 가능하지만,

foo 클래스 외부에서는 " foo.goo "와 같이 네임 스페이스를 거쳐야 합니다.

제가 지금까지 말한 것은 네임 스페이스가 아닌, 심볼 테이블과 관련된 얘기임을 참고해주세요.

 

 

 

 

이제 예제를 통해 심볼 테이블을 확인해보도록 하겠습니다.

 

심볼 테이블 예제

global_a = 1
global_b = 'global'

def foo():
local_a = 2
local_b = 'local'
print(locals())

class MyClass:
x = 10
y = 20


# 1. global symbol table 확인
print(globals()) # 'global_a': 1, 'global_b': 'global', 'foo': <function foo at 0x00000228D8A05268>, 'MyClass': <class '__main__.MyClass'>}

# 2. local symbol table 확인
foo() # {'local_b': 'local', 'local_a': 2}

# 3. 정의된 함수 객체 확인
# symbol table이 있다는 것은 확장이 가능함을 의미한다.
# 그리고 __dict__를 통해 접근이 가능하다.
foo.c = 'hello'
print(foo.__dict__) # {'c': 'hello'}

# 4. MyClass 객체
print(MyClass.__dict__) # {'x': 10, 'y': 20, '__dict__': <attribute '__dict__' of 'MyClass' objects>,}

 

Symbole Table 예제를 도식화 하면 위와 같을 것입니다.

함수도 객체이며, 객체마다 name space가 존재하다는 것을 확인할 수 있습니다.

 

 

 

 

id()함수 - 객체의 아이디 확인

is         - 레퍼런스 비교 연산자

id() 함수는 객체의 아이디를 반환하는 함수이고, is는 두 객체의 레퍼런스를 비교하는 비교 연산자입니다.

 

i1 = 10
i2 = 10
print(hex(id(i1)), hex(id(i2))) # 0x6c39e3a0 0x6c39e3a0
print(i1 is i2) # True

s1 = 'hello'
s2 = 'hello'
print(s1 is s2) # True

l1 = [1, 2, 3]
l2 = [1, 2, 3]
print(l1 is l2) # False

t1 = (1, 2, 3)
t2 = (1, 2, 3)
print(t1 is t2) # False

모든 객체는 자신이 생성될 때 id가 생성됩니다.

그런데 정수와 문자열 값이 같으면, 같은 객체를 참조하는 것을 확인할 수 있습니다.

List와 Tuple의 경우에는 값이 같아도 다른 객체를 참조하네요.

 

그러면 같은 값을 갖는 두 객체가 어떤 때는 같은 객체를 참조하고, 어떤 때는 다른 객체를 참조하는 것일까요?

 

20글자 이하의 문자열, 또는 리터럴로 표현된 정수는 같은 객체를 가르킵니다.

그런데 257 이상의 정수가 연산으로 얻어진 결과라면 다른 객체를 가르킵니다. ( 스택 오버 플로우 - 링크 )

명확한 것은 모든 객체는 자신이 생성될 때 id가 생성된다는 것입니다.

i1 = 256
i2 = 255 + 1
print(i1 is i2) # True

i1 = 257
i2 = 256 + 1
print(i1 is i2) # False

i1 = 257
i2 = 257
print(i1 is i2) # Ture

s1 = "a"*20
s2 = "a"*20
print(s1 is s2) # True

s1 = "a"*30
s2 = "a"*30
print(s1 is s2) # False

 

 

이상으로 심볼 테이블과 객체에 대해 알아보았습니다.

이번 글은 개념적이 이야기가 많았네요.

 

심볼 테이블은 변수의 이름과 주소가 관계를 맺고 있는 테이블이며, Global Symbol Table , Local Symbol Table이 있습니다.

그리고 객체가 생성되면 고유의 id 값이 생성된다는 점과, 문자열과 정수의 경우 같은 값을 갖더라도 특정 조건에 따라 같은 객체를 가르킬 수 있습니다.

 

출처 : https://victorydntmd.tistory.com/241?category=704014

클래스의 메서드를 호출하는 방식은 2가지가 있습니다.

1) 클래스 name space로 접근하는 방법

2) 객체 name space로 접근하는 방법

class MyClass:
def foo(self, x):
print(x)

m = MyClass()
MyClass.foo(m, 10) # 클래스 name sapce

m.foo(10) # 객체 name space

다음 글에서 살펴보겠지만, 모든 객체는 name space가 존재합니다.

그리고 모든 객체가 공통으로 사용할 수 있는 class name space가 존재합니다.

MyClass.foo() 처럼 호출하는 방식은 class name space에 접근해서 foo라는 메서드를 호출한 것이고,

m.foo() 처럼 호출하는 방식은 Instance name space에 접근해서 foo 메서드를 호출한 것입니다.

두 방식에는 차이점이 있으며, 각 방식을 unbound와 bound 방식으로 호출했다고 합니다.

1. bound와 unbound 방식

메서드 호출에는 bound와 unbound 방식이 있습니다.

두 방식은 객체를 참조한다는 점에서 같지만,메서드를 정의할 때 작성한 self가 객체와 자동으로 binding 되어 있느냐의 차이입니다.

따라서 메서드를 호출할 때 인자로 객체를 넣어줘야 하면 unbound 방식이고, 그렇지 않으면 bound 방식입니다.여기서self는 객체 자기 자신을 의미하는 키워드이며, 메서드를 정의할 때 첫 번째 파라미터에 위치합니다.

관례적으로 sefl라는 이름을 사용하며, 다른 이름을 작성하는 것도 가능하지만 관례를 따르는 것이 좋습니다. x, y 좌표를 갖는 Point 클래스를 생성하여 bound와 unbound 방식을 확인해보겠습니다.

class Point:
# Point 클래스의 setter , getterdef set_x(self, x):
self.x = x # 인스턴스 멤버

def get_x(self):
return self.x

def set_y(self, y):
self.y = y # 인스턴스 멤버

def get_y(self):
return self.y

# class를 통해 메서드 호출 ( unbound 방식 )def unbound_class_call():
p = Point()
Point.set_x(p, 10)
Point.set_y(p, 20)
print(Point.get_x(p), Point.get_y(p))

def bound_instance_call():
p = Point()
p.set_x(10)
p.set_y(20)
print(p.get_x(), p.get_y())

unbound_class_call()
bound_instance_call()

unbound 방식에서는 첫 번째 인자로 Point 객체를 전달했지만, bound 방식에서는 그러지 않은 것을 확인할 수 있습니다.

2. 클래스 멤버와 인스턴스 멤버

멤버에는 클래스 멤버와 인스턴스 멤버 두 가지가 있습니다.

클래스 멤버는 Class name space에 생성되지만, 인스턴스 멤버는 Insatnce name space에 생성됩니다.

객체를 생성하면 객체 마다 name space가 존재한다고 했죠?

클래스 멤버는 모든 객체에서 공유되며, 인스턴스 멤버는 각각의 객체에서만 참조할 수 있습니다.

class foo:
class_name_space_var = 20 # 클래스 멤버

def set_instance_name_space_var(self, x):
self.instance_name_space_var = x # 인스턴스 멤버
def get_nstance_name_space_var(self):
return self.instance_name_space_var

def test_member():
p = foo()
p.set_instance_name_space_var(10)

# Instance name space에 class_name_space_var가 없으므로
# class name space에서 class_name_space_var 변수를 찾는다.
# ( 자바스크립트의 prototype chaining과 비슷 )print('{0}, {1}'.format(p.instance_name_space_var, p.class_name_space_var))

test_member()

Instance name space에 변수가 존재하지 않으면 class name space로 올라가서 변수를 확인합니다.

3. 인스턴스 메서드, 클래스 메서드,**

정적 메서드**

클래스 메서드는 클래스를 인스턴스화한 객체들이 공통적으로 사용할 수 있는 메서드이고,

인스턴스 메서드는 인스턴스가 사용할 수 있는 메서드입니다.

따라서 같은 클래스를 인스턴스화 해도 사용할 수 있는 메서드는 다를 수 있습니다.

Python에서 인스턴스 메서드와 클래스 메서드의 차이는 인스턴스 멤버에 접근할 수 있는지 없는지에 대한 차이이기 때문에,

따라서메서드를 정의할 때 첫 번째 파라미터에 self를 작성하면 인스턴스 메서드, 그렇지 않으면 클래스 메서드입니다.

그렇다면 정적 메서드는 무엇일까요?

정적 메서드도 클래스 메서드와 같이 인스턴스 멤버에 접근할 수 없는 메서드입니다.

더불어서 클래스 메서드가 접근할 수 있는 클래스 멤버에도 접근 할 수 없는 메서드가 정적 메서드입니다.

정적 메서드와 클래스 메서드는 장식자( 자바의 어노테이션 같은 것 )를 통해 구분하며,

클래스 메서드를 정의할 때 첫 번째 매개변수에로 클래스 멤버에 접근할 수 있는cls를 작성합니다.

( self와 마찬가지로 관례상 cls 라는 이름을 사용합니다. )

class foo:
a = 0 # class member

def instance_method(self):
self.b = 10 # instance member
print("instance method called")

@classmethod
def class_method(cls):
print("class method called")
return cls.a # class member에 접근 가능

@staticmethod
def static_method():
print("static method called")

f = foo()
f.instance_method()
f.class_method()
f.static_method()

4. 생성자와 소멸자

생성자는 객체가 생성될 때 실행되고, 소멸자는 객체가 소멸할 때 실행됩니다.

생성자는 __init__ 속성으로, 소멸자는 __del__ 속성으로 정의하면 됩니다.

class foo:
count_of_instance = 0

def __init__(self):
foo.count_of_instance += 1

def __del__(self):
foo.count_of_instance -= 1

f1 = foo()
f2 = foo()
print(foo.count_of_instance) # 2
del f2

print(foo.count_of_instance) # 1

5. __str__ 속성

__str__ 속성은 자바에서 Obejct 객체의 toString() 메서드와 유사합니다.

class foo:
pass

f = foo()
print(f) # <__main__.goo object at 0x007324D0>

class goo:
def __str__(self):
return "__str__이 오버라이딩 되었습니다."

g = goo()
print(g) # __str__이 오버라이딩 되었습니다.

6. 연산자 오버로딩

연산자 오버로딩은 알게 모르게 사용해왔던 내용입니다.

문자열 자료형에서 문자열을 연결하는 + 연산자를 기억하시나요?

문자열 연결이 가능한 이유는 str 클래스에 __add__ 메서드가 정의되어 있기 때문에 문자열 연결이 가능한 것입니다.

문자열과 정수는 +연산자를 사용하지 못했는데, 그 이유는 __add__에 문자열과 정수를 연결할 수 있도록 정의를 하지 않았기 때문입니다.

Python에서는 이와 같이 연산자 오버로딩을 사용하고 있는데, 사용자 입장에서도 얼마든지 연산자 오버로딩을 할 수 있습니다.

class MyOperator:
def __mul__(self, i):
self.a = 5
return self.a + i

s = MyOperator()
print(s * 10) # 15

다음은 곱셈 연산자인 *를 사용하면 덧셈이 되도록 오버로딩한 것입니다. 곱셈 연산자를 오버로딩 하기 위해서는 __mul__ 함수를 재정의 하면 됩니다. 연산자를 오버로딩 하기 위해서는 그 연산자에 대응하는 함수를 재정의 하면 됩니다.

그러나,연산자 오버로딩을 지나치게 많이 사용하면 혼란을 줄 수 있으니 사용에 신중해야 합니다.

여기서는 수치 연산자에 대한 오버로딩을 알아볼 것이며, 그 밖에 확장 산술 연산자, 비교 연산자 등의 오버로딩은 공식 문서를 참고하시길 바랍니다. (링크)

 수치 연산자

 __add__

 +

 __sub__

 -

 __mul__

 __floordiv__

// 

 __mod__

 __divmod__

divmod() 

 __pow__

pow() , ** 

 __lshift__

<< 

 __rshift__

>> 

 __and__

 __xor__

 __or__

이상으로 Python의 클래스에 대해 알아보았습니다.

Python에서 모든 객체는 name space를 갖는다는 점과 클래스 메서드, 인스턴스 메서드, 정적 메서드의 차이점과 선언방법이 중요합니다.

출처 : https://victorydntmd.tistory.com/240?category=704014

http://daeson.tistory.com/308


이전 포스팅을 따라서 Anaconda와 tensorflow-gpu를 설치했다면,

로컬 가상환경에서 특정 환경을 생성하고 Pycharm에서 개발환경을 변경해가면서 개발 및 테스트를 해볼 수 있습니다.

이에 대한 문의도 주시고 계시고, 관련 포스팅이 없는거 같아서 올려보겠습니다.

이미지들은 클릭하면 확대됩니다.


처음 설치시


처음 설치하시는 분들은 아래 링크의 포스팅을 먼저 봐주세요

Window 에서 tensorflow-gpu 설치하기



Anaconda prompt를 실행


먼저 기본적인 설치가 되었다면 Anaconda prompt를 실행합니다.




Anaconda 가상환경 목록 확인


실행하면 아래와 같이 콘솔 창이 열립니다.

현재 생성이 되어 있는 아나콘다 가상환경이 있는지 목록을 확인해 보기 위해서 아래 명령어를 실행합니다.


> conda env list


그러면 저는 아래와 같이 총 3개의 환경이 있다고 나타납니다.

root 는 아나콘다를 설치하면 기본적으로 생성이 되는 기본환경이니 여러분도 똑같이 보여지는 항목일 겁니다.

그외에 tf_cpu와 tf_gpu라는 이름의 가상환경이 2개가 생성이 되어 있고 옆에 설치된 경로가 보여지는데요.

이것은 제가 이미 생성을 해놓은 가상환경의 이름이 되겠습니다.


gpu와 cpu를 둘다 사용하는 이유는 gpu의 메모리 한계때문에 데이터가 큰 경우에는 어쩔수 없이 cpu로 실행을 해야 하기 때문에 때에 따라서 두가지를 병행해서 사용하게 됩니다.



여러분은 가상환경이 생성이 되어 있지 않으시다면 root 만 보여질 것입니다.

간단하게 가상환경을 만드는 방법과 생성된 환경에 접속하는 방법, 그리고 tensorflow를 설치하는 방법을 알아보겠습니다.


1. 가상환경 생성하기


> conda create -n tf_gpu python=3.6 anaconda


-n 뒤에는 가상환경의 이름을 넣어주시면 되고, python 버젼을 원하시는 버젼으로 지정할 수도 있습니다.

이렇게 간단히 가상환경을 생성하였습니다. 이 가상환경 내부에서 벌어지는 일들은 외부의 환경에 전혀 영향을 미치지 않고 독립적인 환경이 되기에 테스트하기 아주 좋습니다.


2. 가상환경에 접속하기


> activate tf_gpu


생성한 가상환경의 이름으로 접속을 하면 아래와 같이 프롬프트의 이름이 변경이 됩니다.

접속이 잘 된 것이지요.



3. 텐서플로우 설치하기


> pip install  tensorflow-gpu


가상환경은 초기화가 되어 있기 때문에 다시 텐서플로우를 설치해줍니다.

gpu 버젼으로 설치하는 명령어는 위와 같은데, 만약 cpu 버젼으로 설치하고자 하신다면 그냥 

pip install tensorflow 하시면 됩니다.


4. 기타 명령어


> deactivate                     #가상환경 접속종료하기

> conda remove -n tf_gpu --all    #가상환경 삭제/제거하기



여기까지 하시면 가상환경을 생성하고 텐서플로우도 설치가 된 상태입니다.

이제 Pycharm에서 프로젝트를 하나 생성하고 원하는 가상환경을 사용하고 변경하는 것을 알아보겠습니다.



Pycharm 프로젝트 생성하기


Pycharm을 실행하고 새로운 프로젝틀 생성합니다. (매뉴 - File - New Project)



Interpreter 를 보시면 파이썬 코어를 지정해줄 수 있는데 이때 원하는 로컬 가상환경의 경로에 있는 python.exe를 지정해 주시면 됩니다. 혹은 원격지에 있는 경로도 가능합니다.

저는 파이썬 2, 3버젼 별로 cpu, gpu 별로 가상환경을 만들어 놓고 등록을 해놓아서 위와 같이 몇개의 리스트가 보여집니다.

Anaconda의 기본 경로는 C 드라이브의 Users 폴더 아래 자신의 계정 폴더 아래에 위치하며,

생성된 가상환경은 Anaconda 폴더 아래에 envs에 생성이 되므로 생성하신 가상환경의 폴더를 찾아가서 python.exe 파일을 지정해주시면 되겠습니다.


설정이 되었으면 Create 버튼을 눌러 새로운 프로젝트를 생성합니다.

프로젝트 폴더 아래에 보시면 Libraries 에 방금전에 지정해준 Interpreter 가 보입니다.



자 이제,

파일 생성하고 소스를 붙여놓고 실행하면 가상환경에서 텐서플로우를 사용할 수 있게 되었습니다.



Pycharm 프로젝트의 가상환경 변경하기


여기서 한가지더!

cpu와 gpu를 번갈아가면서 가상환경을 변경하면서 실행을 하고 싶을때가 생깁니다.

새로운 프로젝트를 만들어서 해도 되겠지만, 같은 소스를 복사해주는게 번거로우니 그냥 현재의 프로젝트에서 환경을 변경해서 사용하면 좋을 것 같습니다.


그래서 현재 프로젝트의 설정 매뉴로 이동합니다. (File - settings)

아래의 창에서 Interpreter를 다른 가상환경의 것으로 변경을 하고 적용을 해줍니다.

설치가 된 라이브러리들도 여기서 확인을 할 수 있습니다.



그러면 간단하게 환경이 변경이 된 것을 확인할 수 있습니다.

이제 다양한 환경에서 자유롭게 실행하시면 되겠습니다.^^




출처: http://daeson.tistory.com/308 [대소니]

47.11 가상환경 사용하기

파이썬을 사용하다 보면 pip로 패키지를 설치하게 되는데 이 패키지들은 파이썬 설치 폴더(디렉터리)의Lib/site-packages 안에 저장됩니다. 그래서 pip로 설치한 패키지는 모든 파이썬 스크립트에서 사용할 수 있게 됩니다. 평소에는 이런 방식이 큰 문제가 없지만 프로젝트를 여러 개 개발할 때는 패키지의 버전 문제가 발생합니다.

예를 들어 프로젝트 A에서는 패키지X 1.5를 사용해야 하고, 프로젝트 B에서는 패키지X 2.0을 사용해야 하는 경우가 생깁니다. 이 패키지X 1.5와 2.0은 호환이 되지 않는다면 개발하기가 상당히 불편해집니다.

▼ 
그림 47-5
 글로벌 파이썬 환경에서 패키지가 호환되지 않는 경우

 

 

 

 

이런 문제를 해결하기 위해 파이썬에서는 가상 환경(virtual environment)을 제공하는데, 가상 환경은 독립된 공간을 만들어주는 기능입니다. 가상 환경에서 pip로 패키지를 설치하면 가상 환경 폴더(디렉터리)의 Lib/site-packages 안에 패키지를 저장해줍니다. 즉, 프로젝트 A와 B 각각 가상 환경을 만들어서 프로젝트 A에는 패키지X 1.5를 설치하고, 프로젝트 B에는 패키지X 2.0을 설치할 수 있습니다. 이렇게 하면 파이썬 스크립트를 실행할 때도 현재 가상 환경에 설치된 패키지를 사용하므로 버전 문제가 발생하지 않습니다.

▼ 
그림 47-6
 파이썬 가상 환경으로 독립된 공간을 구성

특히 가상 환경에는 파이썬 실행 파일(인터프리터) 자체도 포함되므로 각 가상 환경 별로 다른 버전의 파이썬 인터프리터가 들어갈 수 있습니다. 따라서 스크립트를 실행할 때는 원래 설치된 파이썬 인터프리터가 아닌 가상 환경 안의 파이썬 인터프리터를 사용합니다.

47.11.1                Windows에서 가상 환경 만들기

그럼 먼저 Windows에서 가상 환경을 만드는 방법을 알아보겠습니다. 가상 환경은 venv 모듈에 가상 환경 이름을 지정해서 만듭니다.

venv는 파이썬 3.3이상부터 사용 가능

  • python -m venv 가상환경이름

여기서는 C:\project 폴더 아래에 가상 환경을 만들겠습니다. 다음과 같이 명령 프롬프트에서 example 가상 환경을 만들고 example 폴더 안으로 이동합니다. 그다음에 Scripts 폴더 안의 activate.bat 파일을 실행하면 가상 환경이 활성화됩니다.

Windows 명령 프롬프트

C:\project>python -m venv example
C:\project>cd example
C:\project\example>Scripts\activate.bat
(example) C:\project\example>

Windows PowerShell에서는 Activate.ps1 파일을 실행합니다(ps1 스크립트를 실행할 수 없을 때는 Windows PowerShell을 관리자로 실행한 뒤 Set-ExecutionPolicy RemoteSigned를 입력하고 Y를 입력).

Windows PowerShell

PS C:\project> python -m venv example
PS C:\project> cd example
PS C:\project\example> .\Scripts\Activate.ps1
(example) PS C:\project\example>

프롬프트 앞을 보면 (example)과 같이 가상 환경의 이름이 표시됩니다.

이 상태에서 pip로 패키지를 설치하면 C:\project\example\Lib\site-packages 안에 패키지가 저장됩니다(dir로 파일과 폴더 확인해보기, /B는 최소 포맷 옵션).

(example) C:\project\example>pip install numpy
(example) C:\project\example>dir /B Lib\site-packages
easy_install.py
numpy
numpy-1.12.1.dist-info
pip
pip-9.0.1.dist-info
pkg_resources
setuptools
setuptools-28.8.0.dist-info
__pycache__

이 상태에서 스크립트 파일을 실행하면 현재 가상 환경 안에 있는 파이썬 인터프리터와 패키지를 사용하게 됩니다.

47.11.2                패키지 목록 관리하기

특히 가상 환경에 설치된 패키지는 목록을 저장해 두었다가 나중에 다시 설치할 수 있습니다. 다음과 같이 pip freeze로 패키지 목록과 버전 정보를 requirements.txt 파일에 저장합니다(git 등으로 버전 관리를 할 때 저장소에 설치된 패키지를 모두 추가하지 않고, requirements.txt 파일만 관리하면 됩니다). requirements.txt은 현재 디렉토리에 저장되므로 루트로 옮긴후 명령을 실행합니다.

(example) C:\project\example>pip freeze > requirements.txt

requirements.txt 파일의 내용대로 패키지를 설치하려면 pip install에서 -r 또는 --requirement 옵션을 사용합니다.

(example) C:\project\example>pip install -r requirements.txt

requirement.txt 파일의 내용대로 패키지를 삭제하려면 pip uninstall에서 -r 또는 --requirement 옵션을 사용합니다.

(example) C:\project\example>pip uninstall -r requirements.txt
 

47.11.3             가상환경 사용하기

 

가상환경이 설치된 디렉토리의 Scripts로 이동하여 activate.bat을 실행하면 된다.

(example) C:\project\example\Script>activate.bat
 

47.11.4                가상 환경별로 파이썬 버전 구분하기

만약 가상 환경별로 파이썬 인터프리터 버전을 다르게 만들고 싶다면 해당 버전의 파이썬 인터프리터로 venv모듈을 실행하면 됩니다. 다음은 파이썬 3.4를 사용하는 가상 환경을 만듭니다(파이썬 3.4를 설치했다고 가정).

C:\project>C:\Python34\python.exe -m venv example3

이렇게 하면 venv 모듈을 실행한 파이썬 실행 파일(인터프리터)이 가상 환경 안에 들어갑니다.

47.11.5                리눅스와 macOS에서 가상 환경 만들기

이번에는 리눅스와 macOS에서 가상 환경을 만드는 방법입니다. 다음과 같이 python3으로 venv 모듈을 실행여 가상 환경을 만들고, source로 bin 디렉터리 안의 activate 파일을 적용하여 가상 환경을 활성화합니다.

리눅스, macOS

~$ python3 -m venv example
~$ cd example
~/example$ source bin/activate
(example) ~/example$

리눅스와 macOS에서도 pip 사용 방법은 앞에서 설명한 것과 같습니다.

47.11.6                가상 환경 폴더를 다른 곳으로 이동시켰다면?

가상 환경을 사용할 때 주의할 점이 있는데, 가상 환경을 만들고 나서 폴더(디렉터리)를 다른 곳으로 이동시키면 활성화가 안 됩니다. 왜냐하면 가상 환경을 활성화하는 activate.batActivate.ps1activate 파일 안에 현재 가상 환경 폴더의 경로가 내장되어 있기 때문입니다. 만약 가상 환경 폴더를 다른 곳으로 이동시켰다면 activate.batActivate.ps1activate 파일 안의 VIRTUAL_ENV 부분을 이동시킨 폴더 경로로 수정해줍니다.

47.11.7                아나콘다 가상 환경 만들기

아나콘다에서 venv를 사용해도 되지만 아나콘다는 전용 가상 환경을 제공하므로 이 환경을 사용하는 것을 권장합니다.

아나콘다에서는 conda를 사용하여 가상 환경을 만듭니다. conda는 아나콘다 설치 폴더의 Scripts 안에 들어있습니다.

  • conda create --name 가상환경이름
C:\project>C:\Users\dojang\Anaconda3\Scripts\conda.exe create --name example

만약 가상 환경에 특정 파이썬 버전을 설치하고 싶다면 python=3.5처럼 버전을 지정해줍니다. 이때는 64비트 파이썬이 설치됩니다.

C:\project>C:\Users\dojang\Anaconda3\Scripts\conda.exe --name example python=3.5

32비트 파이썬을 설치하려면 CONDA_FORCE_32BIT에 1을 지정한 뒤 conda로 가상 환경을 만들면 됩니다(반드시 명령 프롬프트에서 실행).

C:\project>set CONDA_FORCE_32BIT=1
C:\project>C:\Users\dojang\Anaconda3\Scripts\conda.exe --name example python=3.5

conda는 venv와는 달리 가상 환경을 현재 폴더에 생성하지 않고 아나콘다 설치 폴더의 envs 안에 생성합니다.

  • 예) C:\Users\dojang\Anaconda3\envs\example

가상 환경을 활성화할 때는 아나콘다 설치 폴더의 Scripts\activate에 가상 환경 이름을 지정하여 실행해야 합니다(반드시 명령 프롬프트 cmd에서 실행).

  • activate 가상환경이름
C:\project>C:\Users\dojang\Anaconda3\Scripts\activate example
(example) C:\project>

아나콘다 가상 환경에 패키지를 설치할 때는 pip 대신 conda를 사용해야 합니다. 만약 pip를 사용하면 아나콘다 설치 폴더의 Lib/site-packages 안에 패키지가 저장되므로 주의해야 합니다.

  • conda install 패키지
(example) C:\project>conda install numpy

다음은 conda의 주요 명령입니다.

  • conda info: 현재 환경 정보 출력
  • conda search 패키지: 패키지 검색
  • conda install 패키지=버전: 특정 버전의 패키지를 설치(예: conda install numpy=1.11.3)
  • conda install 패키지=버전=파이썬버전: 파이썬 버전을 지정하여 특정 버전의 패키지를 설치(예: conda install numpy=1.11.3=py36_0)
  • conda update 패키지: 패키지 업데이트
  • conda list: 패키지 목록 출력
  • conda remove 패키지: 패키지 삭제
  • conda list --export > package-list.txt: 패키지 목록 및 버전 정보 저장:
  • conda install --file package-list.txt: 패키지 목록으로 설치

47.11.7                가상 환경을 사용하는 IDLE 실행하기

venvconda 가상 환경을 사용하는 IDLE을 실행하려면 가상 환경을 활성화 시킨 뒤 idlelib 모듈을 실행하면 됩니다. 이렇게 하면 IDLE에서도 현재 가상 환경의 패키지를 사용할 수 있습니다.

Windows

(example) C:\project\example>pythonw.exe -m idlelib

macOS, 리눅스

(example) ~/example$ python3 -m idlelib
 
 

 

참고 | 아나콘다 가상 환경 만들기

콘다 명령어 치트시트 : https://docs.conda.io/projects/conda/en/4.6.0/_downloads/52a95608c49671267e40c689e0bc00ca/conda-cheatsheet.pdf

아나콘다는 아나콘다 전용 가상 환경을 제공하며 conda를 사용하여 가상 환경을 만듭니다. conda는 아나콘다 설치 폴더의 Scripts 안에 들어있습니다.

 

  • conda create --name 가상환경이름 python=3.7
  •  
  • conda create --prefix /tmp/test-env python=3.7 : 특정 디렉토리에 가상환경설치하기
C:₩project>C:₩Users₩dojang₩Anaconda3₩Scripts₩conda.exe create --name example

#if you are located in the folder in which you want to create your virtual environment, just omit the path and use

# --prefix는 --name과 동시에 사용할 수 없으므로, activate할때는

# activate [설치한 디렉토리 절대경로]로 기동한다.

# https://stackoverflow.com/questions/37926940/how-to-specify-new-environment-location-for-conda-create/37927252 conda create --prefix=[yourEnvName] python=x.x

conda는 가상 환경을 현재 폴더에 생성하지 않고 아나콘다 설치 폴더의 envs 안에 생성합니다.

  • 예) C:₩Users₩dojang₩Anaconda3₩envs₩example
  • 예) 
    C:\Users\daseul.kim\AppData\Local\conda\conda\envs\ml_scratch  -> C의 programfiles에 접근할 권한이 유저에게 없는 경우에는 이상한 디렉토리에 설치하기도함..

가상 환경을 활성화할 때는 아나콘다 설치 폴더의 Scripts₩activate에 가상 환경 이름을 지정하여 실행해야 합니다.

 

  • activate 가상환경이름
C:₩project>C:₩Users₩dojang₩Anaconda3₩Scripts₩activate example
(example) C:₩project>

아나콘다 가상 환경에 패키지를 설치할 때는 pip 대신 conda를 사용해야 합니다. 만약 pip를 사용하면 아나콘다 설치 폴더의 Lib/site-packages 안에 패키지가 저장되므로 주의해야 합니다.

 

  • conda install 패키지
(example) C:₩project>conda install numpy

다음은 conda의 주요 명령입니다.

 

  • 현재 설치된 가상 환경 정보 출력: conda info --envs
  • 가상환경 활성화 : source activate [가상환경 이름]->리눅스 /  activate [
    가상환경 이름] -> 윈도우
  • 가상환경 비활성화 : source deactivate [가상환경 이름]->리눅스 /  deactivate [가상환경 이름] -> 윈도우
  • 패키지 검색: conda search 패키지
  • 특정 버전의 패키지를 설치:
    • conda install 패키지=버전 (예: conda install numpy=1.11.3)
    • conda install 패키지=버전=파이썬버전 (예: conda install numpy=1.11.3=py36_0)
  • 패키지 업데이트: conda update 패키지
  • 패키지 목록 출력: conda list
  • 패키지 삭제: conda remove 패키지
  • 패키지 목록 및 버전 정보 저장: conda list --export > package-list.txt
  • 패키지 목록으로 설치: conda install --file package-list.txt
  • 주피터 기동: python -m notebook

 

+ Recent posts