顯示具有 python 標籤的文章。 顯示所有文章
顯示具有 python 標籤的文章。 顯示所有文章

2014年1月5日 星期日

cross compile python for arm

這裡是編譯 Python 3.3.3 的方法

1. 建立 config.site,檔案內容如下

ac_cv_file__dev_ptmx=no
ac_cv_file__dev_ptc=no 


2.  在 python 3.3.3 的目錄下依序輸入以下指令。cross compiler 的相關變數你改成你系統的。



CONFIG_SITE=config.site CC=arm-linux-gcc CXX=arm-linux-g++ AR=arm-linux-ar RANLIB=arm-linux-ranlib ./configure --host=arm-linux --build=x86_64-linux-gnu --prefix=/python LDFLAGS="-static -static-libgcc" CPPFLAGS="-static -march=armv4t" --disable-ipv6
make HOSTPYTHON=./hostpython HOSTPGEN=./Parser/hostpgen BLDSHARED="arm-linux-gcc -static" CROSS_COMPILE=arm-linux- CROSS_COMPILE_TARGET=yes HOSTARCH=arm-linux BUILDARCH=x86_64-linux-gnu
 make install HOSTPYTHON=./hostpython BLDSHARED="arm-linux-gcc -static" CROSS_COMPILE=arm-linux- CROSS_COMPILE_TARGET=yes prefix=~/mypython

參考資料:

http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html
http://bugs.python.org/msg136962

2013年12月29日 星期日

簡介 python 的物件生成 ( how to generate an instance in python)

    在開始介紹 python 怎麼產生 instnace 前,先來看一段簡單的程式碼


class MyStr1(str):
    def __init__(self, a='', b=''):
        super(MyStr1, self).__init__()
        self.a = a
        self.b = b


    這段程式碼看起來沒什麼,就繼承自 str 。然後 override __init__ 方法。所以我們可以用下面程式碼產生 instance。


 a = MyStr1("1")

   可是當我們執行下面程式碼時,

 a = MyStr1("1", "2")


    卻會出現

Traceback (most recent call last):
  File "", line 1, in 
TypeError: str() takes at most 1 argument (2 given)

    這到底發生什麼事? 會出現這個錯誤,是因為 str.__new__ 這個方法只接受一個參數,而你給他兩個。

    做個簡單的實驗。執行這兩行 str.__new__(str) 和 str.__new__(str, '1') 程式碼不會出錯。然而 str.__new__(str, '1', '2') 會出現上面的錯誤。所以可以合理懷疑問題真的出在這了。

     接下來來談一個 class 怎麼產生 instance。當 class 要產生 instance 時,他會呼叫 class 的 metaclss 的 __call__ 方法。而 metaclass 的 __call__ 方法大概長這樣:

def __call__(cls, *args, **kwargs):
    obj = cls.__new__(cls, *args, **kwargs)
    obj.__init__(*args, **kwargs)
    return obj

    所以執行 a = MyStr1("1", "2") 時,直譯器會先做 obj = str.__new__(str, *args, **kwargs) ,其中 *args 是 (1, 2, 3),可是因為 str.__new__ 只接受一個參數,因此發生錯誤。

    要怎麼知道直譯器在建立 instance 時,會把類別名稱後面的參數全都丟進 __new__ 和 __init__ 裡呢? 用一段簡單的程式即可說明。



class ClsA(object):
    def __init__(self, *args, **kwargs):
        print 'init: ', args, kwargs

    def __new__(cls, *args, **kwargs):
        print 'new: ', args, kwargs
        return super(ClsA, cls).__new__(cls, *args, **kwargs)

  
a = ClsA('a', 'b', 2)


   上面程式碼,當要建立 ClsA 的程式碼,他會先執行 __new__,而餵給 __new__ 的參數則是 ClsA 後面的參數。之後再把 ClsA 後面的參數餵給 __init__。而這也說明了為什麼一開始的程式碼會有問題。因為建立 instance 時,預設行為是把類別後面的參數全都丟給 __new__ 和 __init__。可是 str.__new__最多只接受一個參數,因此出錯。

    要如何解決第一個程式所遇到的問題呢?
    解法1.
    不要使用預設的 metaclass(type),自訂一個 meta class


class CustomMetaCls(type):
    def __call__(cls, *args, **kwargs):
        if len(args):
            content = args[0]
        else:
            content = ''
        obj = cls.__new__(cls, content)
        obj.__init__(*args, **kwargs)
        return obj

  
class MyStr(str):
    __metaclass__ = CustomMetaCls
 
    def __init__(self, a='', b=''):
        super(MyStr, self).__init__(a)
        self.a = a
        self.b = b


b = MyStr('a', 'b')


    解法2.
    override __new__

class MyStr1(str):
    def __init__(self, a='', b=''):
        super(MyStr1, self).__init__()
        self.a = a
        self.b = b

    def __new__(cls, *args, **kwargs):
        print args, kwargs
        if len(args):
            content = args[0]
        else:
            content = ''
        return str.__new__(cls, content)

2013年11月1日 星期五

CPython 2.7.5 中使用 join 寫法來做字串加法比較快?還是使用 += ?

    如果你在 windows 下執行下面的程式碼,你會發現用 += 會比 join 寫法還快

a='''
def test_join():
    data = []
    for i in range(100):
        data.append('ad')
    return ''.join(data)
test_join()
'''
b = '''
def test_connect():
    data = ""
    for i in range(100):
        data += 'ad'
    return data
test_connect()
'''

import timeit
print timeit.timeit(a, number=10)
print timeit.timeit(b, number=10)

2013年10月13日 星期日

浮點數除於零的行為

    程式語言中,整數除於零,基本上都會讓程式無法執行或是拋出類似例外的錯誤。可是如果是浮點數除於零的話,則行為就不一定。在 IEEE 754 的標準,浮點數除於零的話,會產生代表無窮大的值。c, c++, tcl, ruby, scala, java 遵循 IEEE 754。不過 perl, python , go 語言,發生浮點數除於零的情形,則是產生類似例外的訊息,而非給定無窮大的值。其他的語言沒有測試,這篇純粹紀錄各種語言的細微差異。

2013年7月6日 星期六

python 的 gc ( garbage collection) 演算法介紹

    最近無聊看了一下 python 的 garbage collect 的實作。還蠻簡單易懂的。 python 回收沒用的物件,主要是靠參考計數 (reference count)。然而,他無法解決自己參考自己或是參考循環(a 參考 b, b 參考 a)的問題。這篇文章是講 python 如何解決這個問題。

2013年6月15日 星期六

在 python 中呼叫 java,JPype 簡介

    之前我以為如果要在 python 中呼叫 java lib ,只能用 jython。然而查了一些資料,發現有些神人已經幫我們做好在 CPython 中呼叫 java lib 的方法,JPype 可以幫我們完成這個神奇的需求。


2013年6月9日 星期日

以 html5 撰寫 單機(離線)程式,以 pyside 與 qwebkit 為例。

    現在 html5 蔚為潮流,而 html5 也將觸手伸向單機程式。新的 html5 技術可以使用 ApplicationCache 來達成。而 XULRunner 又是令一個技術,讓你可以用寫網頁的方式來寫單機程式。用 pyside 加上 qwebkit 也可以達到類似的應用。事實上,pyside 加上 qwebkit 的作法不過是作個客製化瀏覽器而已。

2013年5月8日 星期三

python 中 is 和 ==(等於) 的差別

    在很多程式語言中,相等的意義有兩種意涵,一種是指那兩個變數實際上是指向同一個物件,另外一種意涵是雖然他們不是相同物件,但是他們的值一樣(什麼叫做值一樣,可以自己寫函數定義)。在 java 中,我們用 == 還比較這兩個變數是否指向相同物件,而使用 object.equal(other) 還比較兩個變數物件的值是否一樣。 在 python 中,則是使用 is 這個關鍵字來判斷這兩個變數是否指向相同物件,而使用 == 來判斷兩個變數物件的值是否一樣(值是否一樣由 __eq__ 這個函數定義)

2013年5月4日 星期六

pdb 的運作原理

    要了解 python debuger 的運作方式前,需要先了解 python 如何實作 function call。在 C語言中,每個被呼叫函數都有自己的 call stack拿來存放區域變數之類的東西。而在 python 中, call stack作用是由 frame object 物件完成。下面是官網對 frame object 的屬性介紹

python yield 語法與 generator 物件介紹

    這篇介紹 yield 語法以及用來維護 yield 行為的 generator 物件。
    事實上,yield 和 return 很像,只是當函數呼叫 return 時,該函數 call stack (python 中是 frame) 就會被清除,程式主導權回到呼叫該函數的手上。 而 yield 會把程式主導權交給呼叫該函數的手上,但是他不會把函數的 call stack 清除,因此下次呼叫時,可以從上次未執行的部分開始執行,而不是重新建立一個新 stack。

2013年4月9日 星期二

如何使用 django 的 i18n

    因為今天被 django 的 i18n 搞很久。所以只好寫篇文章作個紀錄。

    django 要做到 i18n。首先,你需要把程式中要翻譯的字串都改成 _("string") 這種形式。其次,你需要在 template 加上 {% load i18n %},以及把 template 的字串改成 {% trans "string" %}。在程式碼和 template 加完上面的東西後。接下來就是重點了,至少是我犯錯的地方。

2013年4月8日 星期一

python runtime 產生物件與 compile-time 產生物件方法的比較

    python 是一個很有彈性的語言,可是彈性也意味著,完成一件事情會有很多方法。這篇文章介紹產生產生 dict 與 type object 的方法。注意,以下討論都是未最佳化的情形。

    首先介紹產生 dict 的方法。在 python 中,產生 dict ( list 和 tuple 相同) 方法至少有兩種,一種是使用 {}, 另外一種是使用 dict() 的形式。前者是 compile-time 就會決定要產生 dict 物件,而後者是函數呼叫型式,他必須等到 run-time 時期才知道是產生 dic。至於後者較前者有何好處我就不清楚了。

2013年3月20日 星期三

callback function 與 decorator ( 以 python 為示範 )

    在網路上看到有人問 callback function 和 decorator 有何不同。 基本上,他們兩個完全是不同概念的東西。 callback function 是指 A function  呼叫 B  function 時,傳入 C function 作為參數。B function 在做一些事情後,可能會呼叫 C function。 C function 在這個情境下就是 callback function。


2013年3月18日 星期一

比較c++、python、go、與javascript的 lambda語法

C++11 算是出了一段時間了,而最近編譯器對 C++11 的支持也越來越完善了。 C++11 有一個新特性,就是支援 lambda 的語法,所以就把一些語言的 lambda 語法拿來做比較。首先是python。

map(lambda s: s * s, [1, 2, 3])
python 的 lambda 語法很好理解,冒號前是參數,冒號後是程式碼。lambda   的限制就程式碼只能夠一行。lambda 可以存取外部變數,但是不能使用 assignment statement。

2013年3月7日 星期四

dict literal 與 dict constructor 的比較

    基本上, dict literal ( 使用{}建立物件 ) 和 dict constructor ( 使用 dict() 建立物件 ) 結果一樣。 只是他們之間仍有些許的差異。

    首先是速度上的差異,當 interrupter 執行到 {} 時,interrupter 會知道是要建立 dict 物件。 然而,當 interrupter 執行到 dict() 時,他會認定執行 function call。因此多個函數呼叫與參數傳遞。不過這兩者間的效能差異不算大,也可能會被最佳化。我用下面程式碼做簡單測試

2013年3月1日 星期五

在 python 中較快的字串加法

在 python、java 中,字串都是不可變的(immutable)。意味著,字串被建立後就不能夠被修改。因此,當你在做 n 個字串加法時,它會產生 n - 2 個暫時字串物件。 為了避免在做大量字串加法時,產生過多的暫時物件。 java 中有 stringbuffer 可以使用。用法如下:

2013年2月28日 星期四

python 的 functools.partial 函數

很久以前,就看過這個  functools.partial 了。 只是一直不太明瞭它的實際作用。直到最近我在讀 c++11 時,看到 std::bind 時,我突然領悟 functools.partial 和 std::bind 做的事情一樣。

2013年2月4日 星期一

淺談python繼承

最近無聊翻了一下書櫃,找到一本買了卻沒讀完的書,exceptional c++。就稍微看了一下,看看裡面有沒有什麼文章對於寫python code有助益的

那本書條款24(第104頁),是在討論有關使用/濫用繼承。

2013年1月20日 星期日

程式語言分析



這篇文章是當初我找工作時,履歷的附加檔案。基本上只是我個人的主觀意見。每種語言都有各自的愛好者,且每個人的偏好也不一定相同。選擇自己最喜歡的語言即可。



2013年1月5日 星期六

[程式語言] 淺談Python的預設參數

這篇文章是要討論python的預設參數


def fun1(a=0):
        print a

def fun2(a=[]):
        a.append(1)
        print a
        print 'address: ', id(a)

class DefaultObject:
        def __init__(self):
                print 'call me'

def fun3(a=DefaultObject()):
        print 'address: ', id(a)