类命名空间和对象/实例命名空间:
创建类, 就会创建一个类的名称空间, 空间:存储类的属性
属性:
- 静态属性:直接定义在类下面 & 和类名关联 的变量
- 对象属性:在类内和self关联 & 类外和对象关联 的变量
- 动态属性:方法(函数)
内存空间的指向:
class Foo: a = 1 b = ['big'] def __init__(self): pass f1 = Foo() print(f1.a) # 1 f1.a = 2 # '=' 断开了类的指针,内存地址不在指向类中的a (从内存层面讲) , 指向了新开辟的空间 # 对象修改类的不可变数据类型,,只是赋值在对象自己的空间里增加一个新属性 print(f1.a) # 2 print(f1.b) # ['big'] f1.b.append('small') #没有断开,只是指向的列表append() # 对象修改可变数据类型,全局生效 print(f1.b) # ['big', 'small']
========
class Foo: def func(self): return 100 f = Foo() print(f.func()) f.func = 1 #修改成1, 对象自己创建了一个变量名是func = 1 的东西 print(f.func) #f.func 没有括号,是对象调用属性 print(Foo.func(f)) #如果还想用 100, 可以用类名.方法,self参数必须传进去一个对象
================
例子:统计类被调用的次数
class Foo: count = 0 def __init__(self): Foo.count += 1 f = Foo() print(f.count) #1 Foo.count f2 = Foo() print(f2.count) #2 Foo.count f3 = Foo() print(f3.count) #3 Foo.count f = Foo() f2 = Foo() f3 = Foo() print(f.count) # 3 Foo.count print(f2.count) # 3 Foo.count print(f3.count) # 3 Foo.count
===============================
题外:
class Foo: count = 0 def __init__(self): Foo.count += 1 def func(self): a = 3 f = Foo() print(Foo.func) #<function Foo.func at 0x0000000001E68950> print(f.func) 两个内存地址是不一样的,(因为bound绑定到对象,有个类的指针指向类的方法,不是直接去拿) #<bound method Foo.func of <__main__.Foo object at 0x0000000001E67B38>>
================
命名空间:
- 静态属性: 属于类内部的命名空间
- 动态属性: 属于类内部的命名空间
- 对象属性: 属于对象的,在类内关联self ,类外关联对象名
查看静态属性: 类名.属性 对象.属性
调用类中的方法: 类名.方法名(传对象) ,对象.方法名()
对象能找到类,类找不到对象,单线联系
对象查找属性,现在自己空间找,找不到再去类空间去找