2013-04-20 18 views
0

當從string模塊導入時,使用解析函數。在函數內部使用模塊時出現UnboundLocalError?

from string import punctuation 


def parsing_func(data): 
    if not any(i==v for i in data for v in punctuation.replace('_', '')): 
     print data 

使用stringpunctuation如上面這個功能,一切工作正常。

然後,我想檢查數據對少了幾個標點符號。所以我 改變parsing_func這樣:

def parsing_func(data): 
    punctuation = punctuation.replace('_', '') 
    punctuation = punctuation.replace('()', '') 
    if not any(i==v for i in data for v in punctuation): 
     print data 

但這返回:

Traceback (most recent call last): 
    File "parser.py", line 58, in <module> 
    parsing_func(data) 
    File "ex.py", line 8, in parsing_func 
    punctuation = punctuation.replace('_', '') 
UnboundLocalError: local variable 'punctuation' referenced before assignment 

所以,我做一個測試功能檢查punctuation

def test_func1(): 
    print type(punctuation), punctuation 

>>> <type 'str'> !"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~ 

打印出細膩,無錯誤,並顯示type str。最後,我嘗試將print和字符串操作一個接一個地放在一起。

def test_func2(): 
    print type(punctuation), punctuation 
    punctuation = punctuation.replace('_', '') 

但現在print語句返回錯誤:

Traceback (most recent call last): 
    File "parser.py", line 9, in <module> 
    test_func2() 
    File "parser.py", line 5, in test_func2 
    print type(punctuation), punctuation 
UnboundLocalError: local variable 'punctuation' referenced before assignment 

這是一個錯誤namespace和去打印,而不是對字符串操作的時候爲什麼會test_func2返回錯誤?

回答

1

你分配給你的punctuation函數中,所以Python將其視爲一個局部變量:因此它不使用全局名稱都沒有。爲作業使用不同的名稱。

1

在第二個函數中同時有本地的punctuation和全局的punctuation。您可以將其重命名:

def parsing_func(data): 
    punct = punctuation.replace('_', '') 
    punct = punctuation.replace('()', '') 

    if not any(i == v for i in data for v in punct): 
     print data 

或做punctuation明確一個全球性的:

def parsing_func(data): 
    global punctuation 

    punctuation = punctuation.replace('_', '') 
    punctuation = punctuation.replace('()', '') 

    if not any(i==v for i in data for v in punctuation): 
     print data 

請注意,這個修改punctuation全球範圍內,所以我不會這麼做。

您還可以設置這樣做:

def has_punctuation(data): 
    punct = set(punctuation) - set('_()') 

    return punct & set(data) # Intersection of the two sets 
+0

你的最後一個例子假設'data'不需要重複或訂單。 – 2013-04-20 20:26:56

+1

@Lattyware:它看起來像OP的代碼只是檢查字符串是否包含任何標點符號,所以我不認爲這需要任何順序。 – Blender 2013-04-20 20:28:08

+0

這是一個很好的觀點,我沒有考慮它作爲測試的替代品。 – 2013-04-20 20:28:33

1

這裏的問題是,您正嘗試分配一個全局名稱 - punctuation,這是Python不允許的,所以它會創建一個局部變量punctuation。此時,它會嘗試在右側查找punctuation,並獲取尚不存在的局部變量。

爲了解決這個問題,你可以使用global來修改全局變量(這是一個壞主意,可能不是你想要的),或者簡單地將它分配給本地名稱。

def parsing_func(data): 
    less_punctuation = punctuation.replace('_', '') 
    less_punctuation = less_punctuation.replace('()', '') 
    if not any(i in less_punctuation for i in data): 
     print data 

這也是值得注意我使用的in檢查會員 - 它既是更具可讀性和速度更快。在一般情況下,會員檢驗是集速度更快,並採用套,我們也可以刪除一個更可讀的方式值:

def parsing_func(data): 
    less_punctuation = set(punctuation) - set("_()") 
    if not any(i in less_punctuation for i in data): 
     print data 
相關問題