关于python类方法可以统改实例属性,代码如下:
class date:
def __init__(self):
print("date被创建")
def cx(self,x):
print("cx被调用")
date.x = x
def cs(self,s):
print("cs被调用")
self.s = s
dt0 = date()
dt1 = date()
dt0.cx(10)
dt0.cs(10)
print(dt0.x,dt0.s)
dt1.cx(50)
dt1.cs(50)
print(dt1.x,dt1.s)
print(dt0.x,dt0.s)
#date.s = 100
print(dt0.s,dt1.s)
date.cs(date,100)
print(dt0.s,dt1.s)
print(date.s)
输出如下:
date被创建
date被创建
cx被调用
cs被调用
10 10
cx被调用
cs被调用
50 50
50 10
10 50
cs被调用
10 50
100
问题描述:
从输出来看,执行d1.cx会将所有date实例的属性x修改(甚至没有x属性的date实例也会被赋予x属性),因为cx方法定义中是用date.x来修改x属性而不是self.x修改属性,所以任意date实例调用cx方法将统改所有已创建date实例的x属性,这点可以理解。
但是后面这段
date.cs(date,100)
它的执行就不能理解了,由后面输出可以看到,这里没有创建新的date实例,也没有统改所有date实例的s属性,但输出date.s却可以输出,也就是这段代码单独创建了了一个date.s,这里我非常不理解,这个date.s该如何解释呢?
不要把 python 的成员方法想的规范很多,其实 python 的成员方法是很宽松的,你这里其实就是用了 python 成员方法的最泛用形式。
虽然方法 cs()
是定义在 date
类里,但是 cs()
实际上也是一个常规的函数,只不过定义在类里面作为类成员,可以当作语法糖。
可以说,dt0.cs(10)
在 python 的实际执行中,就是相当于 date.cs(dt0, 10)
。可以看到这其实就是把语法糖展开了,只不过你用 dt0.cs(10)
这样写法的时候,他会帮你把成员函数定义里的 self
自动替换为 dt0
罢了。
而且从你这个例子可以发现,实际上 self
是什么,完全取决你给这个函数传入什么。你最后用 date.cs(date, 100)
,就是把 date
当作了 self
,又多亏于 python 的类型几乎没有限制,所以结果就变成了给 date
增加了一个 date.s
属性罢了。
python是弱类型的编程语言
date.cs(date,100)
你把date当self传进函数里
那么实际执行的就是date.s=100
你再去访问date.s它当然就是100了呀
你这是给date增加了一个静态属性s