proper std out encoding

DEF_ENCODING = sys.getdefaultencoding()
if sys.stdout.encoding:
    DEF_ENCODING = sys.stdout.encoding
elif locale.getpreferredencoding():
    DEF_ENCODING = locale.getpreferredencoding()

including PYTHONIOENCODING

DEF_ENCODING = sys.getdefaultencoding()
if sys.stdout.encoding:
    DEF_ENCODING = sys.stdout.encoding
elif 'PYTHONIOENCODING' in os.environ:
    DEF_ENCODING = os.environ['PYTHONIOENCODING']
elif locale.getpreferredencoding():
    DEF_ENCODING = locale.getpreferredencoding()

and now you can use as follows:

# read string from io(file or network)
u = u’\uc5d4\uc9c4′
print u.encode(DEF_ENCODING)
# ‘엔진’

Happy Coding~:)

Advertisements
Posted in python | Tagged | Leave a comment

CP949 Table in Unicode

CP949 테이블의  문자를 Unicode에 정의된 이름으로 출력해본다.

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import unicodedata

"""
CP949 table
https://msdn.microsoft.com/en-us/library/cc194942.aspx

the output of this script should have the same as
http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT
"""

for lead in range(0x81, 0xF0):
	# these range not exist
	if lead in [0xc1, 0xc2]:
		continue
	for pt in range(0x40, 0xFF+0x1):
		str = ''.join(map(chr, [lead, pt]))
		# print str
		print "# %02x%02x" % (lead, pt),
		try:
			uni = str.decode('cp949')
			text = unicodedata.name(uni)
			print str, text
		except UnicodeDecodeError:
			print "not exist"

생성된 파일은 다음과 같다
cp949.PNG

Happy Coding~:)

 

Posted in python | Tagged , , | Leave a comment

Code Syntax Highlight in WordPress.com

When posting a code in WorkPress.com, you can use ‘code’ tag

syntaxhighlight.PNG

  1. change view as ‘HTML’
  2. enclose your code with ‘code’ tag as follows’
    syntaxhighlight3.PNG

you can check full list of supported language at https://en.support.wordpress.com/code/posting-source-code/

Happy Coding~:)

Posted in python, Uncategorized | Tagged , , , | 2 Comments

Generator, Coroutine, async

500 Lines or Less | A Web Crawler With asyncio Coroutines
http://bit.ly/2pelfz7
어떻게  generator를 이용해서 async를 구현하는 방법에 대한 원문에 해당하는글

 

How Do Python Coroutines Work? – YouTube

blocking io부터 시작해서 async callback, generator를 통한 asyncio를 구현하는 전과정을 보여준다. 
http://bit.ly/2pe35xF

Łukasz Langa – Thinking In Coroutines

by PyCon 2016

python 3.4 이상에서 지원하는 async, await 까지 설명한 종합판

Happy Coding~:)

Posted in python | Tagged , | Leave a comment

How generator works in opcode

다음과 같이 두개의 yield 구문을 포함해서  함수를 정의한다.

def gen_1_2():

# print 'gen return', 1
 arg = yield 1
 # print 'gen got', arg

# print 'gen return', 2
 arg = yield 2
 # print 'gen got', arg

yield 구문을 포함한 function은 일반 함수처럼 호출되지 않고  generator를 리턴한다. opcode는 확인해 보면 다음과 같다.

gen = gen_1_2()
 print type(gen_1_2), type(gen), gen
 # <type 'function'> <type 'generator'> 
 print dis.disassemble(gen.gi_code)
 # 10 0 LOAD_CONST 1 (1)
 # 3 YIELD_VALUE
 # 4 STORE_FAST 0 (arg)

# 14 7 LOAD_CONST 2[ (2)
 # 10 YIELD_VALUE
 # 11 STORE_FAST 0 (arg)
 # 14 LOAD_CONST 0 (None)
 # 17 RETURN_VALUE

generator를 시작하기 위해서는 한가지 주의할 부분이 있다. 가장 처음 send를 호출할때 None value를 넘겨주어야 한다.
처음 send 이후에 last instruction을 확인해 보면(‘–>’를 가르키고 있는 곳) 첫번째 YIELD_VALUE opcode를 가르키고 있습니다.

# TypeError: can't send non-None value to a just-started generator
 # num = gen.send(11)
 print 'caller send None'
 num = gen.send(None)
 print 'caller got', num
 print "disassemble w/ lasti with gen", type(gen)
 print dis.disassemble(gen.gi_code, gen.gi_frame.f_lasti)
 # disassemble w/ lasti with gen <type 'generator'>
 # 10 0 LOAD_CONST 1 (1)
 # --> 3 YIELD_VALUE
 # 4 STORE_FAST 0 (arg)

# 14 7 LOAD_CONST 2 (2)
 # 10 YIELD_VALUE
 # 11 STORE_FAST 0 (arg)
 # 14 LOAD_CONST 0 (None)
 # 17 RETURN_VALUE

이제 2번째 send를 호출한 후 last instruction을 확인해 보면 2번째 YIELD_VALUE를 가르키고 있습니다.

caller = 21
print 'caller send', caller
num = gen.send(caller)
print 'caller got', num

print "disassemble w/ lasti with gen", type(gen)
print dis.disassemble(gen.gi_code, gen.gi_frame.f_lasti)
# caller send 21
# caller got 2
# disassemble w/ lasti with gen <type 'generator'>
# 10 0 LOAD_CONST 1 (1)
# 3 YIELD_VALUE
# 4 STORE_FAST 0 (arg)

# 14 7 LOAD_CONST 2 (2)
# --> 10 YIELD_VALUE
# 11 STORE_FAST 0 (arg)
# 14 LOAD_CONST 0 (None)
# 17 RETURN_VALUE

즉 YIELD_VALUE를 통해서 generator와 caller간에 context switch가 일어 나고 있는 것을 확인 할 수 있습니다.

Happy Coding~:)

Posted in python | Tagged | Leave a comment

CPython internals: A ten-hour codewalk through the Python interpreter source code

와우!!!

Posted in python | Tagged , , , | Leave a comment

string concatenation vs join

bytearray에 대한 글을 읽다 다음과 같은 구문이 있어서 확인해 보았다.
스트링을 concat 하는 것보다는 join을 하는게 퍼포먼스가 좋다는 내용이다.

http://dabeaz.blogspot.kr/2010/01/few-useful-bytearray-tricks.html

The only problem with this code is that concatenation (+=) has horrible performance. Therefore, a common performance optimization in Python 2 is to collect all of the chunks in a list and perform a join when you’re done. Like this:

# remaining = number of bytes being received (determined already)
msgparts = []
while remaining > 0:
    chunk = s.recv(remaining)    # Get available data
    msgparts.append(chunk)       # Add it to list of chunks
    remaining -= len(chunk)  
msg = b"".join(msgparts)          # Make the final message

https://github.com/python/cpython/blob/master/Objects/unicodeobject.c

Concat

모든 element에 대해서 매번 새로운 object를 생성해서 object들을 복사한다.

PyObject *
PyUnicode_Concat(PyObject *left, PyObject *right)
{
 ...

left_len = PyUnicode_GET_LENGTH(left);
 right_len = PyUnicode_GET_LENGTH(right);

 new_len = left_len + right_len;

maxchar = PyUnicode_MAX_CHAR_VALUE(left);
 maxchar2 = PyUnicode_MAX_CHAR_VALUE(right);
 maxchar = Py_MAX(maxchar, maxchar2);

/* Concat the two Unicode strings */
 result = PyUnicode_New(new_len, maxchar);

 _PyUnicode_FastCopyCharacters(result, 0, left, 0, left_len);
 _PyUnicode_FastCopyCharacters(result, left_len, right, 0, right_len);
 assert(_PyUnicode_CheckConsistency(result, 1));
 return result;
}

Join

생성한 하나의 object에 memcpy를 이용해서 모든 element를 복사한다.

PyObject *
_PyUnicode_JoinArray(PyObject *separator, PyObject **items, Py_ssize_t seqlen)
{
...

res = PyUnicode_New(sz, maxchar);
 if (res == NULL)
 goto onError;

/* Catenate everything. */
 if (use_memcpy) {
for (i = 0; i < seqlen; ++i) {
Py_ssize_t itemlen;
item = items[i];

/* Copy item, and maybe the separator. */
if (i && seplen != 0) {
memcpy(res_data,
sep_data,
kind * seplen);
res_data += kind * seplen;
}

itemlen = PyUnicode_GET_LENGTH(item);
if (itemlen != 0) {
memcpy(res_data,
PyUnicode_DATA(item),
kind * itemlen);
res_data += kind * itemlen;
}
}
assert(res_data == PyUnicode_1BYTE_DATA(res)
+ kind * PyUnicode_GET_LENGTH(res));
}
...

Conclusion

concat의 경우 list의 모든 element에 대해서 매번 새로운 object를 생성해서 두개의 object를 복사하기 때문에 속도가 느리게 되고,
반면에 join의 경우 하나의 object만 새로 생성해서  모든 elements를 memcpy하기 때문에 상대적으로 속도가 빠르다.

Posted in python | Tagged , | Leave a comment