第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 第三模块:面向对象网络编程基础-第1章 面向对象

第三模块:面向对象网络编程基础-第1章 面向对象

时间:2022-07-27 05:33:22

相关推荐

第三模块:面向对象网络编程基础-第1章  面向对象

系列文章目录

面向对象编程设计与开发


文章目录

系列文章目录前言一、面向过程编程二、面向对象编程1.面向对象编程介绍2.定义类与实例化出对象3.如何使用类4.如何使用对象5.属性查找与绑定方法6.python中一切皆对象7.面向对象可扩展性总结8.小练习19.小练习2 三、继承与重用性1.什么是继承2.派生3.继承的实现原理4.子类中调用父类的方法或属性5.组合6.抽象类与归一化 四、多态与多态性五、封装1.封装之如何隐藏属性2.封装的意义3.封装与可扩展性4.property的使用 六、绑定方法与非绑定方法1.绑定方法与非绑定方法介绍2.绑定方法与非绑定方法使用 七、反射八、内置方法九、元类1.元类介绍2.自定义元类控制类的创建3.自定义元类控制类的实例化行为4.自定义元类控制类的实例化行为的应用 十、面向对象软件开发十一、异常处理1.什么是异常处理2.try...except详细用法 总结


前言

面向对象编程设计与开发


一、面向过程编程

"""面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式优点:复杂问题流程化,进而简单化缺点:可扩展性差应用场景:面向过程的程序设计思想一般用于那些功能一旦实现之后就很少需要改变的场景"""import jsonimport redef interactive():name = input(">>").strip()pwd = input(">>").strip()email = input(">>").strip()return {"name":name,"pwd":pwd,"email":email}def check(user_info):is_valid = Trueif len(user_info["name"]) == 0:print("用户名不能为空")is_valid = Falseif len(user_info["pwd"]) < 6:print("密码不能少于6位")is_valid = Falseif not re.search(r'@.*?\.com$',user_info["email"]):print("邮箱格式不合法")is_valid = Falsereturn {"is_valid":is_valid,"user_info":user_info}def register(check_info):if check_info["is_valid"]:with open("db.json","w",encoding="utf-8") as f:json.dump(check_info["user_info"],f)def main():user_info = interactive()check_info = check(user_info)register(check_info)if __name__ == '__main__':main()

二、面向对象编程

1.面向对象编程介绍

"""面向对象:核心是对象二字,对象就是特征与技能的结合体优点:可扩展性强缺点:编程复杂度高应用场景:用户需求经常变化,互联网应用,游戏,企业内部应用"""

2.定义类与实例化出对象

类就是一系列对象相似的特征与技能的结合体强调:站在不同的角度,得到的分类是不同的在现实世界中:一定是现有对象,后有类在程序中:一定得先定义类,后调用类产生对象站在路飞学院的角度,在座的诸位都是学生在现实世界中:对象1:王二丫特征:学校=‘luffycity’名字='王二丫'性别='女'年龄=18技能:学习吃饭睡觉对象2:李三炮特征:学校:'luffycity'名字:'李三炮'性别:'男'年龄:38技能:学习吃饭睡觉对象3:张铁蛋特征:学校:'luffycity'名字:'张铁蛋'性别:'男'年龄:48技能:学习吃饭睡觉总结现实中的路飞学院学生类相似的特征学校:'luffycity'相似的技能学习吃饭睡觉#先定义类class LuffyStudent:school = 'luffycity'def learn(self):print("is learning")def eat(self):print("is eating")def sleep(self):print("is sleeping")#后产生对象stu1 = LuffyStudent()stu2 = LuffyStudent()stu3 = LuffyStudent()print(stu1)print(stu2)print(stu3)<__main__.LuffyStudent object at 0x000002A4672E30A0><__main__.LuffyStudent object at 0x000002A4672E3190><__main__.LuffyStudent object at 0x000002A4672EA4C0>

3.如何使用类

#先定义类class LuffyStudent:school = 'luffycity' #数据属性def learn(self): #函数属性print("is learning")def eat(self): #函数属性print("is eating")def sleep(self): #函数属性print("is sleeping")#查看类的名称空间# print(LuffyStudent.__dict__)# print(LuffyStudent.__dict__["school"])# print(LuffyStudent.__dict__["learn"])# 查# print(LuffyStudent.school) #LuffyStudent.__dict__["school"]# print(LuffyStudent.learn) #print(LuffyStudent.__dict__["learn"])#增LuffyStudent.country = "China"print(LuffyStudent.country)#删del LuffyStudent.country#改LuffyStudent.school = "Luffycity"

4.如何使用对象

#init方法用来为对象定制自己独有的特征#先定义类class LuffyStudent:school = 'luffycity'def __init__(self,name,sex,age):self.Name = nameself.Sex = sexself.Age = agedef learn(self):print("is learning")def eat(self):print("is eating")def sleep(self):print("is sleeping")#后产生对象stu1 = LuffyStudent("王二丫","女",18) #LuffyStudent.__init__(stu1,"王二丫","女",18)#加上__init__方法后实例化的步骤#1.先产生一个空对象stu1#2.LuffyStudent.__init__(stu1,"王二丫","女",18)# print(LuffyStudent.__init__)#查# print(stu1.__init__)# print(stu1.Name)# print(stu1.Sex)# print(stu1.Age)#改stu1.Name = "李二丫"print(stu1.Name)#删除del stu1.Nameprint(stu1.__dict__)#增加stu1.class_name = "全栈开发"print(stu1.__dict__)stu2 = LuffyStudent("李三炮","男","38") #Luffycity.__init__(stu2,"李三炮","男","38")print(stu2.__dict__)print(stu2.Name)print(stu2.Age)print(stu2.Sex)

5.属性查找与绑定方法

"""在现实世界中:对象1:王二丫特征:学校=‘luffycity’名字='王二丫'性别='女'年龄=18技能:学习吃饭睡觉对象2:李三炮特征:学校:'luffycity'名字:'李三炮'性别:'男'年龄:38技能:学习吃饭睡觉对象3:张铁蛋特征:学校:'luffycity'名字:'张铁蛋'性别:'男'年龄:48技能:学习吃饭睡觉总结现实中的路飞学院学生类相似的特征学校:'luffycity'相似的技能学习吃饭睡觉"""#init方法用来为对象定制自己独有的特征#先定义类class LuffyStudent:school = 'luffycity'def __init__(self,name,sex,age):self.Name = nameself.Sex = sexself.Age = agedef learn(self,x):print("%s is learning %s" %(self.Name,x))def eat(self):print("%s is eating" %self.Name)def sleep(self):print("%s is sleeping" %self.Name)#后产生对象stu1 = LuffyStudent("王二丫","女",18)stu2 = LuffyStudent("李三炮","男",38)stu3 = LuffyStudent("张铁蛋","男",48)# print(stu1.__dict__)# print(stu2.__dict__)# print(stu3.__dict__)#对象:特征与技能的结合体#类:一系列对象相似的特征与相似的技能的结合体#类中的数据属性:是所有对象共有的# print(LuffyStudent.school,id(LuffyStudent.school))## print(stu1.school,id(stu1.school))# print(stu2.school,id(stu2.school))# print(stu3.school,id(stu3.school))#类中的函数属性:是绑定给对象使用的,绑定到不同的对象是不同的访问方法,对象绑定方法时,会把对象本身当作第一个参数传入# print(LuffyStudent.learn)# LuffyStudent.learn(stu1)# LuffyStudent.learn(stu2)# LuffyStudent.learn(stu3)# print(stu1.learn)# stu1.learn(1)# stu2.learn(2)# stu3.learn(3)# print(stu2.learn)# print(stu3.learn)# stu1.x = "from stu1"LuffyStudent.x = "from luffy class"print(stu1.__dict__)print(stu1.x)

6.python中一切皆对象

#python一切皆对象,在py3统一了类与类型的概念# print(type([1,2,3]))print(list)class LuffyStudent:school = 'luffycity'def __init__(self,name,sex,age):self.Name = nameself.Sex = sexself.Age = agedef learn(self,x):print("%s is learning %s" %(self.Name,x))def eat(self):print("%s is eating" %self.Name)def sleep(self):print("%s is sleeping" %self.Name)print(LuffyStudent)l1 = [1,2,3]l1.append(4) #list.append(l1,4)print(l1)<class 'list'><class '__main__.LuffyStudent'>[1, 2, 3, 4]

7.面向对象可扩展性总结

class Chinese:country = "China"def __init__(self,name,age,sex):self.name=nameself.age=ageself.sex=sexdef eat(self):print("%s is eating" %self.name)p1=Chinese('egon',18,'male')p2=Chinese('alex',38,'female')p3=Chinese('wpq',48,'female')print(p1.country)print(p2.country)print(p3.country)p1.eat()p2.eat()p3.eat()ChinaChinaChinaegon is eatingalex is eatingwpq is eating

8.小练习1

"""1.编写一个学生类,产生一堆学生对象要求:有一个计数器,统计产生了多少对象"""class Student:school = "路飞学院"count = 0def __init__(self,name,age,sex):self.name = nameself.age = ageself.sex = sexStudent.count += 1def learn(self):print("%s is learning" %self.name)stu1 = Student("Alex","male",38)stu2 = Student("jinxing","female",78)stu3 = Student("egon","male",18)print(Student.count)print(stu1.count)print(stu2.count)print(stu3.count)

9.小练习2

"""2.模仿lol定义两个英雄类要求:1.英雄需要有昵称,攻击力,生命值等属性2.实例化出两个英雄对象"""class Garen:camp = "Demacia"def __init__(self,nickname,life_value,aggresivity):self.nickname = nicknameself.life_value = life_valueself.aggresivity = aggresivitydef attack(self,enemy):enemy.life_value -= self.aggresivity#r1.life_value - g1.aggresivityclass Riven:camp = "Noxus"def __init__(self,nickname,life_value,aggresivity):self.nickname = nicknameself.life_value = life_valueself.aggresivity = aggresivitydef attack(self,enemy):enemy.life_value -= self.aggresivityg1 = Garen("草丛伦",100,30)r1 = Riven("瑞文",80,50)print(r1.life_value)g1.attack(r1)g1.attack(r1)print(r1.life_value)

三、继承与重用性

1.什么是继承

继承指的是类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可以成为基类或超类,新建的类称为派生类或子类

python中类的继承分为:单继承和多继承

class ParentClass1:passclass ParentClass2:passclass SubClass1(ParentClass1):passclass SubClass2(ParentClass1,ParentClass2):passprint(SubClass1.__bases__)(<class '__main__.ParentClass1'>,)print(SubClass2.__bases__)(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

继承与重用性

用已经有的类建立一个新的类,这样就重用了已经有的软件中的一部分设置大部分,大大节省了编程工作量,这就是常说的软件重用,不仅可以重用自己的类

class Hero:def __init__(self,nickname,life_value,aggresivity):self.nickname = nicknameself.life_value = life_valueself.aggresivity = aggresivitydef attack(self,enemy):enemy.life_value -= self.aggresivityclass Garen(Hero):passclass Riven(Hero):passg1 = Garen("草丛文",29,30)print(g1.nickname,g1.life_value,g1.aggresivity)

属性查找

像g1.life_value之类的属性引用,会先从实例中找life_value然后去类中找,然后再去父类中找…直到最顶级的父类

class Foo:def f1(self):print("from Foo.f1")def f2(self):print("from Foo.f2")self.f1()class Bar(Foo):def f1(self):print("from Bar.f2")b = Bar()b.f2()from Foo.f2from Bar.f2

2.派生

子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了

class Hero:def __init__(self,nickname,life_value,aggresivity):self.nickname = nicknameself.life_value = life_valueself.aggresivity = aggresivitydef attack(self,enemy):enemy.life_value -= self.aggresivityclass Garen(Hero):camp = "Demacia"def attack(self,enemy):print("from Garen calss")class Riven(Hero):camp = "Noxus"g = Garen("草丛文",29,30)r = Riven("瑞文",80,50)print(g.camp)g.attack(r)Demaciafrom Garen calss

3.继承的实现原理

1.子类会先于父类被检查

2.多个父类会根据它们在列表中的顺序被检查

3.如果对下一个类存在两个合法的选择,选择第一个父类

#验证多继承属性下查找class A(object):def test(self):print('from A')class B(A):pass# def test(self):#print('from B')class C(A):pass# def test(self):#print('from C')class D(B):pass# def test(self):#print('from D')class E(C):pass# def test(self):#print('from E')class F(D,E):# def test(self):#print('from F')passf = F()f.test()print(F.mro())from A[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

4.子类中调用父类的方法或属性

在子类派生出的新的方法中,重用父类的方法,有两种实现方式

#方式1:指名道姓(不依赖继承)# class Hero:#def __init__(self,nickname,life_value,aggresivity):# self.nickname = nickname# self.life_value = life_value# self.aggresivity = aggresivity#def attack(self,enemy):# enemy.life_value -= self.aggresivity## class Garen(Hero):#camp = "Demacia"#def attack(self,enemy):# Hero.attack(self,enemy) #指名道姓# print("from Garen calss")## class Riven(Hero):#camp = "Noxus"## g = Garen("草丛文",29,30)# r = Riven("瑞文",80,50)# print(r.life_value)# g.attack(r)# print(r.life_value)class Hero:def __init__(self,nickname,life_value,aggresivity):self.nickname = nicknameself.life_value = life_valueself.aggresivity = aggresivitydef attack(self,enemy):enemy.life_value -= self.aggresivityclass Garen(Hero):camp = "Demacia"def __init__(self,nickname,life_value,aggresivity,weapon):# self.nickname = nickname# self.life_value = life_value# self.aggresivity = aggresivityHero.__init__(self,nickname,life_value,aggresivity)self.weapon = weapondef attack(self,enemy):Hero.attack(self,enemy) #指名道姓print("from Garen calss")g = Garen("草丛文",29,30,"金箍棒")print(g.__dict__){'nickname': '草丛文', 'life_value': 29, 'aggresivity': 30, 'weapon': '金箍棒'}

#方式2:super()(依赖继承)# class Hero:#def __init__(self,nickname,life_value,aggresivity):# self.nickname = nickname# self.life_value = life_value# self.aggresivity = aggresivity#def attack(self,enemy):# enemy.life_value -= self.aggresivity## class Garen(Hero):#camp = "Demacia"#def attack(self,enemy):# super(Garen, self).attack(enemy) #依赖继承# print("from Garen calss")## class Riven(Hero):#camp = "Noxus"## g = Garen("草丛文",100,30)# r = Riven("瑞文",80,50)## g.attack(r)# print(r.life_value)# class Hero:#def __init__(self,nickname,life_value,aggresivity):# self.nickname = nickname# self.life_value = life_value# self.aggresivity = aggresivity#def attack(self,enemy):# enemy.life_value -= self.aggresivity## class Garen(Hero):#camp = "Demacia"##def __init__(self,nickname,life_value,aggresivity,weapon):# super().__init__(nickname,life_value,aggresivity)# self.weapon = weapon##def attack(self,enemy):# Hero.attack(self,enemy) #指名道姓# print("from Garen calss")### g = Garen("草丛文",100,30,"金箍棒")class A:def f1(self):print("from A")super().f1()class B:def f1(self):print("from B")class C(A,B):passprint(C.mro())#[<class '__main__.C'>,# <class '__main__.A'>,# <class '__main__.B'>,# <class 'object'>]c = C()c.f1()[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]from Afrom B

5.组合

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

class People:school = "luffycity"def __init__(self,name,age,sex):self.name = nameself.age = ageself.sex = sexclass Teacher(People):def __init__(self,name,age,sex,level,salary):super().__init__(name,age,sex)self.level = levelself.salary = salarydef teach(self):print("%s is teaching" %self.name)class Student(People):def __init__(self,name,age,sex,classtime):super().__init__(name,age,sex)self.classtime = classtimedef learn(self):print("%s is learning" %self.name)class Course():def __init__(self,course_name,course_price,course_period):self.course_name = course_nameself.course_price = course_priceself.course_period = course_perioddef tell_info(self):print("课程名%s,课程价钱%s,课程周期%s" %(self.course_name,self.course_price,self.course_period))class Date:def __init__(self,year,month,day):self.year = yearself.month = monthself.day = daydef tell_info(self):print("%s-%s-%s" %(self.year,self.month,self.day))student1 = Student("zhangsan",18,"female","08:30:00")d = Date(1988,4,20)student1.birth = dd.tell_info()python = Course("python",3000,"3months")student1.course = pythonstudent1.course.tell_info()

6.抽象类与归一化

抽象类

抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

import abcclass Animal(metaclass=abc.ABCMeta): #只能被继承,不能被实例化all_type = "animals"@abc.abstractmethoddef run(self):pass@abc.abstractmethoddef eat(self):passclass People(Animal):def run(self):print("people is running")def eat(self):print("people is eating")class Pig(Animal):def run(self):print("pig is walking")def eat(self):print("pig is eating")class Dog:def run(self):print("dog is walking")def eat(self):print("dog is eating")

四、多态与多态性

多态与多态性

多态指的是一类事物有多种形态

#多态:同一类事物多种形态import abcclass Animal(metaclass=abc.ABCMeta): #同一类事物:动物@abc.abstractmethoddef talk(self):passclass People(Animal): #动物的形态之一:人def talk(self):print('say hello')class Dog(Animal): #动物的形态之二:狗def talk(self):print('say wangwang')class Pig(Animal): #动物的形态之三:猪def talk(self):print('say aoao')class Cat(Animal):def talk(self):print("miaomiao")#多态性:在不考虑对象类型的情况下直接使用对象多态性是指在不考虑实例类型的情况下使用实例```pythonpeo1 = People()dog1 = Dog()pig1 = Pig()cat1 = Cat()peo1.talk()dog1.talk()pig1.talk()def fun(animal):animal.talk()fun(peo1)fun(pig1)fun(dog1)fun(cat1)

多态性的好处

1.增加了程序的灵活性

以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)

2.增加了程序额可扩展性

通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用

鸭子类型

class Disk:def read(self):print("disk read")def write(self):print("disk read")class Text:def read(self):print("text read")def write(self):print("text read")disk = Disk()text = Text()#序列:列表list,元组tuple,字符串strl = list([1,2,3])t = tuple(("a","b"))s = str("hello")# print(l.__len__())# print(t.__len__())# print(s.__len__())def len(obj):return obj.__len__()print(len(l))print(len(t))print(len(s))

五、封装

1.封装之如何隐藏属性

# class A:#__x = 1 #_A__x##def __init__(self,name):# self.__name = name#def __foo(self): #_A__foo# print("run foo")#def bar(self):# self.__foo()# print("from bar")# print(A.__dict__)# a = A("egon")# print(a.__dict__)# a.bar()"""这种变形的特点:1.在类外部无法直接obj._AttrName2.在类内部可以直接使用:obj._AttrName3.子类无法覆盖父类__开头的属性"""# class Foo:#def func(self): #_foo__func# print("from foo")## class Bar(Foo):#def func(self): #_bar__func# print("from bar")## b = Bar()# b.func()"""总结这种变形需要注意的问题:"""# class B:#__x = 1#def __init__(self,name):# self.__name = name #self.B__name = name#验证问题一# print(B._B__x)#验证问题二# b = B("egon")# print(b.__dict__)#验证问题三# class A:#def foo(self):# print("A.foo")#def bar(self):# print("A.bar")# self.foo() #b.foo()## class B(A):#def foo(self):# print("B.foo")## b = B()# b.bar()class A:def __foo(self): #_A__fooprint("A.foo")def bar(self):print("A.bar")self.__foo() #self._A__.foo()class B(A):def __foo(self): #_B__foo()print("B.foo")b = B()b.bar()

2.封装的意义

#一:封装数据属性:明确的区分内外,控制外部对隐藏的属性的操作行为

class People:def __init__(self,name,age):self.__name = nameself.__age = agedef tell_info(self):print("name:%s,age:%s" %(self.__name,self.__age))def set_info(self,name,age):if not isinstance(name,str):print("名字必须是字符串类型")returnif not isinstance(age,int):print("年龄必须是数字类型")returnself.__name = nameself.__age = agep = People("egon",18)p.set_info("Egon",28)p.tell_info()name:Egon,age:28

#二:封装方法:隔离复杂度

class ATM:def __card(self):print('插卡')def __auth(self):print('用户认证')def __input(self):print('输入取款金额')def __print_bill(self):print('打印账单')def __take_money(self):print('取款')def withdraw(self):self.__card()self.__auth()self.__input()self.__print_bill()self.__take_money()a=ATM()a.withdraw()

3.封装与可扩展性

class Room:def __init__(self,name,owner,width,length,height):self.name = nameself.owner = ownerself.__weight = widthself.__length = lengthself.__height = heightdef tell_area(self):return self.__weight * self.__length * self.__heightr = Room("卫生间","alex",10,10,10)print(r.tell_area())

4.property的使用

'''例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)成人的BMI数值:过轻:低于18.5正常:18.5-23.9过重:24-27肥胖:28-32非常肥胖, 高于32体质指数(BMI)=体重(kg)÷身高^2(m)EX:70kg÷(1.75×1.75)=22.86'''class People:def __init__(self,name,weight,height):self.name = nameself.weight = weightself.height = height@propertydef bmi(self):return self.weight/(self.height ** 2)p = People("egon",75,1.81)# print(p.bmi)p.height = 1.82print(p.bmi)22.6421929718633

class People:def __init__(self,name):self.__name = name@propertydef name(self):return self.__name@name.setterdef name(self,val):if not isinstance(val,str):print("名字必须字符串")returnself.__name = val@name.deleterdef name(self):print("不允许删除")p = People("egon")print(p.name)p.name = "Egon"egon

六、绑定方法与非绑定方法

1.绑定方法与非绑定方法介绍

一:绑定方法: 绑定给谁就应该由谁来调用,谁来调用就会把调用者当作第一个参数自动传入

绑定到对象的方法:在类内定义的没有被任何装饰器修饰的

class Foo:def __init__(self,name):self.name = namedef tell(self):print("名字是%s" %self.name)f = Foo("egon")# print(f.tell)f.tell()名字是egon

绑定到类的方法:在类内定义的被装饰器@classmethod修饰的方法

class Foo:def __init__(self,name):self.name = namedef tell(self):print("名字是%s" %self.name)@classmethoddef func(cls): #cls = Fooprint(cls)Foo.func()<class '__main__.Foo'>

二:非绑定方法:没有自动传值这么一说了,就是类定义的一个普通工具,对象和类都可以使用

非绑定方法:不与类或对象绑定

class Foo:def __init__(self,name):self.name = namedef tell(self):print("名字是%s" %self.name)@classmethoddef func(cls): #cls = Fooprint(cls)@staticmethoddef func1(x,y):print(x + y)f = Foo("egon")Foo.func1(1,2)f.func1(1,3)34

2.绑定方法与非绑定方法使用

import settingsimport hashlibimport timeclass People:def __init__(self,name,age,sex):self.id = self.create_id()self.name = nameself.age = ageself.sex = sexdef tell_info(self): #绑定到对象的方法print("name:%s,age:%s,sex:%s" %(self.name,self.age,self.sex))@classmethoddef from_conf(cls):obj = cls(settings.name,settings.age,settings.sex)return obj@staticmethoddef create_id():m = hashlib.md5(str(time.time()).encode("utf-8"))return m.hexdigest()# p = People("egon",18,"male")#绑定给对象,就应该由对象来调用,自动将对象本身当作第一个参数传入# p.tell_info()#绑定给类的,就应该由类来调用,自动将类当作第一个参数传入# p = People.from_conf()# p.tell_info()#非绑定方法,不与类或对象绑定,谁都可以调用,没有传值一说p1 = People("egon1",18,"male")p2 = People("egon2",28,"male")p3 = People("egon3",38,"male")print(p1.id)print(p2.id)print(p3.id)

七、反射

#反射:通过字符串映射到对象属性class People:country = "China"def __init__(self,name,age):self.name = nameself.age = agedef talk(self):print("%s is talking" %self.name)obj = People("egon",18)# print(hasattr(obj,"name")) #obj.nameprint(getattr(obj,"name"))print(getattr(obj,"name1","none"))print(getattr(obj,"talk","none"))setattr(obj,"sex","male")print(obj.sex)delattr(obj,"age")print(obj.__dict__)getattr(People,"country")

反射的应用

class Service:def run(self):while True:inp = input(">>:").strip() #cmd = get a.txtcmds = inp.split()if hasattr(self,cmds[0]):func = getattr(self,cmds[0])func(cmds)def get(self,cmds):print("get...",cmds)def put(self):print("put")obj = Service()obj.run()>>:get a.txtget... ['get', 'a.txt']

八、内置方法

1.item系列

#item系列class Foo:def __init__(self,name):self.name = namedef __getitem__(self, item): #item = "name"# print("getitem")# print(item)return self.__dict__.get(item)def __setitem__(self, key, value):# print("setitem")# print(key,value)self.__dict__[key] = valuedef __delitem__(self, key):# print("delitem")# print(key)del self.__dict__[key]#查看属性obj = Foo("egon")print(obj["name"])#设置属性obj["sex"] = "male"print(obj.__dict__)print(obj.sex)#删除属性del obj["name"]print(obj.__dict__)egon{'name': 'egon', 'sex': 'male'}male{'sex': 'male'}

2.str

class People:def __init__(self,name,age):self.name = nameself.age = agedef __str__(self):# print("==>str")return "<name:%s,age:%s>" %(self.name,self.age)obj = People("egon",18)print(obj)<name:egon,age:18>

3.del

class Open:def __init__(self,filename):print("open file")self.filename = filenamedef __del__(self):print("回收操作系统资源:self.close()")f = Open("settings.py")open filedel

九、元类

1.元类介绍

#储备知识exec#参数1.字符串形式的命令#参数2.全局作用域(字典形式),如果不知道默认globals()#参数3.局部作用域(字典形式),如果不知道默认locals()g = {"x":1,"y":2}l = {}exec('''global x,mx = 10m = 100z = 3''',g,l)# print(g)# print(l){'z': 3}

#一切皆对象,对象可以怎么用

#1.都可以被引用,x=obj

#2.都可以当作函数的参数传入

#3.都可以当作函数的返回值

#4.都可以当作容器类型的元素 l = [func,time]

#类也是对象class Foo: #Foo=type(...)passobj = Foo()print(type(obj))print(type(Foo))class Bar:passprint(type(Bar))

#产生类的类称之为元类,默认所有用class定义的类,他们的元类是type

#定义类的两种方式

#方式一:class #Chinese = type(…)

class Chinese:country = "China"def __init__(self,name,age):self.name = nameself.age = agedef talk(self):print("%s is talking" %self.name)# print(Chinese)obj = Chinese("egon",18)print(obj.name,obj.age)

#方式二:type

#定义类的三要素:类名,类的基类,类的名称空间

class_name = "Chinese"class_bases = (object,)class_body = '''country = "China"def __init__(self,name,age):self.name = nameself.age = agedef talk(self):print("%s is talking" %self.name)'''class_dict = {}exec(class_body,globals(),class_dict)# print(class_dict)Chinese1 = type(class_name,class_bases,class_dict)# print(Chinese1)obj1 = Chinese("egon",18)print(obj1.name,obj1.age)

2.自定义元类控制类的创建

class Mymeta(type):def __init__(self,class_name,class_bases,class_dict):if not class_name.istitle():raise TypeError("类名首字母必须大写")if __doc__ not in class_dict or not class_dict.strip():raise TypeError("必须有注释且注释不能为空")super(Mymeta,self).__init__(class_name,class_bases,class_dict)class Chinese(object,metaclass=Mymeta):""""""country = "China"def __init__(self,name,age):self.name = nameself.age = agedef talk(self):print("%s is talking" %self.name)

3.自定义元类控制类的实例化行为

#知识储备__call__

class Foo:def __call__(self, *args, **kwargs):print(self)print(args)print(kwargs)obj = Foo()obj(1,2,3,a = 1,b=2,c=3)#元类内部也应有__call__方法,会在调用foo时触发执行<__main__.Foo object at 0x00000142E5D15D60>(1, 2, 3){'a': 1, 'b': 2, 'c': 3}

#先造出空对象obj

#初始化obj

#返回值

class Mymeta(type):def __init__(self,class_name,class_bases,class_dict):if not class_name.istitle():raise TypeError("类名首字母必须大写")if "__doc__" not in class_dict or not class_dict["__doc__"].strip():raise TypeError("必须有注释且注释不能为空")super(Mymeta,self).__init__(class_name,class_bases,class_dict)def __call__(self, *args, **kwargs): #obj = Chinese("egon",age=18)# print(self) #Chinese# print(args) #('egon',)# print(kwargs) #{'age': 18}#第一件事:先造出一个空对象objobj = object.__new__(self)#第二件事:初始化objself.__init__(obj,*args, **kwargs)#第三件事:返回objreturn objclass Chinese(object,metaclass=Mymeta):"""注释"""country = "China"def __init__(self,name,age):self.name = nameself.age = agedef talk(self):print("%s is talking" %self.name)obj = Chinese("egon",age=18) #Chinese.call(Chinese,"egon",18)print(obj.__dict__){'name': 'egon', 'age': 18}

4.自定义元类控制类的实例化行为的应用

#单例模式

#实现方式一:

class MySql:__instance = None #__instance = obj1def __init__(self):self.host = "127.0.0.1"self.port = 3306@classmethoddef singleton(cls):if not cls.__instance:obj = cls()cls.__instance = objreturn cls.__instance# obj1 = MySql()# obj2 = MySql()# obj3 = MySql()## print(obj1)# print(obj2)# print(obj3)obj1 = MySql.singleton()obj2 = MySql.singleton()

#实现方式二:元类的方式

class Mymeta(type):def __init__(self,class_name,class_bases,class_dict):if not class_name.istitle():raise TypeError("类名首字母必须大写")if "__doc__" not in class_dict or not class_dict["__doc__"].strip():raise TypeError("必须有注释且注释不能为空")super(Mymeta,self).__init__(class_name,class_bases,class_dict)self.__instance = Nonedef __call__(self, *args, **kwargs): #obj = Chinese("egon",age=18)if not self.__instance:obj = object.__new__(self)self.__init__(obj)self.__instance = objreturn self.__instanceclass Mysql(object,metaclass=Mymeta):"""注释"""def __init__(self):self.host = "127.0.0.1"self.port = 3306obj1 = Mysql()obj2 = Mysql()obj3 = Mysql()print(obj1 is obj2 is obj3)True

十、面向对象软件开发

/linhaifeng/articles/7341318.html#_label2

十一、异常处理

1.什么是异常处理

#1.什么是异常:异常是错误发生的信号,一旦程序出现错误,并且程序没有处理这个错误,那这个就会抛出异常并且程序运行随之中止#2.错误分为两种:#语法错误:在程序执行前就要立刻改正过来#逻辑错误:# ValueError:# int("aaa")# NameError:# name# IndexError:# l = [1,2,3]# l[1000]#KeyError# d = {}# d["banana"]# AttributeError# class Foo:#pass# Foo.xxx# ZeroDivisionError# 1/0#TypeError:int类型不可迭代# for i in 3:#pass# import time# time.sleep(100)

#强调一:对于错误发生的条件是可以预知的,此时应该用if判断去预防异常

AGE = 10age = input(">>:").strip()if age.isdigit():age = int(age)if age > AGE:print("太大了")

#强调二:对于错误发生的条件是不可预知的,此时应该用异常处理机制,try…except…

try:f = open("a.txt","r",encoding="utf-8")print(next(f),end="")print(next(f),end="")print(next(f),end="")print(next(f),end="")print(next(f),end="")f.close()except StopIteration:print("出错了")print(">>>1")print(">>>2")111222333444出错了>>>1>>>2

2.try…except详细用法

多分支:被监测的代码块抛出的异常有多种可能性,我们需要针对每种异常类型都定制专门的处理逻辑

try:print(">>1")# nameprint(">>2")l = [1,2,3]l[100]print(">>3")d = {}d["name"]print(">>4")except NameError as e:print("---->>",e)except IndexError as e:print("---->>",e)except KeyError as e:print("----->>",e)print("after code")

#万能异常:Exception,被监测的代码块抛出的异常有多种可能性,我们针对所有的异常类型都只用一种逻辑,那就使用Exception

try:print(">>1")# nameprint(">>2")l = [1,2,3]l[100]print(">>3")d = {}d["name"]print(">>4")except NameError as e:print("---->>",e)except IndexError as e:print("---->>",e)except KeyError as e:print("----->>",e)except Exception as e:print("统一处理方法")print("after code")

#其他结构

try:print(">>1")# nameprint(">>2")l = [1,2,3]# l[100]print(">>3")d = {}d["name"]print(">>4")except NameError as e:print("---->>",e)except IndexError as e:print("---->>",e)except KeyError as e:print("----->>",e)except Exception as e:print("统一处理方法")else:print("在被监测的代码块没有发生异常时")finally:print("不管被监测代码块有无发生异常,都会执行")print("after code")try:f = open("a.txt","r",encoding="utf-8")print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))f.close()finally:f.close()

#主动出发异常,raise,异常类型(值)

class People:def __init__(self,name,age):if not isinstance(name,str):raise TypeError("名字必须传入str类型")if not isinstance(age,int):raise TypeError("年龄必须传int类型")self.name = nameself.age = agep = People("egon",18)

#自定义异常类型

class MyException(BaseException):def __init__(self,msg):super(MyException,self).__init__()self.msg = msgdef __str__(self):return "<%s>" %self.msgraise MyException("我自己的异常类型")

#断言assert

info = {}info["name"] ="egon"info["age"] = 18# if "name" not in info:#raise KeyError("必须有name这个key")# if "age" not in info:#raise KeyError("必须有age这个key")assert ("name" in info) and ("age" in info)if info["name"] == "egon" and info["age"] > 10:print("welcome")

总结

面向对象编程设计与开发

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。