Python 在函数中使用模块时发生UnboundLocalError?

Python 在函数中使用模块时发生UnboundLocalError?,python,import,namespaces,Python,Import,Namespaces,从字符串导入时,与解析函数一起使用 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的标点符号,一切正常 然后,我想对照几个较少的标点符号检查数据。所以我 将解析函数更改为: def parsing_func(

字符串导入时,与解析函数一起使用

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
标点符号,一切正常

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

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
它打印的很好,没有错误,并且显示
类型str
。最后,我尝试将
打印
和字符串操作一个接一个地放在一起

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
回溯(最近一次呼叫最后一次):
文件“parser.py”,第9行,在
测试函数2()
文件“parser.py”,第5行,在test_func2中
打印类型(标点符号),标点符号
UnboundLocalError:赋值前引用的局部变量“标点符号”

这是一个
名称空间
错误,为什么
test_func2
在打印而不是字符串操作时返回错误?

您的第二个函数中既有一个本地标点
也有一个全局标点
。您可以将其重命名为:

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
或者将标点符号明确地设置为全局:

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
请注意,这会全局修改标点符号,所以我不会这样做

也可以使用集合执行此操作:

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

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

在第二个函数中,既有本地的
标点符号
,也有全局的
标点符号
。您可以将其重命名为:

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
或者将标点符号明确地设置为全局:

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
请注意,这会全局修改标点符号,所以我不会这样做

也可以使用集合执行此操作:

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

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

您在函数中指定了
标点符号,因此Python将其视为局部变量:因此它根本不使用全局名称。为赋值使用不同的名称。

您在函数中赋值给
标点符号,因此Python将其视为局部变量:因此它根本不使用全局名称。为赋值使用不同的名称。

这里的问题是,您试图将全局名称分配给一个“
标点符号”
,这是Python不允许的,因此它会创建一个局部变量
标点符号。此时,它将尝试查找右侧的
标点符号
,并获取尚未存在的局部变量

要解决这个问题,您可以使用
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
还值得注意的是,我在
中使用了
,以检查成员资格-它可读性更强,速度更快。通常,在集合上的成员资格测试更快,通过使用集合,我们还可以以更可读的方式删除值:

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

这里的问题是,您试图分配一个全局名称-
标点符号
,Python不允许这样做,因此它创建了一个局部变量
标点符号
。此时,它将尝试查找右侧的
标点符号
,并获取尚未存在的局部变量

要解决这个问题,您可以使用
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
还值得注意的是,我在
中使用了
,以检查成员资格-它可读性更强,速度更快。通常,在集合上的成员资格测试更快,通过使用集合,我们还可以以更可读的方式删除值:

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

上一个示例假设
数据
不需要重复项或顺序。@Lattyware:看起来OP的代码只是检查字符串是否包含标点符号,所以我认为这不需要任何顺序。这是一个很好的观点,我不认为它是测试的替代品。您的上一个示例假设
数据
不需要重复项或顺序。@Lattyware:看起来OP的代码只是检查字符串是否包含任何标点符号,所以我认为不需要任何顺序。这是一个好的观点,我不认为它是测试的替代品。