andelf fledna Feather

2011年6月13日星期一

How to make your source code compatiable with py2.4 to py3.2

* suggestion

put all compat fix code into a compat.py, import it.

* imports fix

some modules have been moved or rearanged.

* unicode fix

use from __future__ import unicode_literals, it only supports py2.6+
fix `unicode`, `basestring` in py3+

* grammer

with expression: never use. if you want to support py2.5-

except ... as ...: use function fix

* sample compat.py

try:
____import urlparse
____from urllib import urlencode, quote, unquote, splithost, splittype
____urlparse.urlencode = urlencode
____urlparse.quote = quote
____urlparse.unquote = unquote
____urlparse.splithost = splithost
____urlparse.splittype = splittype
____# fix py2.5-
____if not hasattr(urlparse, 'parse_qs'):
________from cgi import parse_qs
________urlparse.parse_qs = parse_qs
____globals()['bytes'] = str
except ImportError:
____import urllib.parse as urlparse
____globals()['unicode'] = str
____globals()['basestring'] = str

2011年6月10日星期五

实现 python 源码兼容 python2.4 -> python3.2 的兼容

def except_as():
____return sys.exc_info()[1]

这样就可以搞定不支持 except ... as ... 的情况了.

2011年6月8日星期三

百度贴吧如何贴代码?

浏览器地址栏执行
javascript:document.getElementById('bdeTextArea').setAttribute('onpaste', null);

2011年6月5日星期日

使用 class ClassName: 如何创建 new-style class

class A:
__metaclass__ = type
pass

答案是使用 __metaclass__

2011年6月3日星期五

如何获取文件大小?

除了 stat...如果对于已经有fp的话...可以

with open(filename, 'rb') as fp:
fp.seek(0, 2)
filesize = fp.tell()

2011年5月24日星期二

why a STORE_FAST after INPLACE_ADD

python 2.7


In [20]: def foo():
....: a += 1
....:

In [21]: dis.dis(foo)
2 0 LOAD_FAST 0 (a)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (a)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE3

some notes on python sets

according to the doc, we have a set and frozenset built-in func in
python now.

so what's frozenset?

doc says:
Set and ImmutableSet were renamed to set and frozenset.

they don't act like str and unicode, where there's a basestring! no
baseset!!

so you must use isinstance(x, (set, frozenset)).
check it with set.mro().

PS: I got a new handful type/function:
function = type(lambda : None)
Docstring:
function(code, globals[, name[, argdefs[, closure]]])

Create a function object from a code object and a dictionary.
The optional name string overrides the name from the code object.
The optional argdefs tuple specifies the default argument values.
The optional closure tuple supplies the bindings for free variables.

2011年3月25日星期五

where is urldecode in python urllib?

Answer:

refer to cgi module.

cgi.parse_qs

cgi.parse_qsl

Why:

because urllib is used to make request, while cgi is used to receive request.

uc_authcode 函数的 Python 实现.

很多其他语言开发的网站程序需要整合到UCenter中,但是由于 UCenter 是使用
PHP开发的,很难移植。其中最难缠的 uc_authcode.
测试实现了 uc_authcode 函数。纯 python,无三方库。

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#  FileName    : uc_authcode.py 
#  Author      : Feather.et.ELF  
#  Created     : Fri Mar 25 00:11:57 2011 by Feather.et.ELF 
#  Copyright   : Feather Workshop (c) 2011 
#  Description : uc_authcode in python 
#  Time-stamp: <2011-03-25 00:12:13 andelf> 


def uc_authcode(string, op='DECODE', key='', expiry=0):
    import time as t
    import base64
    import hashlib

    md5 = lambda s: hashlib.md5(s).hexdigest()
    microtime = lambda : str(t.time())
    time = lambda : int(t.time())

    ckey_length = 4

    key = md5(key) # or use key = md5(key or UC_KEY)
    keya = md5(key[:16])
    keyb = md5(key[16:])
    if op == 'DECODE':
        keyc = string[:ckey_length]
    else:
        keyc = md5(microtime())[-ckey_length:]

    cryptkey = keya + md5(keya + keyc)
    key_length = len(cryptkey)

    if op == 'DECODE':
        string = base64.b64decode(string[ckey_length:])
    else:
        string = ('%010d' % (expiry + time() if expiry else 0)) + \
                 md5(string + keyb)[:16] + string

    string_length = len(string)
    result = ''

    box = range(256)

    rndkey = [ord(cryptkey[i % key_length]) for i in xrange(256)]
    
    j = 0
    for i in xrange(256):
        j = (j + box[i] + rndkey[i]) % 256
        box[i], box[j] = box[j], box[i]

    a = j = 0
    for i in xrange(string_length):
        a = (a + 1) % 256
        j = (j + box[a]) % 256
        box[a], box[j] = box[j], box[a]
        result += chr(ord(string[i]) ^ (box[(box[a] + box[j]) % 256]))

    if op == 'DECODE':
        try:
            # use assert to catch misc case
            assert (int(result[:10])== 0) or (int(result[:10]) - time()> 0)
            if result[10:26] == md5(result[26:] + keyb)[:16]:
                return result[26:]
            else:
                return ''
        except:
            return ''
    else:
        return keyc + base64.b64encode(result).replace('=', '')

def test():
    APP_KEY = 'x2ta5X12oTz75gbRTMB6gY6thZ7D83'
    text = 'this_is_the_string_to_be_encrypted'
    print 'text=', text
    e = uc_authcode(text, "ENCODE", APP_KEY)
    print 'e=', e
    e += '='*(len(e) % 4)               # must fix padding
    assert uc_authcode(e, "DECODE", APP_KEY) == text
    
    print 'rslt=', uc_authcode(e, "DECODE", APP_KEY)


if __name__ == '__main__':
    test()