今日内容
面向对象的三大特性
封装
继承与派生
多态与多态性
绑定方法与非绑定方法
内置的方法
元类
异常处理
内容回顾
1.面向对象编程与面向过程编程
面向过程:
核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么…基于该思想编写程序就好比在设计一条流水线
优点:复杂的问题流程化,进而简单化
缺点:可扩展性差
面向对象:
核心是对象二字,对象指的是特征与技能的结合体,基于该思想编写程序就好比在创造一个世界,程序员就是这个世界的上帝,在上帝眼里一切事物均是对象
优点:可扩展性性高
缺点:编程的复杂度相对于面向过程要高
2.定义类
类就是一系列属性和方法的结合体
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n26" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class OldboyStudent:
school='oldboy'
def init(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def choose_course(self,course):
pass
类你也可以把它理解成是一个容器,你往里面存了很多名字,
存不是我们首要的目的,取才是!
如果你要访问类里面的名字
print(OldBoy.dict)
print(OldBoy.dict['school'])
print(OldBoy.school) python给你提供了访问属性的简便操作 统一采用句点符
只要是句点符操作的左边一定是一个容器(名称空间) 比如: 模块,类,对象</pre>
3.实例化对象
调用init完成实例化 self.name = name,这种语法不是在获取属性而是在往对象里面新增属性
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n29" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">obj = OldBoy('jason')
print(obj.dict) # 查看对象独有的属性
print(obj.school) # 还可以查看类里面共有的属性</pre>
产生一个空对象
调用init实例化(将空对象和传入的参数一并传给init)
将实例化好的对象返回出来
4.属性查找
先从对象自己的名称空间找,如果没有则去类名称空间中找,如果还没有则去父类中找...
补充:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n41" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># python中一切皆对象
l = list([1,2,3])
obj1 = OldBoy('egon')
print(type(l))
print(type(obj1))
你定义一个类 可不可以认为就是定义了一个新的数据结构
你定义一个列表之后,是不是配套的有一堆相应的操作该列表的方法?append pop ...
那对象刚好也有对应的绑定方法</pre>
5.绑定给对象的方法
在类中定义的函数,叫方法,类可以调用但是需要手动传入self
该方法在没有被任何装饰器修饰的前提下,其实就是给对象用的而且是绑定给对象的绑定方法
绑定特点:谁来调就会将谁当作第一个参数自动传入
6.封装
1、什么是封装 “装”的意思就往一个容器中放入一系列属性 “封”的意思就是藏起来,在内部可以看到,但对外部是隐藏的
2、为什么要用封装
将复杂的操作封装成简单的接口,并严格控制接口的调用过程
3、如何用封装 但凡是双下划线开头(不能是双下划线结尾)的属性,会被隐藏起来,类内部可以直接使用 而类外部无法直接使用,即封装是对外不对内的
这种隐藏的特点: 1、只是一种语法上的变形,会将开头的属性变形为:自己的类名_属性名(_n=1 #Foo__n=1) 2、该变形只在类定义阶段发生一次,在类定义阶段之后新增的开头的属性并不会发生变形 3、隐藏是对外不对内的 4、在继承中,父类如果不想让子类覆盖自己的同名方法,可以将方法定义为私有的
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n52" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Teacher:
def init(self,name,age):
self.__name=name
self.__age=age
self.set_info(name,age)
def tell_info(self):
print('姓名:%s,年龄:%s' %(self.__name,self.__age))
def set_info(self,name,age):
if not isinstance(name,str):
raise TypeError('姓名必须是字符串类型')
if not isinstance(age,int):
raise TypeError('年龄必须是整型')
self.__name=name
self.__age=age
t=Teacher('egon',18)
t.tell_info()
t.set_info('egon',19)
t.tell_info()</pre>
1.继承与派生
1.什么是继承
继承就是一种新建类的方式,新建的类称为子类或者派生类,被继承的类称之为父类或者基类或者超类
子类会继承所有父类的属性和方法,即可以直接使用这些属性和方法
2.为什么要用继承
减少代码冗余
3.如何使用
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n63" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Parent1:
pass
class Parent2:
pass
class Son1(parent1):
pass
python支持多继承,一个类可以有多个父类,但在java中只能有一个
class Son2(parent1,parent2):
pass
print(Son1.bases) # 查看当前类的所有的基类
print(Son2.bases)
那你是否会好奇想看看我们定义的Parent类它有没有偷偷摸摸的继承谁呢?
print(Parent1.bases)
print(Parent2.bases)
切换python解释器3.x >>> 2.x得出一个结论
"""
在python3中,如果没有显示地继承任何类,那默认继承object类
在python2中,如果没有显示地继承任何类,也不会继承object类
在python中类分为两种:
新式类:
但凡继承object的类,或者该类的子类都是新式类
:在python3中所有的类都是新式类
经典类
没有继承object类,以及该类的子类都是经典类
也就意味着经典类和新式类这对儿概念只在python2中有
python3中只有新式类
"""</pre>
4.基于继承减少代码冗余的案例+派生/衍生
对象与对象之间总结相似的特征与技能得到类 类与类之间总结相似的属性和特征得到父类
http://www.cnblogs.com/linhaifeng/articles/7340153.html
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n67" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 代码实例
import pickle
class OldboyStudent:
school = 'oldboy'
def init(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def choice_course(self):
print('%s is choosing course'%self.name)
def save(self):
with open(self.name,'wb') as f:
pickle.dump(self,f)
class OldboyTeacher:
school = 'oldboy'
def init(self,name,age,sex,level):
self.name = name
self.age = age
self.sex = sex
self.level = level
def score(self):
print('%s is score'%self.name)
def save(self):
with open(self.name,'wb') as f:
pickle.dump(self,f)
stu = OldboyStudent('alex',30,'male')
stu.save()
tea = OldboyTeacher('egon',18,'male',10)
tea.save()
回过头来看,上面的代码是否存在相似的部分。我们刚好学过解决类之间解决代码冗余的方式
class OldboyPeople:
school = 'oldboy'
def save(self):
with open(self.name, 'wb') as f:
pickle.dump(self, f)
初步继承类抽取,思考继承之后对象查找属性和方法的顺序
stu.save()
stu.school
刚刚只是讲属性和方法抽成了父类,但是init里面也有重复的代码,应该也可以抽取
class OldboyPeople:
school = 'oldboy'
def init(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def save(self):
with open(self.name, 'wb') as f:
pickle.dump(self, f)
先不考虑老师和学生init中不同的,先全部继承这个父类统一的init,发现也可以使用到父类的init
派生概念
在子类能够使用父类所有的属性和方法的同时,自身还有一些额外的属性和方法
小思考:如果派生的属性和方法恰巧和父类的一样,那在查找属性和方法的时候先找到谁呢? >>> 还是按查找顺序来
再回过头来看老师的init中有额外的level参数,不应该在父类中添加默认参数,只能自己重写init方法,但是又有重复的代码出现
def init(self,name,age,sex,level):
OldboyPeople.init(self,name,age,sex)
self.level = level
"""
在子类派生出的新方法中重用父类的方法
方式1:指名道姓访问,与继承没有任何关系
OldboyPeople.init(self,name,age,sex)
言外之意还有一种跟继承有关系的能够重用父类的方法的方式,先不着急说
"""</pre>
5.继承原理
刚刚我们一直在讨论的是单继承下属性查找的顺序,那如果是多继承情况呢?
单继承测试
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n71" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Foo:
def f1(self):
print('Foo.f1')
def f2(self): #self=obj
print('Foo.f2')
self.f1() #obj.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj=Bar()
obj.f2()</pre>
多继承
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n73" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># F(A,B,C) 无论是新式类还是经典类,都是从左往右挨个走到底 画图 切换python版本演示,记得加文件头coding:utf-8
2、多继承的属性查找“:对象自己-》对象的类-》从左往右一个一个的分支找下去
class D:
def test(self):
print('D')
pass
class E:
def test(self):
print('E')
class F:
def test(self):
print('F')
class A(D):
def test(self):
print('A')
pass
class B(E):
def test(self):
print('B')
class C(F):
def test(self):
print('C')
class G(A,B,C):
def test(self):
print('G')
pass
obj=G()
obj.test()</pre>
如果是菱型继承的话就不一样了(不考虑object)>>>广度优先!
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n75" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#3、新式类:广度优先
class A(object):
def test(self):
print('from A')
class B(A):
# def test(self):
# print('from B')
pass
class C(A):
# def test(self):
# print('from C')
pass
class D(B):
# def test(self):
# print('from D')
pass
class E(C):
# def test(self):
# print('from E')
pass
class F(D,E):
# def test(self):
# print('from F')
pass
obj=F()
print(F.mro()) # 查找属性的顺序遵循mro列表(只有新式类中才有mro方法)
obj.test()
</pre>
回过头再来看通过继承关系调用父类的方法
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n77" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 方式二:super(自己的类名,self).父类中的方法名()
调用super会得到一个特殊的对象,该对象是专门用来引用父类中的方法的,
具体的:该对象会严格按照当前类的MRO列表从当前类的父类中依次查找属性,即这种方式是严格依赖于继承的
ps:在python3中可以简写为super()
class OldboyPeople:
def init(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyTeacher(OldboyPeople):
def init(self,name,age,sex,level):
# OldboyPeople.init(self,name,age,sex)
super(OldboyTeacher,self).init(name,age,sex)
self.level=level
tea1=OldboyTeacher('egon',18,'male',10)
print(tea1.name,tea1.level)
class A:
def f1(self):
print('A')
super().f2() # super()会基于当前所在的查找位置继续往后查找
def f2(self):
print('A')
class B:
def f2(self):
print('B')
class C(A,B):
def f2(self):
print('C')
obj=C()
print(C.mro())
obj.f1()
</pre>
实际工作中要谨慎使用多继承,编程是解耦合,而继承则是强耦合
6.多态与多态性
1.什么是多态
同一种事物的多种形态(动物:人,猫,狗)
2.为何要用多态
多态性:指的是可以在不用考虑对象具体类型的前提下,直接调用对象的方法
3.如何使用多态
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n87" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Animal:
def talk(self):
pass
class People(Animal):
def talk(self):
print('say hello')
class Dog(Animal):
def talk(self):
print('汪汪汪')
class Pig(Animal):
def talk(self):
print('哼哼哼')
peo1=People()
dog1=Dog()
pig1=Pig()
不用考虑对象具体类型的前提下,直接调用对象的方法
peo1.talk()
dog1.talk()
pig1.talk()
"""
再来想车是不是有很多牌子,你去学车需要说专门学哪个牌子的车的驾驶方式吗?
"""
来你之前也一直在用多态性:不用考虑对象具体类型的前提下,直接调用对象的方法
l=list([1,2,3])
s=str('hello')
t=tuple((4,5,6))
l.len()
s.len()
t.len() # 我不需要考虑这三个具体是什么类型,只要是容器类型就都能调用len这个方法
再来看多态性能够实现的条件是什么?父类有的方法名子类也必须叫这个方法才行
class Animal:
def talk(self):
pass
class People(Animal):
def jiao(self):
print('say hello')
class Dog(Animal):
def han(self):
print('汪汪汪')
class Pig(Animal):
def hou(self):
print('哼哼哼')
多态性能实现的条件就是父类给子类定义了一个标准,动物都必须会叫,并且叫的方法都必须是talk
但是你现在能约束我说子类必须叫这个方法吗?
那有没有一种情况能够做到说子类必须按照父类定义的标准
import abc
class Animal(metaclass=abc.ABCMeta): # 父类存在的意义就是用来定义规范
@abc.abstractmethod
def talk(self):
pass
Animal() # 抽象基类不能被实例化!!!
class People(Animal):
def jiao(self):
print('say hello')
class Dog(Animal):
def han(self):
print('汪汪汪')
class Pig(Animal):
def hou(self):
print('哼哼哼')
上面三个类 一实例化都会报错
但是python推崇的是自由,简约并不希望限制程序员的开发
鸭子类型:只要你长得像鸭子,说话像鸭子,那你就是鸭子!
class People:
def talk(self):
print('say hello')
class Dog:
def talk(self):
print('汪汪汪')
class Pig:
def talk(self):
print('哼哼哼')
再来看linux中:一切皆文件!
class Disk:
def read(self):
print('disk read')
def write(self):
print('disk write')
class Process:
def read(self):
print('process read')
def write(self):
print('processes write')
class Memory:
def read(self):
print('memory read')
def write(self):
print('memory write')
</pre>
7.类中的装饰器
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n89" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># property
人体的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,height,weight):
self.name=name
self.height=height
self.weight=weight
@property
def bmi(self):
return self.weight / (self.height ** 2)
egon=People('egon',1.80,75)
egon.height=1.82
print(egon.bmi())
print(egon.bmi)
了解
class People:
def init(self,name):
self.__name=name
@property
def name(self):
return self.__name
@name.setter
def name(self,val):
# print('=====>准备修改名字的值:',val)
if type(val) is not str:
raise TypeError('名字的值必须为str类型')
self.__name=val
@name.deleter
def name(self):
# del self.__name
print('不让删啊老铁')
classmethod
staticmethod
</pre>
8.反射
通过字符串来获取类或对象的属性或方法
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n92" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#1、反射:指的是通过字符串来操作类或者对象的属性
class People:
country='China'
def init(self,name):
self.name=name
obj=People('egon')
涉及四个内置函数
hasattr
print('country' in People.dict)
print(hasattr(People,'country'))
getattr
print(People.dict['country'])
print(getattr(People,'country'))
print(getattr(People,'country1111',None))
setattr
People.dict['x']=111
print(People.x)
setattr(People,'x',111)
print(People.dict)
delattr
delattr(People,'country')
print(People.dict)
应用
class Ftp:
def get(self):
print('get...')
def put(self):
print('put...')
def auth(self):
print('auth...')
def run(self):
while True:
cmd=input('>>: ').strip() #cmd='get'
if hasattr(self,cmd):
method=getattr(self,cmd)
method()
else:
print('输入的方法不存在')
obj=Ftp()
obj.run()
</pre>
9.内置方法
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n94" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># str
getattr 注意是对象获取自己没有的属性时才会触发(属性和方法)
setattr
</pre>
10.元类
https://www.cnblogs.com/Dominic-Ji/p/10520256.html
异常处理
1.什么是异常?
异常是错误发生的信号,程序一旦出错,如果程序中还没有相应的处理机制,那么该错误就会产生一个异常抛出来,程序的运行也随之终止
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n100" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">print('start')
x = 1
y = 2
if
print('end') # 程序一句也不会运行直接报错,运行前会先检测语法
</pre>
异常分为三部分: 异常的类型(一个个的类) 异常的内容、提示信息 异常的追踪/定位信息信息
异常的分类:
语法上的错误(如上例)
-
逻辑上的错误
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n108" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"># NameError
age = 12
aIndexError
l = [1,2,3]
l[123]KeyError
d = {'name':'jason'}
d['password']
</pre>
2 为何要进行异常处理
增强程序的健壮性
3 如何进行异常处理
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n112" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">try
...
except
...
</pre>
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n113" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#针对逻辑上的异常才应该使用try...except去捕捉异常进行处理
1、异常的单分支(单个except)
2、异常的多分支(多个except)
3、万能异常:Exception,可以匹配所有种类的异常(挨个注释挨个尝试)
try:
age
l=[1,2,3]
l[100]
d={'x':1}
d['y']
import os
os.xxx
except Exception as e: # as语法将错误信息赋值给变量e
print('万能异常')
print(e)
print('其他代码')
4、多分支+Exception,注意Exception一定要放到except 其他异常的的后面
5、try...else,else会在被检测的代码块没有异常发生的情况下执行, else一定要与except连用,并且一定要放到多个except后面
6、try...finally,finally的代码,无论被检测的代码有无异常,都会执行,通常在finally内做一些回收资源的事情
try:
f = open('a.txt','w',encoding='utf-8')
f.read()
finally:
f.close()
print('other...')
7、主动触发异常raise 异常类型(’异常的内容‘)
应用于程序中自定义某种法则,一旦不遵循则会像抛出语法异常一样,终止程序的运行
class People:
def init(self,name):
if not isinstance(name,str):
raise TypeError('%s must be str type'%name)
self.name = name
8、断言
l = [1,2,3]
assert len(l) > 0
9 自定义异常
class MyError(BaseException):
def init(self,msg):
super().init()
self.msg=msg
def str(self):
return '<%s>' %self.msg
raise MyError('我自己定义的异常') # 主动抛出异常其实就是将异常类的对象打印出来,会走str方法
</pre>