计算异常会导致UnboundLocalError

时间:2017-07-13 11:54:55

标签: python scope jupyter-notebook

当我尝试像这样计算Jupyter Notebook中的异常时:

read_err_cnt = 0
def clean_words(text):
  tokenizer = RegexpTokenizer('[\'а-яА-Яёй]+', discard_empty=True)
  try:
      for word in tokenizer.tokenize(text):
          yield word
  except:
      read_err_cnt += 1

然后致电:

clean_words(some_bad_text)

我明白了:

UnboundLocalError: local variable 'read_err_cnt' referenced before assignment'

如果事实上变量' read_err_cnt'不是本地人吗?

2 个答案:

答案 0 :(得分:0)

是的,你只需在函数内添加global read_err_cnt即可。 如下修改给定代码,只是为了演示。 然后它可以解决错误。

示例:

read_err_cnt = 0
def clean_words(text):
    #global read_err_cnt
    tokenizer = [1,2,3,4,5]
    try:
        for word in tokenizer:
            yield word
    except:
        read_err_cnt += 1

obj = clean_words("hesfsfsdfsdafsdf sdafdsa fdsaf dsfsd")

print obj.next()

给了我错误:

Exception UnboundLocalError: "local variable 'read_err_cnt' referenced before assignment" in <generator object clean_words at 0x7fb8988231e0> ignored

global read_err_cnt添加到功能后。它运作得很好。

In side function it is trying to assign value, or change a value, immediately that variable will become local.尝试增加之前不存在的变量。为了避免使用全局关键字。

使用全局关键字后,如果代码尝试引用全局变量,则在函数内部,赋值只是起作用,因为变量已经存在。

答案 1 :(得分:0)

问题在于,如果为函数内的变量赋值,则会创建局部变量。这将遮蔽外部作用域中具有相同名称的任何变量。

在你的情况下:

ItemsControl

相当于:

<Grid Grid.Row="1" Background="Purple" Grid.IsSharedSizeScope="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
        <ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.ColumnSpan="2" >
        <ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"                               
                      Background="Yellow" 
                      Grid.IsSharedSizeScope="True">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Background="Green">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="Labels"/>
                            <ColumnDefinition SharedSizeGroup="InputControls"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Path=Label}" 
                               Grid.Column="0" 
                               Margin="5"
                               VerticalAlignment="Center"/>
                        <TextBox Text="{Binding Path=Name}"  
                             Grid.Column="1" 
                             Margin="5"
                             VerticalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

    <!--<TextBlock Text="Invoice Number" Grid.Column="0" Margin="5" VerticalAlignment="Center"/>
        <TextBox Text="InvoiceNumber" Grid.Column="1" Margin="5" VerticalAlignment="Center"/>-->
</Grid>

read_err_cnt += 1 部分告诉Python您要创建一个名为read_err_cnt = read_err_cnt + 1 的(本地)变量。但是,在同一行中,您希望从外部作用域访问read_err_cnt =变量。这根本不可能,因为局部变量会影响&#34;外部&#34;变量

有几种方法可以解决此问题,例如在函数中使用read_err_cnt,告诉Python您要访问并修改全局read_err_cnt变量。但是您也可以在全局范围中使用可变类型,并使用该对象的方法来修改状态:

global read_err_cnt