Python/2.7 information

파이썬 내부구조 이해하기. 2.x

qkqhxla1 2016. 2. 27. 10:54

문제될시 댓글달아주시면 글 삭제하겠습니다.

파이썬코리아에서 얻은 정보입니다.

http://www.slideshare.net/dahlmoon/20160302-58759476

에서 정보를 얻었으며 'Moon Yong Joon'님이 정리해주신 슬라이드를 바탕으로 얻어가는게 많은것 같아 공부를 위해 따로 정리했습니다.(제 공부를 위함이므로 앞 글에서 정리했거나 아는 내용은 제거했습니다.) 위에 적었듯이 문제될시 글 삭제하겠습니다.



Keyword정보를 확인하기 위해 keyword를 import해서 출력해볼 수 있다.

# -*- encoding: cp949 -*-
import keyword
print keyword
print keyword.kwlist

파이썬 2.x버전은 print가 키워드라 함수처럼 처리가 안되어 함수로 전환해서 사용할 수 있다고 한다.

from __future__ import print_function 를 넣을 경우 파이썬 3버전의 print함수를 사용할 수 있다.


함수,클래스,메소드 등에 대한 정보를 확인하기 위해 help함수를 사용할수 있다.

import한 파일의 위치를 확인하기 위해 __import__함수를 사용할수 있다.

# -*- encoding: cp949 -*-
print __import__('urllib2')

vars()와 locals()함수를 이용해서 현재 관리되는 속성들을 표시할수 있다.

# -*- encoding: cp949 -*-
def add(x,y):
    print 'vars :',vars()
    print 'locals :',locals()

add(5,5)

클래스, 모듈 등의 관리하는 내부 정보를 확인하기 위해 dir함수를 사용할수 있다.

# -*- encoding: cp949 -*-
print dir('urllib2')

issubclass(), isinstance()함수로 객체 간의 관계를 알 수 있다. __bases__ 로 부모 클래스를 확인할수 있고, __class__는 뭔지 몰랐는데 http://stackoverflow.com/questions/9610993/python-type-or-class-or-is 링크의 답변자가 채택한 답변을 보면 대충 뭔지 감을 잡을 수 있다.

# -*- encoding: cp949 -*-
print list.__bases__ 
print issubclass(list,object)
print issubclass(list,type) 

print list.__class__
print isinstance(list,object) 
print isinstance(list,type)

id()는 객체에 대한 주소를 확인하는 함수고, hash()는 객체에 대한 hash값을 integer로 표시한다.

locals()함수와 globals()함수로 지역변수와 전역변수를 체크할수 있다. 전역 영역에서 locals()함수를 이용하면 전역변수가 보인다. 변수 검색 기준은 local > global > built-in 영역 순으로 찾는다고 한다.


compile함수. 사용 예제를 보면 대충 뭔지 알수 있다.

# -*- encoding: cp949 -*-
sl = '10 * 10'
sll = compile(sl,'','eval')
print eval(sll)
print eval('10 * 10')

sc = 'print "Hello World"'
scc = compile(sc,'','exec')
exec(scc)
exec('print "Hello World"')

그런데 글을 쓰면서 compile()함수에 대해 찾아봤는데 아직도 잘 이해가 안간다. compile()함수는

compile(source, filename, mode[, flags[, dont_inherit]]) 라고 정의되있는데 두번째 인자가 뭐하는역할인지 모르겠다. 공백스트링 대신 'asdfasdf'처럼 아무거나 줘도 정상적으로 실행된다. (다른 변화도 찾기가 힘듬.) 거기다 세번째 인자로는 exec, eval, single만 줄수있는데 compile시 세번째인자를 exec로 주고 eval로 실행해도 잘 실행이된다. 이럴거면 왜 굳이 세개나 만들었는지 잘 이해가 되지 않는다.

http://stackoverflow.com/questions/22443939/python-built-in-function-compile-what-is-it-used-for 여기에 어떤 분이 설명을 해놓긴 했는데 더 찾아봐야겠다.


파이썬은 모듈도 구성정보을 제공한다.

# -*- encoding: cp949 -*-
import __future__
print __future__
print '__import__ :',__import__('__future__') #__future__모듈의 경로
print '__future__ :',__future__.__file__ #위와 똑같은 명령인것 같다.
print '__future__ :',__future__.__doc__ #docs의 내용을 보여주는 듯 하다.

함수 내부의 상황을 여러 가지 함수를 써서 확인할수 있다. 30p의 사진.

# -*- encoding: cp949 -*-
def add(x=1,y=2):
    '''ret x+y'''
    print 'vars :',vars()
    print 'locals :',locals()
    return x+y

add(5,5)
print 'func __name__ :',add.__name__ #이름 확인
print 'func name :',add.func_name #위와 동일
print 'func __doc__ :',add.func_doc #함수 처음부분에 '''주석으로 단 글자가 나오는듯 싶다.
print 'func_default :',add.func_defaults #인자 기본값으로 설정해놓은 1,2가 출력된다.

inspect 모듈로 내부구조 보기.

# -*- encoding: cp949 -*-
import inspect
def sum(x,y):
    return x+y
print inspect.getsource(sum) #소스코드 전체를 볼 수 있다.
print inspect.getsourcefile(sum) #해당 함수가 어디에 있는지 알 수 있다.
#그러니까 종종 모듈 내부의 소스를 보고 싶을 때에는 
#ex urllib2의 urlopen의 소스를 보고싶다.
#print inspect.getsource(__import__('urllib2').urlopen) #이렇게 하거나

#import urllib2
#print inspect.getsource(urllib2.urlopen) #이렇게 볼수있다.

클래스 메소드들.

# -*- encoding: cp949 -*-
class myclass:
    @classmethod #class 메소드를 정의하기 위해 적어 줘야 한다.
    def cls_method(cls):
        cls.cls_var = 1
        print 'call cls_method! : ',cls.cls_var
    @staticmethod #static 메소드를 정의하기 위해 적어 줘야 한다.
    def static_method():
        cls_var = 100
        print 'call static_method! : ',cls_var
    def instance_method(self):
        self.ins_var = 1
        print 'call instance_method! : ',self.ins_var

myclass.cls_method()
myclass.static_method()
a = myclass()
a.instance_method()

작성하면서 class method와 static method의 차이점이 뭔지 궁금했는데 여기서 찾을 수 있었다.

http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python


__new__로 클래스에서 초기값을 세팅할수 있다. __new__는 인스턴스 맨 처음에 만들때 한번만 불려지는것 같지만 __init__은 매번 인스턴스 생성시마다 초기화용으로 쓰이는것같다.

좋은 예제 : http://stackoverflow.com/questions/674304/pythons-use-of-new-and-init


__call__은 설명하기가 복잡한것 같다.. 생성자(__init__)와 비슷하지만 클래스이름()등으로 계속 호출할수 있다. 50p의 사진.

그리고 좋은 스택오버플로우 예제 코드.

http://stackoverflow.com/questions/5824881/python-call-special-method-practical-example

에서 가져옴.

# -*- encoding: cp949 -*-
class Factorial:
    def __init__(self):
        self.cache = {}
    def __call__(self, n):
        #print 'c'
        if n not in self.cache:
            if n == 0:
                self.cache[n] = 1
            else:
                self.cache[n] = n * self.__call__(n-1)
        return self.cache[n]

fact = Factorial()
for i in xrange(10):                                                             
    print("{}! = {}".format(i, fact(i)))


'Python > 2.7 information' 카테고리의 다른 글

raw 소켓 파악하기 2.  (0) 2016.03.07
raw 소켓 파악하기 1.  (0) 2016.03.07
python lambda function  (0) 2016.02.08
gotoxy, 콘솔 창 색깔 변화 colorama모듈.  (0) 2015.12.29
지도 모듈 (구글맵, folium 등등.)  (0) 2015.12.24