面向对象命名空间、组合

时间:2022-12-15 21:57:17

一 类命名空间与对象、实例的命名空间

创建一个类就会创建一个类的名称空间,用来存储类中定义的所有名字,这些名字称为类的属性

而类有两种属性:静态属性和动态属性

  • 静态属性就是直接在类中定义的变量
  • 动态属性就是定义在类中的方法

 

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)#用结构化年份-生日年份等于年龄

面向对象命名空间、组合