17 Nov 2016
|
python
venv
pyenv
- pyenv
- 로컬에 다양한 파이썬 버전을 설치하고 사용할 수 있도록 한다. pyenv를 사용함으로써 파이썬 버전에 대한 의존성을 해결할 수 있다.
- virtualenv
- 로컬에 다양한 파이썬 환경을 구축하고 사용할 수 있도록 한다.
- autoenv
- 특정 프로젝트 폴더로 들어가면 자동으로 개발 환경을 설정해주는 스크립트
pyenv 깔기
brew install pyenv
brew upgrade pyenv --HEAD
brew install openssl readline xz
pyenv에 지원하는 python list 살펴보기
새로운 python 깔기
만약 zlib 관련 에러가 난다면 xcode-select --install
로 개발자 툴을 업데이트하자
pyenv-virtualenv 깔기
brew install pyenv-virtualenv
이후 bash_profile에 다음 줄을 추가한다.
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
pyenv-virtualenv 사용하기
pyenv virtualenv 3.5.1 pyView-3.5.1
하면 3.5.1버전으로 pyView-3.5.1 가상환경을 만든다.
이제 pyenv shell pyView-3.5.1
로 가상환경을 사용가능하다.
autoenv를 자동으로 실행
brew install autoenv
bash_profile에 다음을 추가하면 폴더의 .env가 존재할 경우 실행시켜준다.
source /usr/local/opt/autoenv/activate.sh
make .env
#~/Git/math-logic-server/.env
pyenv shell mathServer-3.5.1
요렇게 만들면 폴더에 들어가면서 자동으로 python을 바꿔준다.
물론 이는 내 클라이언트에만 해당하니 git에 올리지 않는 것이 좋다.
13 Nov 2016
|
python
class
원문
Class
python에서는 class 또한 object이다. 아래는 다른 언어와 비슷한 용도로 class를 쓰는 방법이다.
class ObjectCreator(object):
pass
my_object = ObjectCreator()
print(my_object)
# <__main__.ObjectCreator object at 0x8974f2c>
위처럼 class
는 object를 생성할 수 있는 녀석이지만 말했듯이 object
이기 때문에 다음과 같은 것이 가능하다
- variable을 assign 가능
- copy가 가능
- attribute를 추가할 수 있음
- function의 parameter로 넘길 수 있음
### class또한 object이기 때문에 print 가능! ###
print(ObjectCreator)
#<class '__main__.ObjectCreator'>
def echo(o):
print(o)
### 함수의 파라미터로 넘길 수도 있다. ###
echo(ObjectCreator)
# <class '__main__.ObjectCreator'>
### 새로운 attribute를 추가할 수 있다. ###
print(hasattr(ObjectCreator, 'new_attribute'))
# False
ObjectCreator.new_attribute = 'foo'
print(hasattr(ObjectCreator, 'new_attribute'))
# True
print(ObjectCreator.new_attribute)
# foo
### class를 variable에 assign 가능하다. ###
ObjectCreatorMirror = ObjectCreator
print(ObjectCreatorMirror.new_attribute)
# foo
print(ObjectCreatorMirror())
# <__main__.ObjectCreator object at 0x8997b4c>
Creating classes dynamically
class가 object이기 때문에 다이나믹하게 class를 만들 수 있다.
다음은 예제코드이다
def choose_class(name):
if name == 'foo':
class Foo(object):
pass
return Foo # instance가 아닌 class를 return
else:
class Bar(object):
pass
return Bar
MyClass = choose_class('foo')
print(MyClass) # 함수가 instance가 아닌 class를 리턴한다.
#<class '__main__.Foo'>
print(MyClass()) # return받은 class로 instance를 만들 수 있다.
#<__main__.Foo object at 0x89c6d4c>
예제를 보면 유기적으로 class를 만들지만 좀 복잡해보인다. class 선언문
을 그대로 집어넣었는데 이를 바꿔볼 순 없나??
그래서 python에서는 type
함수를 지원한다.이 함수는 용법이 다음과 같다.
type(만들 class의 이름, --(1)
부모 class들의 tuple, --(2)
attribute를 위한 dictionary) --(3)
(1) : 정확히 얘기하자면 만들 class.__name__에 들어갈 속성을 의미한다. 보통 class 이름과 같이 쓰고 헷갈리지 않기 위해 이를 지켜주자.
(2) : parent class들의 tuple인데 빈 tuple이 될 수도 있다.
(3) : attribute가 들어간다.
사실 python에 type 함수는 어떤 object의 type을 알아보기 위해서도 쓰는데 역할이 다른 하나의 함수는 python에서 보기 힘들다. 이는 예전 호환성을 지키기 위함이고 다른 function이라 생각하자.
type
함수를 이용하여 class를 만들어보자!
class Foo(object):
bar = True
class FooChild(Foo):
pass
#위와 같은 것은
Foo = type('Foo', (), {'bar':True})
FooChild = type('FooChild', (Foo,), {})
print(FooChild.bar)
# True
생성 시 attribute 넣기
위의 class에 attribute를 넣을 수 있다.
def echo_bar(self):
print(self.bar)
FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
hasattr(Foo, 'echo_bar')
# False
hasattr(FooChild, 'echo_bar')
# True
my_foo = FooChild()
my_foo.echo_bar()
# True
이미 존재하는 class에 attribute를 추가하기
def echo_bar_more(self):
print('yet another method')
FooChild.echo_bar_more = echo_bar_more
hasattr(FooChild, 'echo_bar_more')
# True
13 Nov 2016
|
python
class
meta class
#Meta class
class를 만드는 어떠한 것. class : instance = metaclass : class로 볼 수 있다.
MyClass = MetaClass()
MyObject = MyClass()
우리는 python Class Master
에서 type
함수가 class
를 만드는 것을 보았다.
MyClass = type('MyClass', (), {})
type
함수는 사실 metaclass이며, python에서는 class를 만들기 위해, 속에서는 type
을 이용하여 class를 만든다.
파이썬의 모든 것은 object이며, 모두 class로부터 나온다.
age = 35
age.__class__
#<type 'int'>
name = 'bob'
name.__class__
#<type 'str'>
def foo(): pass
foo.__class__
#<type 'function'>
class Bar(object): pass
b = Bar()
b.__class__
#<class '__main__.Bar'>
또한 이 모든 object의 metaclass는 default로 type
이다.
>>> age.__class__.__class__
<type 'type'>
>>> name.__class__.__class__
<type 'type'>
>>> foo.__class__.__class__
<type 'type'>
>>> b.__class__.__class__
<type 'type'>
class를 만들 때 __metaclass__
attribute를 넣으면 해당 class를 만들기 위해 이 attribute를 쓴다.
class Foo(object):
__metaclass__ = something...
[...]
__metaclass__
를 찾는 순서는 다음과 같다.
class
에 __metaclass__
가 존재한다면 가져다 쓴다.
- 존재하지 않는다면 자기 모듈에서 찾는다.(아무것도 상속받지 않는 경우)
- 부모 class중 첫번째 녀석의
__metaclass__
를 가져다쓴다.(상속을 받는 경우)
모든 attribute가 Upper case인 class를 만들 때…
def upper_attr(future_class_name, future_class_parents, future_class_attr):
uppercase_attr = {}
for name, val in future_class_attr.items():
if not name.startswith('__'):
uppercase_attr[name.upper()] = val
else:
uppercase_attr[name] = val
return type(future_class_name, future_class_parents, uppercase_attr)
__metaclass__ = upper_attr # 이 녀석이 있어서 해당 파일의 모든 class가 이 녀석을 씀
class Foo():
bar = 'bip'
print(hasattr(Foo, 'bar'))
# Out: False
print(hasattr(Foo, 'BAR'))
# Out: True
f = Foo()
print(f.BAR)
# Out: 'bip'
다음은 type을 상속받아 만드는 예제이다.
class UpperAttrMetaclass(type):
# __new__: __init__전에 불리는 함수. object를 만들고 return한다.
def __new__(cls, clsname, bases, dct):
uppercase_attr = {}
for name, val in dct.items():
if not name.startswith('__'):
uppercase_attr[name.upper()] = val
else:
uppercase_attr[name] = val
return super(UpperAttrMetaclass, cls).__new__(cls, clsname, bases, uppercase_attr)
12 Nov 2016
|
python
args
*args
파라미터를 몇개 받을 지 모르는 경우 사용한다. 튜플 형태로 전달된다.
def print_param(*args):
print args
for p in args:
print p
print_param('a', 'b', 'c', 'd')
#('a', 'b', 'c', 'd')
#a
#b
#c
#d
**kwargs
파라미터 명을 같이 보낼 수 있다. 딕셔너리형태로 전달된다.
def print_param2(**kwargs):
print kwargs
print kwargs.keys()
print kwargs.values()
for name, value in kwargs.items():
print "%s : %s" % (name, value)
print_param2(first = 'a', second = 'b', third = 'c', fourth = 'd')
#{'second': 'b', 'fourth': 'd', 'third': 'c', 'first': 'a'}
#['second', 'fourth', 'third', 'first']
#['b', 'd', 'c', 'a']
#second : b
#fourth : d
#third : c
#first : a
나머지…
def print_param3(*args, **kwargs):
print args
print kwargs
print_param3('a', 'b')
#('a', 'b')
#{}
print_param3(third = 'c', fourth = 'd')
#()
#{'fourth': 'd', 'third': 'c'}
print_param3('a', 'b', third = 'c', fourth = 'd')
#('a', 'b')
#{'fourth': 'd', 'third': 'c'}
함수의 인자로 List에 *를 붙이면 position arguments로 함수에 집어넣은 것과 똑같은 의미를 갖는다.
Dictionary의 경우 **를 붙이면 keyword arguments로 함수에 집어넣은 것과 같은 의미이다.
def print_param4(a, b, c):
print a, b, c
p = ['a', 'b', 'c']
print_param4(*p)
#a b c
p2 = {'c' : '1', 'a' : '2', 'b' : '3'}
print_param4(**p2)
#2 3 1