面向对象操作

静态属性,静态方法,组合,继承,衍生,继承之mro线性顺序列表,面向对象综合实例

1.静态属性(附有装饰器)

class Room:
    def __init__(self,name,owner,width,length,height):
        self.name=name
        self.owner=owner
        self.width=width
        self.length=length
        self.height=height
    @property
    def cal_area(self):
        return self.width*self.length
r1=Room("厕所","alex",100,100,100000)
r2=Room("公共厕所","yuanhao",1,1,1)
print("%s住的%s总面积是%s" %(r1.owner,r1.name,r1.width*r1.length))
print("%s住的%s总面积是%s" %(r2.owner,r2.name,r2.width*r2.length))
# r1.cal_area
# r2.cal_area
print(r1.cal_area)
print(r2.cal_area)
print(r1.name)
print(r2.name)

利用常规类实例计算值和利用装饰器封装函数,调用取值,让用户觉察不到数据类型的处理方法

class Volume:
    def __init__(self,length,width,height):
        self.length=length
        self.width=width
        self.height=height
    @property
    def cal_volume(self):
        return self.length*self.width*self.height
v1 = Volume(10,20,30)
print("长宽高分别是%s,%s,%s" %(v1.length,v1.width,v1.height))
print("体积是%s" %(v1.length*v1.width*v1.height))
res = v1.cal_volume
print("体积是%s" %res)

2.静态方法

#静态方法:
class Room:
    tag = 1
    def __init__(self,name,owner,width,length,height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height
    @property
    def cal_area(self):
        return self.width*self.length
    def test(self):
        print("from test",self.name)

    @classmethod #类方法,只用于实例属性
    def tell_info(cls,x): #cls为函数本身的参数,不用人为传参
        print("---->",cls.tag,x)
        #类方法能否调用实例属性?可以
print(Room.tag)
# r1 = Room("toilet", "alex",100,100,10000)
# Room.tell_info(r1) #类方法:只和类捆绑,不和任何实例捆绑
Room.tell_info(10) #默认Room=cls
r1 = Room("toilet", "alex",100,100,10000)
r1.tell_info(100) #实例调用可传入类

静态方法

class Room:
    tag = 1
    def __init__(self,name,owner,width,length,height):
        self.name = name
        self.owner = owner
        self.width = width
        self.length = length
        self.height = height
    @property #封装逻辑
    def cal_area(self):
        return self.length * self.width
    @classmethod#自动传入类
    def tell_info(cls,x): #类,函数,不能访问实例属性,静态类变量只是名义上的归属类管理,不能使用类变量和实例变量,是类的工具包
        print(cls)
        print("-->",cls.tag,x)
    @staticmethod
    def wash_body(a,b,c):
        print("%s %s %s正在洗澡"%(a,b,c))
    def test(x,y):
        print(x,y)
print(Room.__dict__)
r1 = Room("厕所","alex",100,100,100000) #定义类
print(r1.__dict__)

3.组合

# 组合
class Hand:
    pass
class Foot:
    pass
class Trunk:
    pass
class Head:
    pass
class Person:
    def __init__(self,id_num,name):
        self.id_num = id_num
        self.name = name
        self.hand = Hand()
        self.foot = Foot()
        self.trunk = Trunk()
        self.head = Head()
# p1 = Person("1111","alex")
# print(p1.__dict__)
class School:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
    def zhao_sheng(self):
        print("%s 正在招生" %self.name)
class Course:
    def __init__(self,name,price,period,school):
        self.name = name
        self.price = price
        self.period = period
        self.school = school
s1 = School("oldboy","peking")
s2 = School("oldboy","nanjing")
s3 = School("oldboy","Tokyo")
c1 = Course("linux",10,"1h",s1)
print(c1.__dict__)
print(c1.school)
print(s1)
print(c1.school.name)

#----------------------------------------------选课系统
class Hand:
    pass
class Foot:
    pass
class Trunk:
    pass
class Head:
    pass
class Person:
    def __init__(self,id_num,name):
        self.id_num = id_num
        self.name = name
        self.hand = Hand()
        self.foot = Foot()
        self.trunk = Trunk()
        self.head = Head()
# p1 = Person("1111","alex")
# print(p1.__dict__)
class School:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
    def zhao_sheng(self):
        print("%s 正在招生" %self.name)
class Course:
    def __init__(self,name,price,period,school):
        self.name = name
        self.price = price
        self.period = period
        self.school = school
s1 = School("oldboy","peking")
s2 = School("oldboy","nanjing")
s3 = School("oldboy","Tokyo")
c1 = Course("linux",10,"1h",s1)
msg = '''
1 老男孩 北京校区
2 老男孩 南京校区
3 老男孩 东京校区
'''
while True:
    print(msg)
    menu = {
        "1":s1,
        "2":s2,
        "3":s3
    }
    choice = input("选择学校>>")
    school_obj = menu[choice]

    name = input("课程名>>: ")
    price = input("课程费用>>: ")
    period = input("课程周期>>: ")

    new_course = Course(name,price,period,school_obj)
    print("磕碜【%s】 属于【%s】学校" %(new_course.name,new_course.school.name))

#组合方法_创建3个类:课程,老师,课程关联老师,老师管理课程
#组合应用场合:两个类本质上没有共同点,但是有关联的
#----------------------------------------------------------------------------
class Hand:
    pass
class Foot:
    pass
class Trunk:
    pass
class Head:
    pass
class Person:
    def __init__(self,id_num,name):
        self.id_num = id_num
        self.name = name
        self.hand = Hand()
        self.foot = Foot()
        self.trunk = Trunk()
        self.head = Head()
# p1 = Person("1111","alex")
# print(p1.__dict__)
class School:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
    def zhao_sheng(self):
        print("%s 正在招生" %self.name)
class Course:
    def __init__(self,name,price,period,school):
        self.name = name
        self.price = price
        self.period = period
        self.school = school
s1 = School("oldboy","peking")
s2 = School("oldboy","nanjing")
s3 = School("oldboy","Tokyo")
c1 = Course("linux",10,"1h",s1)
print(c1.__dict__)
print(c1.school)
print(s1)
print(c1.school.name)

4.不同类组合的实例(动态输出多个组合结果)

class Znj:
    def __init__(self,word1,word2):
        self.word1 = word1
        self.word2 = word2
class School:
    def __init__(self,name,addr,course):
        self.name = name
        self.addr = addr
        self.course = course
        self.znj = Znj
    def zhao_sheng(self):
        print("%s 正在招生" %self.name)
    def Znj(self):
        print("想对znj说一句%s" %self.znj)
class Course:
    def __init__(self,name,price,period,num):
        self.name = name
        self.price = price
        self.period = period
        self.num = num
c3 = Znj("123","456")
c1 = Course("linux",10,"1h",c3)
s1 = School("oldboy","南京",c1)
s2 = School("girl",24,c1)
print(c1.num.word1,c1.num.word2) #实现不同类组合!
print(c3.__dict__)
print(s1.__dict__)
print(s2.__dict__)
print(s1.course.name) #类组合就是在实例中添加另一个实例,作为参数传到类中

5.继承

class Dad:
    "this is a dad class"
    money = 10
    def __init__(self,name):
        print("dad")
        self.name = name
    def hit_son(self):
        print("%s 正在打儿子" %self.name)
class Son(Dad):
    money = 10000008
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def hit_son(self):
        print("from son class")
Son.hit_son("self")
print(Dad.__dict__)
print(Son.__dict__)
s1 = Son("alex",18)
s1.hit_son() #实例调用hit_son()
Son.hit_son("self") #类调用hit_son()
print(Dad.money)
print(s1.name)
print(s1.__dict__) #实例字典
#父类在字典中包括更全key,value值
#子类在字典中缺少部分父类拥有的key,value值

6.继承与派生

什么时候用继承:

a)当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好。

b)当类之间有很多相同的功能,提取这些共同的功能叫做基类,用继承比较好。

继承有两种含义:1继承基类的方法,并作出自己的改变或者扩展(代码可重用);2接口继承:声明某个子类兼容与某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法

接口技术:定义父类,规定子类必须读或写,否则不能调用实例。

#接口实际是函数
#接口继承是定义一个基类,基类中实现自己函数(装饰器)
# 子类中必须实现父类中方法,否则不可实例化
import abc
class All_file(metaclass = abc.ABCMeta):
    @abc.abstractmethod
    def read(self):
        print("all_file read")
    @abc.abstractclassmethod
    def write(self):
        print("all_file write")
class cdrom(All_file):
    def read(self):
        print("cdrom read")
    def write(self):
        print("cdrom write")
class disk(All_file):
    def read(self):
        print("disk read")
    def write(self):
        print("disk write")
class mem(All_file):
    def read(self):
        print("mem read")
    def write(self):
        print("mem write")
m1 = mem()
m1.read()
m1.write()

7.继承顺序值mro线性顺序列表

class A:
    def test(self):
        print("A")
    pass
class B(A):
    def test(self):
        print("B")
    pass
class C(A):
    def test(self):
        print("C")
    pass
class D(B):
    def test(self):
        print("D")
    pass
class E(C):
    def test(self):
        print("E")
    pass
class F(D,E):
    def test(self):
        print("D,E")
    pass
f1 = F() #实例化
f1.test() #实例化调用函数 继承顺序 F->D->B->E->C->A

8.PY3新式类和PY2经典类

class A:
    def test(self):
        print("A")
    pass
class B(A):
    # def test(self):
    #     print("B")
    pass
class C(A):
    def test(self):
        print("C")
    pass
class D(B):
    # def test(self):
    #     print("D")
    pass
class E(C):
    # def test(self):
    #     print("E")
    pass
class F(D,E):
    # def test(self):
    #     print("D,E")
    pass
f1 = F() #实例化
f1.test() #实例化调用函数     新式类继承顺序 F->D->B->E->C->A
# print(F.__mro__) #新式类方法
f1 = F()
f1.test() #python2 经典类继承顺序 F->D->B->A->E->C

9.在子类中调用父类

class Vehicle:
    Country = "China"
    def __init__(self,name,speed,load,power):
        self.name = name
        self.speed = speed
        self.load = load
        self.power = power
        # self.line = line
    def run(self):
        print("开动了")
class Subway(Vehicle):
    def __init__(self,name,speed,load,power,line):
        Vehicle.__init__(self,name,speed,load,power)
        self.line = line
    def show_info(self):
        print(self.name,self.line)
    def run(self):
        Vehicle.run(self)
        Vehicle.run(self)
        Vehicle.run(self)
        Vehicle.run(self)
        print('%s 开动啦' %self.name)
line13 = Subway("13号线","30m/s","1000","",13)
line13.show_info()
line13.run()

10.super调用父类方法

class Vehicle:
    Country = "China"
    def __init__(self,name,speed,load,power):
        self.name = name
        self.speed = speed
        self.load = load
        self.power = power
        # self.line = line
    def run(self):
        print("开动了")
class Subway(Vehicle):
    def __init__(self,name,speed,load,power,line):
        # Vehicle.__init__(self,name,speed,load,power)
        super().__init__(name,speed,load,power) #运行super函数,调用__init__函数,可以调用到父类函数
        self.line = line
    def show_info(self):
        print(self.name,self.line)
    def run(self):
        # Vehicle.run(self)
        super().run() #super()函数好处,1不用父类名 2不用传self参数
        super().run()
        super().run()
        print('%s 开动啦' %self.name)
line13 = Subway("13号线","30m/s","1000","",13)
line13.show_info()
line13.run()

11.学校类创建综合实例(序列化方式存取文件)

import pickle
class School:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
    def save(self):
        with open("school.db","wb") as f:
            pickle.dump(self,f) #以序列化方式创建文件
class Course:
    def __init__(self,name,price,period,school):
        self.name = name
        self.price = price
        self.period = period
        self.school = school
s1 = School("oldboy","北京")
s1.save()
# school_obj = pickle.load(open("school.db","rb"))
# print(school_obj.name,school_obj.db)

#以上永久建立实例
#以下取出实例
import pickle
class School:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
    def save(self):
        with open("school.db","wb") as f:
            pickle.dump(self,f) #以序列化方式创建文件
class Course:
    def __init__(self,name,price,period,school):
        self.name = name
        self.price = price
        self.period = period
        self.school = school
school_obj = pickle.load(open("school.db","rb"))
print(school_obj.name,school_obj.addr) 

12.补充:深度查找方法和广度查找方法

深度优先查找顺序:A-B-D-G-I-E-C-F-G

广度优先查找顺序:A-B-C-D-E-F-G-H-I

图2 广度优先和广度优先查找方法解释图

13.面向对象综合实例

#xxx.db文件没有生成,一个类对应一个序列的操作没有实现
import pickle
import hashlib
import time
def create_md5():
    m = hashlib.md5()
    m.update(str(time.time()).encode("utf-8"))
    return m.hexdigest()
id=create_md5()
time.sleep(1)
id1=create_md5()
time.sleep(1)
id2=create_md5()

#每一个ID作为标识,存储文件
print(id)
print(id1)
print(id2)

class Base:
    def save(self):
        with open("school.db","wb") as f:
            pickle.dump(self,f)

class School(Base):
    def __init__(self,name,addr):
        self.id=create_md5()
        self.name=name
        self.addr=addr

class Course(Base):
    def __init__(self,name,school):
        # self.price=price
        # self.period=period
        self.id=create_md5()
        self.course_name=name
        self.school=school

class SchoolMember(Base):
    """
    学习成员基类
    """
    def __init__(self,name,age,sex,school):
        self.id=create_md5()
        self.name=name
        self.age=age
        self.sex=sex
        self.school=school

class Lecturer(Base):
    def __init__(self,name,age,sex,school):
        self.id=create_md5()
        self.name=name
        self.age=age
        self.sex=sex
        self.school=school

s1=School('oldboy','北京')
s1.save()
s2=School('oldboy','上海')
s2.save()
# c1=Course('linux',10,'1h','oldboy 北京')
# c1=Course('linux',10,'1h',s1)
msg='''
1 老男孩 北京校区
2 老男孩 上海校区
'''
while True:
    print(msg)
    menu={
        '北京':s1,
        '上海':s2,
    }
    sch_choice=menu[input('学校>>: ')]
    Course_name=input('课程名>>: ')
    Course1=Course(Course_name,sch_choice)
    # print(sch_choice,Course_name,Course1.school.name)
    print('课程【%s】属于学校【%s】【%s】'% (Course1.course_name,Course1.school.name,Course1.school.addr))

    sch_choice1 = menu[input('学校(学员)>>: ')]
    sch_peo=SchoolMember("alex","18","female",sch_choice1)
    print("成员【%s】属于学校【%s】[%s]" %(sch_peo.name,sch_peo.school.name,sch_peo.school.addr))

    sch_choice2 = menu[input('学校(教员)>>: ')]
    lec = Lecturer("wusir", "25", "male", sch_choice2)
    print("教员【%s】属于学校【%s】[%s]" %(lec.name,lec.school.name,lec.school.addr))
    school_obj = pickle.load(open("school.db","rb"))
    print(school_obj.name, school_obj.addr)

f图2 面向对象综合实例作业要求

14.面向对象建立目录时文件夹分类:

bin:可执行文件

conf:配置文件,一般设置成setting.py

db:数据

lib:图书馆

log:日志模块

src:存放主逻辑

原文地址:https://www.cnblogs.com/yuyukun/p/10591507.html