我有使用命令式语言的经验(最常见的是 C),这可能就是我在学习 python 时感到困惑的原因。
我正在尝试实现一个简单的按位标志设置函数。所以在 C 中它会像:
void set_state(int *state, int var, int set)
{
(set)? *state |= var : *state &= ~var
}
int is_state(int *state, int var)
{
return (*state & var > 0)
}
int *state 是指我跟踪的状态标志,var 是我想设置或清除的标志(由 int set 决定)。
所以我尝试用 Python 3.2 和...做同样的事情
def setState(nState, nVar, bSet):
if bSet:
nState |= nVar
else:
nState &= ~var
print(nState)
然后我跑...
>>> state
1024
>>> nfirst
1
>>> nsecond
2
>>> setState(state, nfirst, True)
1025
>>> state
1024
调试器告诉我“state”的值被复制到 nState 中,现在 nState 自己发生了变异(这意味着它在自己的本地范围内发生了变化)。 Python 不就是关于对象和一切都是通过引用调用的吗?
如果是这样,为什么我看不到副作用?
我迷路了。谁能解释一下这里发生了什么。
请您参考如下方法:
Python int 是不可变的,因此在传入引用时,不可能更改 int 对象的值。如您所见,局部变量是引用的副本,因此它们都绑定(bind)到同一个整数。但是,当您更改局部变量的值时,会创建一个新的整数对象,并将局部变量重新绑定(bind)到新对象。
例如。
>>> def setState(nState, nVar, bSet):
... print((nState, id(nState)))
... if bSet:
... nState |= nVar
... else:
... nState &= ~var
... print((nState, id(nState)))
...
>>> nState = 1024
>>> nState, id(nState)
(1024, 3077840368)
>>> setState(nState, 1, True)
(1024, 3077840368) # local nState is bound to the same object
(1025, 3077840448) # now the local nState is bound to the new `int` object
也许您可以从函数返回 nState 并将其赋值回来,例如
>>> def setState(nState, nVar, bSet):
... if bSet:
... nState |= nVar
... else:
... nState &= ~var
... return nState
...
>>> nState = 1024
>>> nState = setState(nState, 1, True)
>>> nState
1025
