类命名空间与对象、实例的命名空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法
对于类的静态属性和方法不同操作发生的效果
#·类名操作变量 不管操作可变还是不可变数据类型 都是类中对应的变量发生变化
#对象名操作静态变量
#引用变量:现在自己的命名空间中查找,找不到就去类的命名空间找
#修改变量:
# 如果是对可变数据类型中的元素进行修改,那么全局生效
#如果对可变数据类型,断开并指向新的数据类型,那只是对象自己的静态属性发生变化
# 如果是对变量进行重新赋值,那么只是在对象自己的命名空间里增加了一个新的属性
# 结论:应该尽量用类名去使用静态变量
# 设计一个类,统计这个类被实例化的次数,且所有的对象共享这个属性
class Foo: country='中国' country_list=['china'] def __init__(self,name): self.name=name f1=Foo('alex') f2=Foo('jinxing') f1.country='印度' #当我在对象中操不可变类型的作静态变量时,只是类自己中的静态变量发生变化 print(f1.country) #印度 print(f2.country) #中国 print(Foo.country) #中国 Foo.country='美国' #当在类中操作不可变类型的静态变量时,对象的静态变量都会发生变化, print(Foo.country) # 美国 print(f1.country) #印度 #除了这个在上边已经单独对对象的静态属性进行改变的 print(f2.country)# 美国 f1.country_list.append('韩国') #在对象中操作可变类型的静态属性时,当对其增删改时 # ,整体都会发生变化 print(f1.country_list)#['china', '韩国'] print(Foo.country_list) #['china', '韩国'] f2.country_list=[] #这个是将f2.country_list断开可原来的指向,指向了另外一个新的列表 print(f2.country_list)#[] #得到的结果是 print(Foo.country_list) #['china', '韩国']
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
面向对象的组合用法
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用
class Squear: #先定义一个类 def __init__(self,radius): self.radius=radius def squear(self): # 在类中有关于他面积的动态属性, return 3.14*(self.radius**2) def perimeter(self): return self.radius*2*3.14 class Ring: def __init__(self,r1,r2): #在这里是将其他类中的对象当作此类中的数据来引用 self.a1=Squear(r1) self.a2=Squear(r2) def squear_ring(self): return self.a1.squear()-self.a2.squear() #在这里可以直接调用调用过来的 # 对像的属性来进行相印的计算和操作的 def perimeter_ring(self): return self.a1.perimeter()+self.a2.perimeter() w3=Ring(30,10) print(w3.squear_ring()) #2512.0 计算出圆环的面积 print(w3.perimeter_ring()) #计算出圆环的周长