在函数内部使用模块时是UnboundLocalError吗?

时间:2013-04-20 20:18:09

标签: python import namespaces

string模块导入时,与解析函数一起使用。

from string import punctuation


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

在上面这个函数中使用string的{​​{1}},一切正常。

然后,我想检查几个较少标点符号的数据。所以我 将punctuation更改为:

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'> !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ 。最后,我尝试将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会在打印而不是字符串操作时返回错误?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

您在函数内部分配punctuation,因此Python将其视为局部变量:因此它根本不使用全局名称。为作业使用不同的名称。

答案 2 :(得分: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