2012-06-02 48 views
4

Python初學者在這裏。試着通過在這裏和那裏閱讀代碼來學習。在一個旨在用python打開Excel文件的程序中遇到這個問題。此函數執行簡單的工作 - 使用ord()將Excel列字母標籤('Z'或'BB'或'CCC')轉換爲int。我理解就好直到我看到的轉換代碼的這個部分:什麼是[0])的的(1 +(ORD(柱目的使用ord()將字母轉換爲整數(非常基本)

if clen == 1: 
    return ord(column[0]) - 64 
elif clen == 2: 
    return ((1 + (ord(column[0]) - 65)) * 26) + (ord(column[1]) - 64) 

- 65)與只使用(ORD( 。列[0]) - 64)再次實施 「1 +」 似乎是多餘的,這是否是有目的的

這是全功能:

def column_index_from_string(column, fast=False): 
    """Convert a column letter into a column number (e.g. B -> 2)""" 

    column = column.upper() 

    clen = len(column) 

    if not fast and not all('A' <= char <= 'Z' for char in column): 
     msg = 'Column string must contain only characters A-Z: got %s' % column 
     raise ColumnStringIndexException(msg) 

    if clen == 1: 
     return ord(column[0]) - 64 
    elif clen == 2: 
     return ((1 + (ord(column[0]) - 65)) * 26) + (ord(column[1]) - 64) 
    elif clen == 3: 
     return ((1 + (ord(column[0]) - 65)) * 676) + ((1 + (ord(column[1]) - 65)) * 26) + (ord(column[2]) - 64) 

回答

5

不,它沒有目的? 。甚至在Python中也可以使用1+x-65 = x-64 :-)

可能是原始開發者認爲理解65是什麼比64更容易理解。但兩者都是幻數,而且最好通過將它們分配給變量來賦予數字名稱。

4

-65 +1的目的主要是由原始開發人員進行糟糕的優化嘗試所致。我通常使用下面的函數來Excel列轉換成一個整數值:

return reduce(lambda x,y: x*26+ord(y)-ord('A')+1, column.upper(), 0) 

有趣的是ord(y)-ord('A')+1,讓你你的問題的關鍵。假設列變量僅包含有效的A-Z Excel列字符串,則列號實際上是給定字符從A char加上1的位移。 ord('A')會給你65作爲結果。開發人員用其最終值替換ord('A')

那說,是的,它似乎是一個在這裏優化避免調用ord,但它實際上是混淆代碼和消除可讀性,我認爲過一段時間獲得的。如果這個函數確實是一個在程序中被調用了數百萬次的關鍵函數,那麼這不是必須編寫用於優化代碼的代碼 - 而是創建一個預先計算好的字典,其中包含所有Excel列名稱條目到它們的整數值,或者像這樣的非常有效的東西。

這裏,所做的是在性能與可讀性和代碼維護的權衡取捨方面做出的不好選擇;至少你會期待解釋# 65 = ord('A')的評論,你不會在這裏問一個關於它的問題。關鍵點:保持代碼邏輯,簡單,易讀,易於維護,不要因惡意優化而改變代碼。