python 中缺乏一致性,函数前定义变量的行为完全矛盾

Lack of consistency in python, completely contradictory behaviour of defined variables before function

我快疯了,因为我的代码正在执行完全矛盾的操作。 我在定义函数 custom_action 之前将 packet_counts 定义为 Counter() 并且没有问题。当我尝试以与 packet_counts 完全相同的方式将 test1 定义为 int 时,它表示 custom_action 内的 test1 未定义。 多么缺乏一致性。 你们能给我解释一下哪里出了问题吗?

我用 global 试过,结果相同。我无法在函数内部定义 test1,因为它必须使用 scapy 收集捕获的数据包的大小,如果我这样做,它会在每次调用时重置。

from collections import Counter

test1=0
packet_counts = Counter()
def custom_action(packet):
    key = tuple(sorted([packet[0][1].src, packet[0][1].dst]))
    packet_counts.update([key])
    packetSize = len(packet)
    test1 += packetSize              #here occurs error that test1 is undefined...

函数中任何赋值的名称都是隐式本地的;如果您只读取一个名称,它将从最近的包含该变量的范围读取。

test1 += packetSize  

既是读取又是赋值,使 test1 成为本地的,但是由于事先没有为它赋值,所以你得到一个 UnboundLocalError (因为你实际上只是想说 test1 = ??? + packetSize).

要写入变量而不使其成为本地变量,请添加:

global test1

nonlocal test1

作为函数的第一行。 The former explicitly jumps to global scope, the latter looks for it in the nearest enclosing scope(在这种情况下,它们是等价的)。

请注意,通常需要 global 语句的代码通常是错误的形式;这通常是一个线索,表明您应该使用 class 的实例,函数是 class 上的一个方法(每个实例都可以保留自己的状态,而不是只有一个全局状态).

Python 将允许您在函数内部读取和修改全局范围内的变量,但是一旦您 向其分配 一个新值,它就会分配在函数的本地范围内。见 https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value:

"当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并隐藏外部作用域中任何类似命名的变量"。

要改为分配给全局范围,请在函数开头使用以下行:

global test1