关于python:增加实例属性与增加全局属性(范围)

Incrementing an intstance attribute vs incrementing global attributes (scope)

本问题已经有最佳答案,请猛点这里访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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有什么不同?对我来说,这些例子很相似,但一个失败了,一个没有。尽管这个对象在全局范围内,类似于x的第二个示例,但我们在blahinstance.x的赋值前没有引用错误。

为了澄清-我完全理解第二个例子,以及全局与局部范围。我不明白的是为什么第一个会起作用,因为它看起来和第二个相似。这是因为实例对象及其属性是可变的,并且我们在本地范围内对全局具有读取/修改访问权限吗?


裸名称不同于属性引用。

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

"分配前引用的局部变量"业务仅在分配给变量(即裸名称)时才起作用,而不是属性引用、项引用或其他任何内容。在这方面,blahinstance.x += 2somelist[1] += 2没有区别;在第一种情况下,x与在第二种情况下,1指数不再是局部变量。