python中用类名.类方法方式调用类方法,其中self参数传入类名

关于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