[英]Python static variable in function global name not defined
I have written a function to calculate the heading between two points only if a vehicle reports that it's moving and that the vehicle has moved 20cm between points. 我编写了一个仅在车辆报告正在行驶并且车辆在两点之间移动20cm时才计算两点之间的航向的函数。
The function uses static variables - or at least it would if it worked - to keep track of previous positions and heading values. 该函数使用静态变量-或至少可以使用它-跟踪先前的位置和航向值。
Here is the code: 这是代码:
def withCan(pos):
eastdist = pos[0]-previous_pos[0]
northdist = pos[1]-previous_pos[1]
canflag = pos[2]
if (canflag == 1 or canflag==2):
if (previous_canflag == 1 and canflag == 2):
previous_heading += 180.0
previous_canflag = canflag
elif (previous_canflag == 2 and canflag == 1):
previous_heading += 180.0
previous_canflag = canflag
else:
previous_canflag = canflag
if ( (canflag == 1 or canflag == 2) and math.sqrt(northdist*northdist+eastdist*eastdist) > canstep ):
previous_heading = math.degrees(math.atan2(eastdist, northdist))
previous_pos[0] = pos[0]
previous_pos[1] = pos[1]
return previous_heading
withCan.previous_pos = [0.0,0.0]
withCan.previous_heading = 0.0
withCan.previous_canflag = 0
withCan.canstep = 0.2
positions = backandforth([100,100]) #populates an array of form [x,y,canflag]
for p in positions:
print withCan(p)
I am getting an error that says eastdist = pos[0]-previous_pos[0] NameError: global name 'previous_pos' is not defined
. 我收到一条错误消息,说
eastdist = pos[0]-previous_pos[0] NameError: global name 'previous_pos' is not defined
。 Please could someone explain the cause of this error? 请有人可以解释此错误的原因吗?
When you do this: 执行此操作时:
def foo():
pass
foo.name = 1
You are not creating a global name name
. 您没有在创建全局名称
name
。 Instead you are adding a property to the foo
function! 相反,您是向
foo
函数添加属性! You can access it with: 您可以通过以下方式访问它:
def foo():
return foo.name
foo.name = 1
But that is quite weird. 但这很奇怪。 If you need a global name, just do it:
如果您需要一个全局名称,请执行以下操作:
def foo():
global name
name += 1
return name
name = 1
Remember that if you want to modify the global name from the function, you have to declare it as global
. 请记住,如果要从函数中修改全局名称,则必须将其声明为
global
。 If you fail to do this, you can use it but you cannot assign to it. 如果无法执行此操作,则可以使用它,但不能分配给它。
Your confusion with static names may come from using classes. 您对静态名称的困惑可能来自使用类。 But note that in your code
withCan
is not a class, it is a plain function! 但是请注意,在您的代码中
withCan
不是一个类,它是一个普通函数!
It looks like what you are trying to do is writing a class... 您似乎正在尝试写一门课...
class WithCan():
def __init(self, previous_pos)__:
self.previous_pos=previous_pos
def withCan(self, pos):
# your function as class method
Then you could initialize an instance 然后您可以初始化一个实例
withCan=WithCan(previous_pos)
and access it 并访问它
withCan.previous_pos=...
You can do static variables in Python using function attributes, but you need to use the full name inside the function to access those attributes. 您可以使用函数属性在Python中执行静态变量,但是您需要使用函数内部的全名来访问这些属性。
Here's a short demo. 这是一个简短的演示。
def test(a):
print a, a + test.b
test.b += 1
test.b = 5
test(3)
test(10)
output 输出
3 8
10 16
However, it would be more usual to do this sort of thing using a class, as shown in Tim's answer. 但是,如蒂姆的回答所示,使用类来进行此类操作会更常见。
Another way to do statics in Python is to give your function default mutable arguments, but many people are uncomfortable with that. 在Python中执行静态操作的另一种方法是为您的函数提供默认的可变参数,但是许多人对此感到不舒服。 But if you're curious, please see “Least Astonishment” in Python: The Mutable Default Argument .
但是,如果您感到好奇,请参阅Python:Mutable Default Argument中的“最小惊讶” 。
Let me contribute a perhaps more streamlined way of emulating static variables in functions that could make the OP's example maybe easier to read: 让我为在函数中模拟静态变量的一种可能更简化的方式做出贡献,这可能会使OP的示例更易于阅读:
def with_can(pos):
if not hasattr(with_can, "canflag"):
# set up and initialise the static variables
with_can.canflag = 0
with_can.previous_pos = [0.0,0.0]
with_can.previous_heading = 0.0
with_can.canstep = 0.2
# ... use them ...
eastdist = pos[0]-with_can.previous_pos[0]
# ... etc ...
Basically at the first invocation we detect that one of the "static" variables ( canflag
) is not yet there so we add and initialise all of them. 基本上,在第一次调用时,我们检测到“静态”变量(
canflag
)尚不存在,因此我们添加并初始化了所有变量。 After that they can be used as indicated. 之后,可以按照指示使用它们。
However, as others have pointed out already, it is much better to write a class with data members instead of these "static" function variables. 但是,正如其他人已经指出的那样,编写一个带有数据成员的类而不是这些“静态”函数变量要好得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.