一 类的名称空间:
类中的代码在什么时候执行的? 在实例化之前,也就是说在创建一个类时,类自己先给自己创建
建一块空间,也就是公共的空间.(里面会把静态变量和__init__及方法方进去)
类中代码执行顺序:(在实例化之前就执行了)
问题:一个类中可不可以没有__init__? , 在没有的情况下实例化经历了哪些步骤
答案: 可以 , (1,创建一个空间给对象,将这个空间的地址返回)
class A:# Country = 'China' #静态属性# def __init__(self,name):# self.name = name# def talk(self):# print('%s is talking'%self.name)
上代码中: A.Country='abc' # 修改静态属性 将其改为'abc'
del A.Country # 删除静态属性 此时打印会报错
print(A.__dict__) # 查看静态属性
类的名称空间中有什么?
静态属性和动态属性(方法)
2 对象的命名空间和类的命名空间之间的关系:
对象和类之间有一个单向的联系,类对象指针
对象在使用某个名字的时候,先在自己空间里找,没有就会去类空间去找.
class A:# Country = 'China'# def __init__(self,name):# self.name = name# def talk(self):# print('%s is talking'%self.name)## alex = A('alex')# baoyuan = A('baoyuan')# print(alex.Country) # 'China' # 用的是静态属性自己里没有找的类的# alex.Country = '泰国' # 自己创建了个Country属性 名为泰国# print(alex.Country) # '泰国' 自己的# del alex.Country # 删除自己的属性# print(alex.Country) # 'China' # 又找的类的# print(A.Country) # china # 静态属性类的# print(baoyuan.Country) # china # 也是用的类的
因此 对象可以查看类的静态属性,但不能修改(修改相当于给自己创建了一个,此时你要想再用类中的
静态方法,除非删除刚刚创建的),所以静态属性的修改,都应该用类名来完成.
因此得出 : 静态属性就是用来描述所有对象都共同的某一个值.
小例子:
# class People: money = 1000# def salary(self):# People.money += 1000 # 这里只能用类名去修改他 ,如果用对象自己那相当于私房钱了 没有汇总 # mother = People()# father = People()# mother.salary()# father.salary()# print(People.money,mother.money,father.money)
静态属性 再看一个例子:
class B:# l = []# def __init__(self,name):# self.l.append(name) # self.l=[name] 下面所说的第三种情况## alex = B('alex')# baoyuan = B('宝元')# print(B.l) #['alex', '宝元']# print(alex.l)# print(baoyuan.l
1 如果静态变量是一个不可变数据类型,那么只要对象修改这个数据,就相当于在对象的空间中新建
2 如果静态变量是一个可变数据类型,那么对象修改这个容器中的元素,相当于修改类的空间中的元素
3 如果静态变量是一个可变数据类型,那么对象直接对这个变量重新赋值,相当于修改对象自己空间中的元素
大结论 # 只要是静态变量,就用类名去修改,永远修改成功,并且所有的对象都共享这个改变
# 总结 # 对象的命名空间:类指针\对象的所有属性 # 类的命名空间:方法和(静态属性\字段) # 对象在寻找名字的时候 : 先找对象自己内存空间中的,找不到就去类的命名空间中寻找 # 类中的名字是什么时候写入内存的 : 代码从上到下执行的时候就已经写入的.一定是在实例化之前 # 静态变量 : 尽量用类名去操作
二 组合(一个类对象的属性是另外一个类的对象) 先说下组合的特点:
组合指得是,在一个类中以另一个类的对象作为数据属性,称为组合 作用是可以将两个本来不相关的类联系起来,一般两个类之间有显著的不同,很多时候还要附属关系(有相同的属性也有不同的属性 ).比如人和头,手机和电池等 无纵向关系时用组合,有纵向关系用继承 组合就是一个类中使用另一个类,从而把几个类拼到一起,也为了减少代码
看两个例子吧: 1(这是算一个圆环的面积和其周长)
from math import pi # 数学模块 用到 πclass Yuan: def __init__(self,r): self.r=r def mianji1(self): return pi *self.r**2 def zhouchang(self): return 2*pi*self.rclass Huan: def __init__(self,R,r): a=Yuan(R) b=Yuan(r) self.a=a self.b=b def mianji(self): return self.a.mianji1()-self.b.mianji1() # 相当于调了上个类的对象 让他去执行 def zhouchang(self): return self.a.zhouchang()+self.b.zhouchang()zo=Huan(6,2)print(zo.mianji())print(zo.zhouchang()) # 总体来说 把下面的参数传给上一个对象,让他去计算下面只要个结果,可以这么理解(上面是专门 做复杂运算的,我把参数直接传给上面让其帮我运算) # 一个类对象的属性是另类的对象
例子2
年月日的类
student类
class Birthday: # 生日类 def __init__(self,yaer,moth,day): # 生日信息 self.yaer=yaer self.moth=moth self.day=day# a=Birthday()class Student: # 学生类 def __init__(self,name,sex,birthday): self.name=name self.sex=sex self.birthday=birthdaybirthday=Birthday(1991,2,2)b=Student('张三','不详',birthday)print(b.birthday.yaer)