一 类命名空间与对象、实例的命名空间
创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性
而类有两种属性:静态属性和动态属性
- 静态属性就是直接在类中定义的变量
- 动态属性就是定义在类中的方法
class Person: Country = '中国人' # 静态变量 print(Person.Country) alex = Person() # 创建了一个空的命名空间 alex.name = 'alex' # 对象 alex.Country = '泰国人' egon = Person() egon.name = 'egon' # 类名.静态变量 对象.属性名 # 类名可以调用对象的属性么? 不可以 # 对象可以调用类中的属性么? 可以 print(Person.Country)#中国人 print(alex.Country)#泰国人 print(egon.Country)#中国人 # 由于对象和类之间存在一个关联关系 # 所以对象能够找到类 # 但是 类不能找到对象 # # 使用类名.属性 只会寻找类中的静态变量名字 # 使用对象.属性 会现在对象自己的命名空间中找名字 # 如果找不到 再到类的内存空间中去找
其中类的数据属性是共享给所有对象的
>>>id(egg.role) 4341594072 >>>id(Person.role) 4341594072
而类的动态属性是绑定到所有对象的
>>>egg.attack <bound method Person.attack of <__main__.Person object at 0x101285860>> >>>Person.attack <function Person.attack at 0x10127abf8>
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
class Person: money = 0 mother = Person() father = Person() Person.money += 1000#类的静态属性等于1000 Person.money += 1000#类的静态属性等于2000 print(Person.money)#类的money属性等于2000 print(mother.money)#妈妈调用类的money等于2000 print(father.money)#父亲调用类的money属性也等于2000
class Person: money = [0]#类的money的命名空间有一个列表,列表里是0 mother = Person()#妈妈开通一个空的命名空间 father = Person()#父亲开通一个命名空间 mother.money[0] += 1000#妈妈的命名空间里创建一个列表,列表里第一位索引等于1000元 father.money[0] += 1000#父亲的命名空间里创建一个列表,列表里第一位索引等于2000元 print(Person.money)#2000 print(mother.money)#2000 print(father.money)#2000
class Person: money = [0] mother = Person() father = Person() mother.money = [1000]#妈妈的money属性赋予新变量[1000] father.money = [2000]#爸爸的money属性赋予新的变量[2000] print(Person.money)#对象的money属性无法改变,类的money属性[0] print(mother.money)#直接打印妈妈的新的变量属性[1000] print(father.money)#直接打印爸爸的新的变量属性[2000]
面向对象的组合用法
软件重用的重要方式除了继承之外还有另外一种方式,即:组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
# 组合 两个类的事儿 # 什么叫组合 : 一个类对象的属性 是 另外一个类的对象 # 两个类的事儿 :类与类之间有一种"什么有什么的关系"
圆的类
圆环 和 圆
圆环 也是一个类
属性 大圆半径 和 小圆半径
圆环 求面积 求周长
# 圆环 from math import pi class Circle:#创建一个圆的类 def __init__(self,r):#初始化圆的对象,定义一个半径r self.r = r def area(self):#圆的面积 return pi*(self.r**2) def perimeter(self):#圆的周长 return 2*pi*self.r c1 = Circle(5)#c1是半径为5的圆#实例化 #c1.perimeter()#对象的调用周长属性 class Ring:#创建一个同心圆 def __init__(self,outer,inner):#初始化同心圆的外环,内环 self.outer = Circle(outer) # 组合Ring的属性是,Circle类的实例化对象 self.inner = Circle(inner)# 组合Ring的属性是,Circle类的实例化对象 def area(self):#圆环的面积等于外环的面积➖内环的面积 return self.outer.area() - self.inner.area() def perimeter(self):#圆环的周长等于外环的周长+内环的周长 return self.outer.perimeter() + self.inner.perimeter()
老师 name sex course(课程) birth
生日 年月日
class Birthday:#生日类 def __init__(self,year,month,day):#初始化对象 self.year = year#生日类(被传入的对象)的年属性 self.month = month#生日类的月属性 self.day = day#生日类的日属性 class Teacher:#教师类 def __init__(self,name,sex,course,birth):#初始化对象 self.name = name#教师类(对象)的name属性 self.sex = sex#教师的sex属性 self.course = course#教师的course的属性 self.birth = birth # birth是一个对象 birth = Birthday(1960,3,7) # birth 是Birthday类的一个对象 alex = Teacher('alex','male','python',birth)#Alex对象传入一个birth属性 # alex.birth = birth # # time # '1960-3-7' # # 老师的年龄 2018 - 1960 # print(birth) # import time # if birth.month == time.localtime().tm_mon and \ # birth.day == time.localtime().tm_mday: #如果调用birth类的月属性等于结构化时间的月,日属性等于结构化时间的日 # print('生日快乐')#打印生日快乐 # print(time.localtime().tm_year - birth.year)#用结构化年份-生日年份等于年龄