Your wish is my command

whitekid's blog

Archive for the ‘python’ tag

Python 2.7 Release Note를 보다가..

without comments

http://docs.python.org/dev/whatsnew/2.7.html#pep-372-adding-an-ordered-dictionary-to-collections

순서가 보장되는 딕셔너리.. 그래 이거 필요했다. 특히 json으로 넒길때 아무리 순서가 없다지만. .그래도 순서 있는게 좋지 않겠어?

http://docs.python.org/dev/whatsnew/2.7.html#pep-378-format-specifier-for-thousands-separator

format()이란것을 통해서 해야된다는 것이 불편하긴 하지만… 그래도 locale 모듈을 통해서 한다는 것에 비하면, 천지차이라고나 할까?

http://docs.python.org/dev/whatsnew/2.7.html#pep-3106-dictionary-views

그래 이것도 맞는 것 같다… key를 iteration하면서 그 리스트를 수정하는 경우.. 뭔가 애매한 부분이 있었었지…

아래건… 실수할 가능성이 많아진 문법인듯..

>>> {1,2,3,4,5}
set([1, 2, 3, 4, 5])
>>> set() # empty set
set([])
>>> {}    # empty dict
{}

http://docs.python.org/dev/library/io.html#module-io

cStringIO 보단 그냥 io 써야겠다.. C로 작성되어 2~20배 빨라졌다고 함… 근데 편차가 왜이리 큰겨?

http://docs.python.org/dev/library/shutil.html#shutil.make_archive

간단한 압축엔 유용하겠는걸…

Written by whitekid

April 13th, 2011 at 1:49 am

Posted in Uncategorized

Tagged with

mako expression filtering, decorator

without comments

www.makotemplates.orgdocsfiltering.htmlexpression-filtering">

http://www.makotemplates.org/docs/filtering.html#expression-filtering

  • u : URL escaping, provided by urllib.quote_plus(string.encode('utf-8'))
  • h : HTML escaping, provided by markupsafe.escape(string) (new as of 0.3.4 – prior versions use cgi.escape(string, True))
  • x : XML escaping
  • trim : whitespace trimming, provided by string.strip()
  • entity : produces HTML entity references for applicable strings, derived from htmlentitydefs
  • unicode (str on Python 3): produces a Python unicode string (this function is applied by default).
  • decode.<some encoding> : decode input into a Python unicode with the specified encoding
  • n : disable all default filtering; only filters specified in the local expression tag will be applied.

필터는 그냥 스트링 인자를 하나 받는 함수이므로 작성하기도 편하다.

그런데 아쉽게도 필더에 파라미터가 들어가지 않는구나..

www.makotemplates.orgdocsfiltering.htmldecorating">

http://www.makotemplates.org/docs/filtering.html#decorating

mako의 함수에 python의 decorator처럼 사용할 수 있다. 멋진데?

Written by whitekid

April 2nd, 2011 at 3:44 am

Posted in Uncategorized

Tagged with ,

파라미터가 있는 decorator

without comments

Python의 Decorator 기능은 한마디로 멋지다. 잘 쓰면 유용하지… 근데 작성하면 항상 헷갈린단 말이지…

decorator에 파라미터를 넘겨주고자 하는 경우에도 상당히 헷갈린다. 파라미터가 없는 것하고 형태가 아주 또 달라지거든.. 간단히 기억하자 파라미터가 있는 데코레이터는 wrapp 함수를 한번 더 두어야한다는 것..

def prefix_decorator(func):
        def new_func(*args, **kwargs):
                return 'prefix: ' + func(*args, **kwargs)
        return new_func

def my_decorator(str):
        def wrap(func):
                def new_func(*args, **kwargs):
                        return func(*args, **kwargs) + ' :' + str
                return new_func

        return wrap

@prefix_decorator
@my_decorator('added by decorator')
def test():
        return "I'm test"

print test()

실행 결과는 아래와 같음..

prefix: I'm test :added by decorator

Written by whitekid

March 31st, 2011 at 10:57 am

Posted in Uncategorized

Tagged with ,

python-mcrypt 사용 예

without comments

python-mcrypt은 문서가 없다. 포함된 test.py를 보면 되는데… 좀 길고..

#! -*- encoding: utf8 -*-
import base64
import urllib
import mcrypt
import random
import string

def random_string(length):
        return ''.join([random.choice(string.ascii_letters + string.digits) for x in range(length)])

chiper_key = random_string(16)

# encode
def encrypt(data):
        m = mcrypt.MCRYPT('rijndael-256', 'cfb')
        iv_size = m.get_iv_size()
        iv = random_string(iv_size)

        m.init(chiper_key, iv)
        return base64.b64encode(m.encrypt(iv + data))

# decode
def decrypt(data):
        data = base64.b64decode(data)
        m = mcrypt.MCRYPT('rijndael-256', 'cfb')
        iv_size = m.get_iv_size()
        iv = data[:iv_size]
        encrypted = data[iv_size:]
        m.init(chiper_key, iv)
        return m.decrypt(encrypted)

data = '안녕하세요'
assert data == decrypt(encrypt(data))

Written by whitekid

March 25th, 2011 at 4:45 pm

Posted in Uncategorized

Tagged with ,

cannot write mode P as JPEG

without comments

PIL로 이미지 썸내일 만드는데… 이런 에러가…

http://www.errorhelp.com/search/details/80884/ioerror-cannot-write-mode-p-as-jpeg

간단하다.. P 모드가 아닌 RGB 모드로..

Written by whitekid

March 12th, 2011 at 12:42 am

Posted in Uncategorized

Tagged with ,

GeoIP python

without comments

http://www.pointlessrants.com/2010/05/python-geoip-python-geoip-cities-tutorial/

import GeoIP
import socket

host = 'www.daum.net'

gi = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE)
print socket.gethostbyname(host), gi.country_code_by_name(host),

gi = GeoIP.open('GeoLiteCity.dat', GeoIP.GEOIP_STANDARD)
city = gi.record_by_name(host)
if city:
    print city['city'], city['region_name']

Written by whitekid

March 1st, 2011 at 1:17 am

Posted in Uncategorized

Tagged with ,

Python 함수에서 static 변수처럼 사용하기…

without comments

class에서는 static 변수가 지원됩니다. 그런데 함수에서 가끔 static이 필요할 때가 있습니다.

static을 사용하지 않는다면, global을 써야하는데, global을 사용한다는 것은 항상 꺼려지는 것이기에 static이 권장되죠. 하지만 python은 함수에 static을 지원하지 않고, 비슷하게 이를 흉내낼 수 있습니다.

_static을 잘 보시면 됩니다. 자세한 내용은 생략 ㅋㅋ

def get_connection(_static = {}):
    if 'conn' not in _static:
        conn = MySQLdb.connect(host=DB_HOST, user=DB_USER, passwd=DB_PASS, db=DB_NAME, use_unicode=True, charset='utf8')
        _static['conn'] = conn
    return _static['conn']

def get_cursor():
    return get_connection().cursor()

Written by whitekid

February 19th, 2011 at 10:41 pm

Posted in Uncategorized

Tagged with

psycopg2 쿼리 결과를 유니코드로 받기

without comments

psycopg2에서 쿼리의 결과는 client_encoding에 따른 그 형태 그대로 옮니다. 이 경우 인코딩을 처리하면서 해야하면 상당한 불편함이 따르지요.

무식하게 하나하나 unicode(row[0], ‘utf8′)로 인코딩해가면서 하고 있었습니다. 진짜 무식하게..

근데 설마 있겠지.. 하고 찾아봤더니 역시나 있군요.

import psycopg2
from lib import *

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
cursor = get_cursor()
cursor.execute('select subject from messages order by id desc limit 1')

for row in cursor:
    print type(row[0])

실행 결과는…

$ python test.py
<type 'unicode'>

역시.. 사람은 공부해야 손발이 고생하지 않는다.

Written by whitekid

September 14th, 2010 at 5:29 pm

Posted in Uncategorized

Tagged with ,

Python으로 iCalendar 만들기

without comments

Python으로 iCalendar를 만드는건 vobject을 이용하면됩니다. 다른 iCalendar 라이브러리인 py-iCalendar도 있는데, 이벤트 각 필드에 parameter를 주는데 문제가 있어서 잘 안됩니다.

# -*- encoding: utf8 -*-
import vobject
from datetime import datetime

cal = vobject.iCalendar()
event = cal.add('vevent')
event.add('summary').value = u'이벤트 하나'
event.add('description').value = u'이벤트 하나\n\n모두 참석해주세요...'
event.add('dtstart').value = datetime(2010, 9, 9, 18, 0, 0)
event.add('dtend').value = datetime(2010, 9, 9, 20, 0, 0)
event.add('dtstamp').value = datetime(2010, 9, 9, 18, 0, 0)
event.add('location').value = u'회의실'

o = event.add('organizer')
o.value = u'organizer@gmail.com'
o.params['CN'] = [u'오거나이저']

o = event.add('attendee')
o.value = u'must@gmail.com'
o.params['CN'] = [u'필수 참석자']
o.params['ROLE'] = [u'REQ-PARTICIPANT']

o = event.add('attendee')
o.value = u'optinal@gmail.com'
o.params['CN'] = [u'옵션 참석자']
o.params['ROLE'] = [u'OPT-PARTICIPANT']

o = event.add('attendee')
o.value = u'optinal1@gmail.com'
o.params['CN'] = [u'옵션 참석자1']
o.params['ROLE'] = [u'OPT-PARTICIPANT']

file('example.ics', 'wb').write(cal.serialize())

이코드로 만들어진 파일은 아래와 같습니다.

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//PYVOBJECT//NONSGML Version 1//EN
BEGIN:VEVENT
UID:20100910T025017Z-99461@woosum.net
DTSTART:20100909T180000
DTEND:20100909T200000
ATTENDEE;ROLE=REQ-PARTICIPANT;CN=필수 참석자:must@gmail.com
ATTENDEE;ROLE=OPT-PARTICIPANT;CN=옵션 참석자:optinal@gmail.com
ATTENDEE;ROLE=OPT-PARTICIPANT;CN=옵션 참석자1:optinal1@gmail.c
 om
DESCRIPTION:이벤트 하나\n\n모두 참석해주세요...
DTSTAMP:20100909T180000
LOCATION:회의실
ORGANIZER;CN=오거나이저:organizer@gmail.com
SUMMARY:이벤트 하나
END:VEVENT
END:VCALENDAR

이제 이 파일을 Outlook 인터넷 일정으로 등록하여 공유할 수 있고, 다른 여러 용도로 사용할 수 있겠지요.

Written by whitekid

September 10th, 2010 at 2:25 pm

Posted in Uncategorized

Tagged with , ,

python email header 인코딩 오류 수정l

without comments

postfix mail archiving을 진행하면서 메시지 헤더를 처리할 일이 생겼지요. 보내는 사람에 따라서 archiving을 하지 않으려구오. 뭐… cron에서 보내는거 daily 체크 메일등등 저장할 필요 없잖아요.

그런데 이거 하다보니 헤더 디코딩이 안된 것들이 간간히 들어옵니다. 언듯 봐서는 잘된것 처럼 보이는데 그래서 좀 찾아보니 python의 오류가 아니고, 아예 잘못된 헤더랍니다.

=?UTF-8?B?6rmA7ZiV7ISd?=&lt;XXXX@naver.com&gt;'
=?UTF-8?B?6rmA7ZiV7ISd?= &lt;XXXX@naver.com&gt;'

첫번째 것은 잘못 인코딩 된 것이고, 두번째 것은 제대로 인코딩 된 것입니다. RFC에 따르면 “?=” 다음에 스페이스를 넣게 되어있다는군요.

그래서 이거 해결하는 코드 간략하게 만들어 봤습니다. 아주 간단!!

def decode_header(s):
    ret = []
    for header, encoding in email.header.decode_header(s):
        if (encoding is None) and re.search(r'\?=.+', header):
            header = re.sub(r'([^\?.]{2})(\?=)(.{1})', r'\1\2 \3', header)
            ret.extend(email.header.decode_header(header))
            continue
        ret.append((header, encoding))
    return ret

근데.. 이런 오류는 꼭 NAVER에서 온 메일만 그래요… ㅡㅡ

ps. re.sub에서 [a-zA-Z0-9]는 \w로 바꿀 수 있다구요? 예 유니코드 환경이 아니면 맞는 이야기인데, 유니코드면 약간 다르더군요. Python 메뉴얼에는 이렇게 나와있습니다.

\w
When the LOCALE and UNICODE flags are not specified, matches any alphanumeric character and the underscore; this is equivalent to the set [a-zA-Z0-9_]. With LOCALE, it will match the set [0-9_] plus whatever characters are defined as alphanumeric for the current locale. If UNICODE is set, this will match the characters [0-9_] plus whatever is classified as alphanumeric in the Unicode character properties database.

Written by whitekid

August 25th, 2010 at 2:59 pm

Posted in Uncategorized

Tagged with ,