690 likes | 1.03k Views
Advanced Topics in Python. SPARCS 05 김준기 2010. 4. 8. Contents. Class Details & Inheritance Unicode vs . String More about Functions Functional Programming Review on Modules Python Packages & Libraries Extra Things. Class. 다들 복습하셨겠죠 ?. Class. 기억이 안 난다구요 ?. 자료형. 그럼 이건 ?. Class.
E N D
Advanced Topics in Python SPARCS 05 김준기 2010. 4. 8
Contents • Class Details & Inheritance • Unicode vs. String • More about Functions • Functional Programming • Review on Modules • Python Packages & Libraries • Extra Things
Class 다들 복습하셨겠죠?
Class 기억이 안 난다구요?
자료형 그럼 이건?
Class class = type defined as data + operations instance = an object whose type is a certain class
Class 그 다음엔? class person(object): def __init__(self, …): … def __str__(self, …): … 강성훈
Class Method를추가해보자 class person(object): def __init__(self, …): … def __str__(self, …): … def dday_to_birthday(self): …
Class from datetime import date class person(object): def __init__(self, …): … def __str__(self, …): … defdday_to_birthday(self): return date(self.year, self.month, self.day) – date.today() >>>date.today() datetime.date(2010, 4, 8) >>>joongi.dday_to_birthday() datetime.timedelta(-8367)
Class Details • 미리 정의된 이름들__init__, __str__, …? • date 자료형을 뺄셈하면 뭐가 나오나? class date(object): def__sub__(self, other): returntimedelta(self.toordinal() – \other.toordinal() )
Class Details • 미리 정의된 이름의 목록과 명세는 여기:http://docs.python.org/reference/datamodel.html#special-method-names • 참고: 앞으로 배울 Django에서도 이거 많이 써서 만들었습니다.용자는 소스코드를 뜯어보세요~ㅋㅋ • 영어 레퍼런스 읽기를 두려워하지 마세요!
Class Details C++/Java를 보면 이런 것도 있던데…요? public static void main(String args[]) {…} private intmyFunction(int x) {…} protectedvoidprintToSomething(BufferedWriter writer) {…}
Class Details • 결론: Python엔 그런 거 없뜸 (모두 public) • 하지만…‘_’로 시작하는 class, function 제외 • 일반적으로 private은 ‘_’로 시작하는 이름으로 표시하는 것이 관습 from mypackageimport *
Class Details • 잠깐! static도 없나요? • 사실 필요는 없어요. (class = namespace?) • 지금까지 본 건 모두 instance methodstatic method도 있습니다. class person(object): @staticmethod defask_name(man): … >>>person.ask_name(joongi)
Class Details • 비슷한(?) 것으로 class method • cls는 person 자료형 자체 전달 • 상속처리할 때 유용 class person(object): @classmethod defask_name(cls, man): … classnewtype(person): … >>>person.ask_name(joongi) >>>newtype.ask_name(joongi)
Class Inheritance 상속? 그거 하면 세금도 내나요?
Class Inheritance • Extend vs. Inherit • 사실은 같은 개념 (subtype) class person(object): … classnewtype(person): … >>>joongi = person() >>> type(joongi) <class 'person'> >>> android = newtype() >>> type(android) <class 'newtype'>
Class Inheritance • 상속 관계 알아보기 “I’m your base!” >>> type(joongi).__bases__ (<type 'object'>,) >>> type(android).__bases__ (<class 'person'>,)
Class Inheritance • static method vs. class method • class method는 어떤 클래스로부터 호출되나 알 수 있다. classperson(object): @classmethod defdoit(cls, action): print'%s!! by %s' % (action, cls.__name__) classnewtype(person): pass >>>person.doit('shout') shout!! by person >>>newtype.doit('shout') shout!! by newtype
Unicode vs. String • Encoding • 어떤 ‘정보’를 컴퓨터에서 실제로 ‘어떻게’ 표현할 것인가? • String • 이상: ‘문자’의 나열 • 현실: 그냥 메모리에 1byte씩 때려박기 • Unicode • 세계 공통의 ‘문자집합’ 정의
Unicode vs. String • String Encoding • ‘문자’들을 메모리에 ‘어떻게’ 때려박을까? • CP949, UTF-8, ISO-8859-1 (Latin1) • 여러분이 자주 보게 될 encoding 이름 • Unicode Encoding • Unicode에 속한 문자들을 어떻게 표현하나? • UTF-7, UTF-8, UTF-16, UTF-32, …
Unicode vs. String • 자, 그럼 현실을 들여다봅시다. # coding: cp949 print '김준기' print repr('김준기') 김준기 '\xb1\xe8\xc1\xd8\xb1\xe2'
Unicode vs. String • 다른 평행현실은? • 깨진 글자가 보였다면 윈도 명령 프롬프트? # coding: utf8 print '김준기' print repr('김준기') 源以湲 '\xea\xb9\x80\xec\xa4\x80\xea\xb8\xb0'
Unicode vs. String • 특이점 • 어째서 깨지지 않았을까? # coding: utf8 print u'김준기' print repr(u'김준기') 김준기 u'\uae40\uc900\uae30'
Unicode vs. String • 사실은… • 어라, 똑같네? # coding: cp949 print u'김준기' print repr(u'김준기') 김준기 u'\uae40\uc900\uae30'
Unicode vs. String • Python엔 2가지 종류의 문자열 자료형이 있습니다. >>> type('김준기') <type 'str'> >>> type(u'김준기') <type 'unicode'>
Unicode vs. String • unicode가 안 깨졌던 비밀은… • 소스파일 읽을 때 unicode로 자동 변환(u''쓴 것만,“coding” 설정에 따라) • print할 때 str로 자동 변환 classunicode(object): def __str__(self): # print할 때 호출됨 returnself.encode(sys.getfilesystemencoding())
Unicode vs. String • 상호 변환하기 .encode(encoding_name) unicode object str object .decode(encoding_name) >>> u'김준기'.encode('utf8') '\xea\xb9\x80\xec\xa4\x80\xea\xb8\xb0' >>> u'김준기'.encode('cp949') '\xb1\xe8\xc1\xd8\xb1\xe2'
Unicode vs. String • 상호 변환하기 • unicode object 자체로는 입출력 불가! • Python이 암시적으로 자동 변환하든(print),프로그래머가 명시적으로 변환하든 해야만 가능 >>>'\xea\xb9\x80\xec\xa4\x80\xea\xb8\xb0'.decode('utf8') u'\uae40\uc900\uae30' >>>'\xea\xb9\x80\xec\xa4\x80\xea\xb8\xb0'.decode('cp949') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'cp949' codec can't decode bytes in position 2-3: illegal multibyte sequence
Unicode vs. String • 흔히 많이 하는 실수 • unicode와 str섞어쓰기암시적 변환이 편리하지만 버그 발생률 높음 예) Database/System 인코딩 설정이 다른 상황에 암시적 변환이 결합하면… • 조금 귀찮지만, 항상 unicode를 쓰자.(Python 3.0부터는 unicode가 기본!) 'This is my precious name, %s.' % u'김준기'
More about Functions • 선택적 인자(optional argument) • Positional arguments def download(url, exit_on_complete=True): … def sum(*args): result = 0 for item inargs: # args is a tuple. result += item return result >>> sum(1,2,3,5,8) 19
More about Functions • Keyword arguments def animate(**kwargs): # kwargs is a dict. duration = kwargs.get('duration', 100) replay = kwargs.get('replay', False) … >>> animate() (animation with duration 100, no replay) >>> animate(replay=True) (animation with duration 100, replay) >>> animate(replay=True, duration=500) (animation with duration 500, replay)
More about Functions • More complex example defcreate_person(name, *args, **kwargs): man = person(name, sum(*args), 1, 1) for k, v inkwargs.iteritems(): setattr(man, k, v) return man >>>create_person(u'김준기', 1, 2, 3,...shoes_size=275) >>>create_person(u'강성훈', 5, 6,...is_supercoder=True)
Functional Programming • 저번 시간에 lambda 나왔습니다. 사실 이거 함수(function)입니다.다만 문법 상 expression으로 제한했을 뿐. Function = just a callableobject 혹시 앞부분 기억한다면… 이런 것도 있어요~ def__call__(self, *args): …
Functional Programming • lambda 자주 사용하는 곳 • map() : 개별 item에 적용할 함수 • filter() : 조건 만족 판단 함수 • sort() : 대소 비교하는 함수 • Functional Programming의 장점? 임의의 함수를 인자로 전달하거나 다른 곳에 저장하여 유연하게 프로그래밍할 수 있습니다.
Functional Programming • Decorator function을 장식하여 장식된 function을 반환하는 function class person(object): @staticmethod defask_name(man): … class person(object): defask_name(man): … ask_name = staticmethod(ask_name)
Functional Programming • Decorator Example: CS101 WTF def print_return(func): def decorated(*args, **kwargs): ret = func(*args, **kwargs) print ret return ret return decorated class person(object): @print_return def get_name(self): return self.name
Functional Programming • Decorator Example: CS101 WTF • 실제 활용 예 (Django views) >>>joongi = person(u'김준기') >>> dummy = joongi.get_name() # without deco >>> dummy = joongi.get_name() # with deco 김준기 fromdjango.contrib.auth.decoratorsimportlogin_required @login_required defprivileged_page(request): …
Functional Programming • Decorator Example Improved decorated 함수의 footprint를 func의 것으로 바꿔주는 효과로 Django view 목록 볼 때 편리함 from functoolsimport wraps def print_return_improved(func): @wraps(func) def decorated(*args, **kwargs): ret = func(*args, **kwargs) print ret return ret return decorated
Functional Programming • Decorator Example Improved 보면 알겠지만 함수도 object라서 여러 속성과 내부 method들이 있습니다. >>> def myfunc(): pass >>>myfunc1 = print_return(myfunc) >>>myfunc2 = print_return_improved(myfunc) >>>myfunc1.__name__ decorated >>>myfunc2.__name__ myfunc
Functional Programming • Generator: the secret of Python def range(n): thelist = [] foriinxrange(n): thelist.append(i) returnthelist def xrange(n): k = 0 while k < n: yield k k += 1 raiseStopIteration()
Functional Programming • List Generator Syntax >>> [k+1 for k inxrange(10)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> [(k+1,j+1) for k inxrange(3) for j inxrange(3)] [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] >>>importos >>>[name for name inos.listdir('.') \ ...ifnotname.startswith('.')]
Modules 뭔가 추가할까 했는데,강성훈 슬라이드 보니 잘 해놨더라 =3 잠시 쉽시다.
Packages 여러분이 모든 걸 직접 다 짜진 않겠죠? Don’t reinvent the wheel!
Packages • 외부 라이브러리 설치하는 방법 • Debian/Ubuntu등 리눅스배포판에서 제공하는 패키지 설치 (보통 “python-”으로 시작) • 압축파일 받아서 푼 다음 수동설치$ sudo python setup.py install • python-setuptools패키지 설치한 후$ sudoeasy_install something • 수동설치에 C/C++ 컴파일러 필요할 수 있음(python-dev, build-essentials 설치)
Packages • 외부 라이브러리가 설치되는 장소 • Linux (배포판마다 다름)/usr/lib/python2.6/site-packages/usr/lib/python2.6/dist-packages • WindowsC:\{Python설치경로}\Libs\site-packages • 설치 형태 • python 소스코드 그대로 • C/C++ 컴파일된모듈 • .egg 압축 파일
Packages • 설치 장소 알아내는 팁 • 참고 • *.py : source code • *.pyc : pre-compiled bytecode • *.pyo : optimized bytecode >>> import somelib >>>somelib.__file__ /usr/lib/python2.6/dist-packages/somelib/__init__.pyc
Packages • 패키지 업데이트 : 보통 재설치하면 됨 • 패키지 삭제 • 배포판 패키지 : apt/yum 등에서 삭제 • easy_install이용한 경우, 불행히도…site-packages/*.pth 파일 및 그 안에 적힌 관련 파일 모두 찾아 수동 삭제 • 수동 설치한 경우는 당연히 수동 삭제 -_-
Packages 그럼 우리가 만들 순 없을까? 당연히 된다. …다만 setup.py/egg 제작법 같은 건 아직 나도 몰라요;(대충 distutils, setuptools잘 구워삶으면 되는 듯)
Packages • Package의 구조 mylib __init__.py module1.py classes, functions, … module2.py classes, functions, … subdir1 __init__.py module3.py classes, functions, … module4.py classes, functions, … subdir2 __init__.py module5.py classes, functions, …