【问题标题】:Incrementing an intstance attribute vs incrementing global attributes (scope) [duplicate]增加实例属性与增加全局属性(范围)[重复]
【发布时间】:2014-08-25 19:25:31
【问题描述】:
class blah(object):
  def __init__(self):
    self.x=5

blahinstance=blah()

def testclass():
  blahinstance.x+=1
  print blahinstance.x

testclass()  #blah will be incremented

print blahinstance.x #the incremented value holds after function exit
"------------------------------------------------------------------------------------"

x=5

def test():
  x+=1
  print x

print x
test() #fails because ref before assignemnt

所以我们在局部范围内拥有对全局变量的读取权限和修改权限,但显然尝试重新分配只会创建一个与全局变量同名的局部变量。在上面的示例中,引用函数范围之外的实例属性blahinstance.x 有什么不同?对我来说,这些例子非常相似,但一个失败,一个没有。尽管该对象在全局范围内,但我们在 blahinstance.x 的赋值错误之前没有 ref,类似于 x 的第二个示例。

澄清一下 - 我完全理解第二个示例,以及全局与本地范围。我不明白为什么第一个有效,因为它看起来与第二个相似。是因为实例对象和它的属性是可变的,而且我们在本地范围内可以读取/修改全局变量吗?

【问题讨论】:

  • 您基本上遇到了与此问题中描述的相同的问题:Python globals, locals, and UnboundLocalError。我知道在某个地方有更好的骗局,我就是找不到。
  • 这无关。我已经说过,我了解本地范围已读取和修改(用于可变)对全局变量的访问。也许我的问题不清楚?还是因为实例对象及其属性是可变的,就像列表或字典一样,而整数不是?也许这是我不明白的,实例是可变的?
  • x(一个整数)是不可变的。

标签: python scope instance local


【解决方案1】:

裸名不同于属性引用。

没有名字blahinstance.x。有一个名字blahinstance,它所指的对象有一个属性叫x。当您执行blahinstance.x += 2 之类的操作时,您引用的唯一变量是blahinstance,并且您没有为blahinstance 分配新值,所以一切都很好。在blahinstance.x 中使用x 完全是blahinstance 的“内部”,而x 根本不是一个真正的变量,它只是一个属性名称。

“分配前引用的局部变量”业务仅在您分配给变量时才起作用——即,一个裸名——而不是属性引用、项目引用或其他任何东西。在这方面blahinstance.x += 2somelist[1] += 2 没有什么不同;第一种情况下的x 与第二种情况下的索引1 一样,不再是一个局部变量。

【讨论】:

    猜你喜欢
    • 2017-09-15
    • 2022-11-14
    • 2018-01-13
    • 2013-05-08
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多