最好别让类变量和成员变量具有相同的名字, 以区别。:这应该是最好的解决方案
== 无论是对于任何变量、在内层变量未重新赋值的前提下,可以将外层变量的值优先赋值给同名的局部变量==
== 全局变量具有==
1 入侵性 可入侵赋值给局部变量
2 可阻拦性 可被内部赋值阻拦
函数(局部、全局)
通常函数中的变量就可以认为是程序中的局部变量
我们可以将每个函数都是一个工厂,至于工厂中发生了什么我们是不用关心的
函数的调用->执行性质 决定了其存在的独立性。
通常情况下这种隔离不会被打破(在函数中定义global变量除外、一般情况下们也不会在自己的程序中加入这种易乱的变量)
非常规情况
1:代码如下
if __name__== '__main__':
a = [1]
def test():
a.append(2)
if __name__ == '__main__':
print(a, id(a))
test()
print(a, id(a))
result:
[1] 140681844497672
[1, 2] 140681844497672
这里可以明显看到全局变量被局部变量给修改了
if __name__== '__main__':
a = 1
def test():
global a
a += 1
def test_1(a):
a += 5
print(a)
if __name__ == '__main__':
print(a, id(a))
test()
print(a, id(a))
test_1(2)
print(a, id(a))
result:
1 94409945545248
2 94409945545280
7
2 94409945545280
if __name__== '__main__':
a = 1
b = 3
def test():
a = b+1
def test_1(a):
a += 5
print(a)
if __name__ == '__main__':
print(a, id(a))
test()
print(a, id(a))
test_1(2)
print(a, id(a))
result:
1 94409945545248
1 94409945545248
7
1 94409945545248
产生上述两种不同的根本原因如下
链接: link
类(类变量、成员变量)
类在一定程度上自成体系,自己定义了一个小型生态圈;类是一种可以含有函数工厂的生态圈。
函数只是类的方法
类变量可以看成类生态圈中的全局变量
成员变量可以看成是方法中的局部变量
与函数中的局部变量和全局变量的关系类似:
In [109]: class A:
...: a = [1]
...: b = 1
...:
...:
...: def test(self):
...: self.a.append(2)
...: self.b += 2
...:
In [110]: A.a
Out[110]: [1]
In [111]: A.b
Out[111]: 1
In [112]: a = A()
In [113]: a.a
Out[113]: [1]
In [114]: a.b
Out[114]: 1
In [115]: a.test()
In [116]: a.a
Out[116]: [1, 2]
In [117]: a.b
Out[117]: 3
In [118]: A.a
Out[118]: [1, 2]
In [119]: A.b
Out[119]: 1
In [120]: b = A()
In [121]: b.a
Out[121]: [1, 2]
In [122]: b.b
Out[122]: 1
In [123]: A.a
Out[123]: [1, 2]
In [124]: A.b
Out[124]: 1
In [125]: b.test()
In [126]: b.a
Out[126]: [1, 2, 2]
In [127]: b.b
Out[127]: 3
In [128]: A.a
Out[128]: [1, 2, 2]
In [129]: A.b
Out[129]: 1
由于a.append函数并不改变变量a指向的内存地址,而是改变内存地址中的值(相当于在a所指的内存地址中的原值进行操作即对[]进行操作)
改变这种不同实例之间存在的相互影响最好事先进行初始化:即使用 init() 函数
In [34]: class A:
...: x = []
...: y = 0
...: def __init__(self):
...: pass
...: def add(self):
...: self.x.append('1')
...: self.y+=1
...: a=A()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: a.add()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: b=A()
...: print (b.x,b.y)
...: print (A.x,A.y)
[] 0
[] 0
['1'] 1
['1'] 0
['1'] 0
['1'] 0
不同实例之间相互干扰;如何接解决
In [35]: class A:
...: x = []
...: y = 0
...: def __init__(self, x=[], y=0):
...: self.x = x
...: self.y = y
...:
...: def add(self):
...: self.x.append('1')
...: self.y+=1
...: a=A()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: a.add()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: b=A()
...: print (b.x,b.y)
...: print (A.x,A.y)
[] 0
[] 0
['1'] 1
[] 0
['1'] 0
[] 0
未解决
继续…
In [50]: class A:
...: x = []
...: y = 0
...: def __init__(self, x=[], y=0):
...: self.x = x
...: self.y = y
...:
...: def add(self):
...: self.x.append('1')
...: self.y+=1
...: a=A()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: a.add()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: b=A([], 0)
...: print (b.x,b.y)
...: print (A.x,A.y)
[] 0
[] 0
['1'] 1
[] 0
[] 0
[] 0
解决->通过重新初始化赋值, 所以最好使用位置不赋值
In [51]: class A:
...: x = []
...: y = 0
...: def __init__(self, x, y):
...: self.x = x
...: self.y = y
...:
...: def add(self):
...: self.x.append('1')
...: self.y+=1
...: a=A([], 0)
...: print (a.x,a.y)
...: print (A.x,A.y)
...: a.add()
...: print (a.x,a.y)
...: print (A.x,A.y)
...: b=A([], 0)
...: print (b.x,b.y)
...: print (A.x,A.y)
[] 0
[] 0
['1'] 1
[] 0
[] 0
[] 0
事实上In[35]未能解决是忽略了---------- 这里 ------------ 的改变
In [54]: def test(a=1, b=[]):
...: a += 1
...: b.append(2)
...:
...: print(a, b)
...:
In [55]: test()
2 [2]
In [56]: test()
2 [2, 2]
In [57]: test()
2 [2, 2, 2]
In [58]: test()
2 [2, 2, 2, 2]
In [59]: test()
2 [2, 2, 2, 2, 2]
In [60]: test()
2 [2, 2, 2, 2, 2, 2]
In [73]: class Test(object):
...: ss = 9
...: cc = 59
...: def __init__(self):
...: self.ss = self.ss
...: self.cc = self.cc
...: @classmethod
...: def class_m(cls):
...: cls.ss += 1
...: cls.cc += 3
...: return cls.ss, cls.cc
...: @classmethod
...: def class_m_m(cls):
...: cls.ss += 9
...: cls.cc += 19
...: return cls.ss, cls.cc
...: def traditional_m(self):
...: print(self.ss, self.cc)
...: self.ss = self.ss*2
...: self.cc = self.cc*2
...: return self.ss, self.cc
...:
In [74]: Test.cc
Out[74]: 59
In [75]: Test.ss
Out[75]: 9
In [76]: t = Test()
In [77]: t.traditional_m()
9 59
Out[77]: (18, 118)
In [78]: t.ss
Out[78]: 18
In [79]: t.cc
Out[79]: 118
In [80]: t.class_m()
Out[80]: (10, 62)
In [81]: Test.cc
Out[81]: 62
In [82]: Test.class_m_m()
Out[82]: (19, 81)