Python第六章 面向对象 – Python量化投资

Python第六章 面向对象

目录

第六章 面向对象

1.面向对象初了解

​ 面向对象的优点:

​ 1.对相似功能的函数,同一个业务下的函数进行归类,分类

​ 2.类是一个公共的模板,对象就是从具体的模板中实例化出来的,得到对象就得到一切

类:具有相同属性和功能的一类事物

对象:某个类的具体表现

2.面向对象的结构

class Human:#类名不要用下划线
    #第一部分:静态属性
    mind = '有思想' #类的属性 (静态属性,静态字段)
    
    #第二部分:动态方法
    def eat(self):#方法
        print('人类都需要吃饭')

3.从类名的角度研究类

1.类名查看类中所有的内容

print(Human.__dict__)
#结果:
#{'__module__': '__main__', 'mind': '思想', 'eat': <function Human.eat at 0x000001AD41659D08>, '__dict__': <attribute '__dict__' of 'Human' objects>, '__weakref__': <attribute '__weakref__' of 'Human' objects>, '__doc__': None}

2.类名操作类中的静态属性 (万能的点)

​ 1.增:

Human.body = '有躯体'
print(Human.__dict__)

​ 2.删:del Human.mind

del Huamn.mind

​ 3.改:Human.mind = ‘live脑残’

Human.mind = 'live脑残'

​ 4.查:print(Human.mind)

print(Human.mind)

3.类名调用类中的方法

​ 一般类中的(除了静态方法和类方法)方法不会通过类名调用

Human.eat(1)#self,需要传参,对象不需要,默认传对象名

4.从对象的角度研究类

1.实例化对象:

obj = Human()#实例化过程
#得到一个返回值,返回值就是对象,实例

2.实例化一个对象发生三件事:

​ 1.开辟一个对象空间。

1564719073842

​ 2.自动执行object中的__new__()方法,在内存中开辟一个对象空间.

​ 3.运行__init__方法内的代码,给对象空间封装属性

class Human:
    mind = '有思想' 
    
    def __init__(self,name,age):
        self.name = name
        self.age = age
   
    def eat(self):
        print('人类都需要吃饭')
obj = Human()#将obj传给了self,自动执行__init__()函数
print(obj)#结果:<__main__.Human object at 0x00000210B6A48E80>
#传参:
obj = Human('qq',18)
print(obj.name,obj.age)
'''
结果:qq 18
'''
print(obj.__dict__)#对象的属性,字典的形式
'''
结果:{'name': 'qq', 'age': 18}
'''

3.对象操作对象空间的属性

1.对象查看对象空间的所有属性:

​ 1.print(obj.__dict__):

obj = Human('qq',18)
print(obj.__dict__)
2.对象操作对象空间的属性

​ 1.增:obj.sex = ‘laddy_boy’

​ 2.删:del obj.age

​ 3.改:obj.age = 58

​ 4.查:print(obj.sex)

4.对象查看类中的属性

​ 对象不允许修改类中的属性,只允许查看。

obj = Human('qq',18)
print(obj.mind)#通过对象查看类中的属性
obj.mind = '无脑'
print(obj.mind)
print(Human.mind)
'''
类中的属性并没有更改,而是对象中新增了mind属性
'''

5.对象调用类中的方法

class Human:
    mind = '有思想'
    def __init__(self,name,age):
        self.name = name
        self.age = age
   
    def eat(self):
        print(f'{self.name}都需要吃饭')
    def work(self):
        print(f'{self.name}都会工作')
obj = Human('戴维',23)
obj.work()
obj.eat()

6.一个类可以实例化多个对象

obj1 = Human('戴维',20)
obj2 = Human('杰西',22)
obj3 = Human('肉丝',18)

5.类的空间问题

​ 1.添加对象的属性

#1.在类的__init__中添加,
#2.在类的方法中添加
def eat(self,argv):
    self.sex = '女'
#3.在类的外部添加
sun = Human('孙','18')
sun.weight = 120

​ 2.添加类的属性

#1.类的内部,直接定义
#2.类的外部:
Human.body = '有头有脸'

​ 3.对象空间与类空间的关系

当对象空间与类空间有相同的的名字,对象. 要先从对象空间查找

查询顺序:

对象.名字:对象空间 _类对象指针_ –>类空间 — >父类空间

类名.名字:类空间 –> 父类空间

6.类与类之间的关系

1.依赖关系:

​ 有主从之分,将一个类的类名或者对象传入另一个类的方法中

class Elephant:#主
    def __init__(self,name):
        self.name = name
    def open(self,obj):
        print(f'{self.name}打开冰箱')
        obj.be_open()
class Fire:#从
    def __init__(self,name):
        self.name = name
    def be_open(self):
        print(f'{self.name}冰箱被打开了')
        
qiqi = Elephant('琪琪')
haier = Fire('海尔')
qiqi.open(haier)
'''
结果:
琪琪打开冰箱
海尔冰箱被打开了
'''
2.组合关系:

​ 给一个类的对象封装一个属 性,此属性为另一个类的对象(类名)

class Game:
    def __init__(self,name,ad,hp):
        self.name = name
        self.ad = ad
        self.hp = hp
    def attrck(self,p):
        '''
        2.
        #p.hp = p.hp - self.ad - self.weap.a
        d
        #print(f'{self.name}使用{self.weap.name}攻击{p.name},掉了{self.ad+self.weap.ad},还剩{p.hp}')
        '''
    def equipment(self,weap):
        self.weap = weap
class Weapon:
    def __init__(self,name,ad):
        self.name = name
        self.ad = ad
    def weappon(self,p1,p2):
        #1. p2.hp = p2.hp - p1.ad - self.ad
        #1. print(f'{p1.name}使用{self.name}攻击{p2.name},{p2.name}掉了{p1.ad+self.ad}血量,{p2.name}还剩{p2.hp}')
gailun = Game('盖伦',10,100)
zhaoxin = Game('赵信',20,80)
baojian = Weapon('大宝剑',20)
changqiang = Weapon('长枪',15)
#1. gailun.equipment(baojian)
# 1.gailun.weap.weappon(gailun,zhaoxin)
# 1.zhaoxin.equipment(changqiang)
# 1.zhaoxin.weap.weappon(zhaoxin,gailun)
'''
2.
gailun.equipment(baojian)
gailun.attrck(zhaoxin)
gailun.attrck(zhaoxin)
'''

7.继承

1.初识继承:

​ 专业角度:如果B类继承A类,B类就称为子类、派生类。A类就称为父类、基类、超类。

​ 面向对象三大特性:封装、继承、多态

最顶级父类就是object

2.继承的优点:

​ 1.减少重复代码

​ 2.增加类之间的耦合性

​ 3.使代码更加清晰,流畅

3.继承:单继承,多继承

1.单继承:

​ 查询顺序单项不可逆:子类可使用父类的属性方法,父类不可使用子类的属性方法

​ 1.1 类名执行父类属性方法,对象执行父类属性方法

class Animal:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
class Human(Animal):
    pass
class Dog(Animal):
    pass
class Cat():
    pass
#Animal:父类
#Human,Dog:子类
person = Human('C罗','男',18)
#cat1 = Cat()#默认为继承object

1.2 既执行子类的方法,又执行父类的方法

方案一:不依赖于继承,使用函数的调用

方案二:依赖于继承。super(),

执行父类的方法。称为重构

class Animal:
    def __init__(self,name,sex,age):
        self.name = name
        self.sex = sex
        self.age = age
        pass
    def eat(self):
        print('动物都需要吃饭')
class Human(Animal):
    def __init__(self,name,sex,age,hobdy):
     
 #方案一   #Animal.__init__(self,name,sex,age)#需要传入人类对象,姓名,性别,年龄
      
 #方案二:   #super(Huamn,self).__init__(name,sex,age)#完整写法
        super().__init__(name,sex,age)#简写
        self.hobdy = hobdy
        pass
    def eat(self):
        super().eat()
        print(f'{self.name}需要吃饭')
human1 = Human('涛涛','雌','48','唱跳')
print(human1.__dict__)
human1.eat()
'''
结果:
{'name': '涛涛', 'sex': '雌', 'age': '48', 'hobdy': '唱跳'}
动物都需要吃饭
涛涛需要吃饭
'''
2.多继承:

python中类分为两种:

python2.x:python 2.2之前都是经典类,python2.2之后,经典类与新式类共存

python3.x:全是新式类

​ 1.经典类:不继承object类,遵循深度优先原则:从左至右。

​ 2.新式类:继承object类,遵循mro(C3)算法

关于mro算法:

  1. mro序列:
class B(A):
    pass
mro(B) = mro(B(A))
       = [B] + merge(mro(A) + [A])
       = [B,A]
  1. 表头和表尾

表头:列表的第一个元素

表尾:列表中除表头以外的所有元素(可以为空)

+操作:[A] + [B] = [A,B]

  1. merge规则:
如计算merge( [E,O], [C,E,F,O], [C] )
有三个列表 :  ①      ②          ③
1 merge不为空,取出第一个列表列表①的表头E,进行判断                              
   各个列表的表尾分别是[O], [E,F,O],E在这些表尾的集合中,因而跳过当前当前列表
2 取出列表②的表头C,进行判断
   C不在各个列表的集合中,因而将C拿出到merge外,并从所有表头删除
   merge( [E,O], [C,E,F,O], [C]) = [C] + merge( [E,O], [E,F,O] )
3 进行下一次新的merge操作 ......
  1. mro算法实例:print(A.mro())
class O:
    name = 'qq'
class D(O):
    pass
class E(O):
    name = 'wx'
    # pass
class F(O):
    name = 'taobao'
class B(D,E):
    pass
class C(E,F):
    pass
class A(B,C):
    pass
obj = A()
print(obj.name)
print(A.mro())#直接得出mro算法求出的顺序
"""
mro(A(B,C)) = [A] + merge(mro(B),mro(C),[B,C])#多继承
mro(B(D,E)) = [B] + merge(mro(D),mro(E),[D,E])#单继承:mro(D(O)) = [D,O]
            = [B] + merge([D,O],[E,O],[D,E])#拿出并删除D
            = [B,D] + merge([O],[E,O],[E])
            = [B,D,E] + merge([O],[O])
            = [B,D,E,O]
            
mro(C(E,F)) = [C] + merge(mro(E),mro(F),[E,F])
            = [C] + merge([E,O],[F,O],[E,F])
            = [C,E] + merge([O],[F,O],[F])
            = [C,E,F] + merge([O],[O])
            = [C,E,F,O]
        
mro(A(B,C)) = [A] + merge([B,D,E,O],[C,E,F,O],[B,C])
            = [A,B] + merge([D,E,O],[C,E,F,O],[C])
            = [A,B,D] + merge([E,O],[C,E,F,O],[C])
            = [A,B,D] + merge([O],[C,E,F,O],[C])
            = [A,B,D,C] +merge([O],[E,F,O])
            = [A,B,D,C,E,F,O]
所以:mro()算法得出的顺序为:A-->B-->D-->C-->E-->F-->O
"""

8.封装、多态和鸭子类型

​ 1.封装:把数据代码放到一个空间,并且可以使用(函数)

​ 2.多态:一个事物可呈现多种形态

python默认支持多态,一个变量可以指向多种数据类型

鸭子类型:python崇尚鸭子类型(编程思路),看起来像,就是鸭子。对相同的功能定义相同的名字。

鸭子的优点:

​ 1.好记

​ 2.虽然A,B两个类没有关系,但是统一两个类中相似方法的方法名,在某种意义上统一标准

class A:
    def login(self):
        print('登录')
class B:
    def login(self):
        print('登录')
'''
A,B互为鸭子。
'''

9.类的约束

方法一:python语言惯于使用的一种约束方式,在父类主动抛出错误

class Payment:
    def pay(self):
        raise Exception('你的子类未定义pay方法')#主动报错,起到约束作用
        
class QQ_pay(Payment):
    def pay(self,money):
        print(f"QQ成功支付{money}元")
      
class Ali_pay(Payment):
    def pay(self,money):
        print(f"支付宝成功支付{money}元")
  
class Wechat(Payment):
    def fukuan(self,money):
        print(f"微信成功支付{money}元")
def pay(obj,money):#归一化设计:统一接口
    obj.pay(money)
    pass
#使用Wechat实例化对象并调用pay函数,就会主动报错。       

方法二:借鉴于java语言,定义抽象类的概念,做到真正的强制约束

from abc import ABCMeta,abstractmethod
#抽象类,接口类:强制制定规则
class Paymet(metaclass=ABCMeta):#指定元素
    @abstractmethod
    def pay(self,money):
        pass
class QQ_pay(Paymet):
    def pay(self,money):
        print(f"QQ成功支付{money}元")
class Wechat(Paymet):
    def fukuan(self,money):
        print(f"微信成功支付{money}元")
def pay(obj,money):
    obj.pay(money)
obj = Wechat()
'''
在实例化对象时就会报错
 obj = Wechat()
TypeError: Can't instantiate abstract class Wechat with abstract methods pay
'''

10.super的深度剖析

严格按照对象从属于类的mro的执行顺序执行,查询下一个类

class A:
    def f1(self):
        print('in A')
class Foo(A):
    def f1(self):
        super().f1()
        print('in Foo')
class Bar(A):
    def f1(self):
        print('in Bar')  # 1
class Info(Foo,Bar):
    def f1(self):
        super(Foo,self).f1()
        print('in Info f1')  # 2
# [Info --> Foo --> Bar --> A]
obj = Info()
obj.f1()

11.类的关于

1.类的私有成员:

​ 在类的内部可以访问,外部不可访问,也不可在类的派生类中使用。

​ 当遇到重要的数据,功能,(只允许本类使用的)使用私有成员

类的私有成员:类的私有属性、类的私有方法、对象私有属性

class A:
    name = '涛涛'
    __name = '套套'
    def func(self):
        print(self.name)
        print(self.__name)
obj = A()
obj.func()
#可以访问
obj.__name#不可访问,会报错
#如何访问私有属性:
print(A.__dict__)
#{'__module__': '__main__', 'name': '涛涛', '_A__name': '套套', 'func': <function A.func at 0x00000237FC0F9D08>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}##会发现私有属性都被加上了'_类名+私有名'
#所以调用
print(A._A__name)

2.实例方法、类方法

1.实例方法:默认参数为self的方法

2.类方法:

​ 一般就是通过类名去调用的方法,并且自动将类名地址传给cls,但是如果通过对象调用也可以,但传的地址还是类名地址

类方法作用:

​ 1.得到类名可以实例化对象。

​ 2.可以操作类的属性

class A:
    @classmethod
    def cls_func(cls):
        print(f'cls'--->{cls})
        #实例化对象
        obj = cls()
        print(obj)
print(A)
A.cls_func()
obj1 = A()
obj.cls_func()       

3.静态方法:

​ 静态方法不依赖对象与类。静态方法就是函数

作用:保证代码的规范性,合理的划分,提高代码后续维护性。

class A:
    @staticmethod
    def static_func():
        print('静态方法')

4.属性:

将执行一个函数需要函数名()变成直接函数名,将动态方法伪装成一个属性,虽然代码级别上没有提升,但是使其看起来更合理(本质还是方法)

class Bmi:
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.weight = weight
    @property
    def bmi(self):
        self.BMI = self.weight / self.height**2
        print(self.BMI)
p1 = Bmi('w',1.75,74)
p1.bmi

property是一个组合:

​ 应用场景:1.面试考调用流程

​ 2.工作中如果遇到一些类似属性的方法名,可以让其伪装成属性

设置属性的两种方式:后两个return是无效的,得不到。

1.利用装饰器设置属性

class Foo:
    @property
    def bmi(self):
        print('get的时候运行我')
    @bmi.setter
    def bmi(self,value):
        print('set的时候运行我')
        print(value)#return得不到
    @bmi.deleter
    def bmi(self):
        print('delete时运行我')    
    
obj = Foo()
obj.bmi
obj.bmi = 666#不是改变值,而是调用@bmi.setter装饰下的函数
del obj.bmi     

2.利用实例化对象的方式设置属性

class Foo:
    def get_A(self):
        print('get的时候运行我')
    def set_A(self,value):
        print('set的时候运行我')
        print(value)
    def delete_A(self):
        print('delete的时候运行我')
    A = property(get_A,set_A,delete_A)#内置三个参数,与get,set,delet一一对应
f1 = Foo()
f1.A
f1.A = '666'
del f1.A

5.内置函数:isinstance,issubclass

isinstance:判断的是对象与类的关系True/False

isinstance(a,b):判断对象a是否是b类或者b类的派生类实例化的对象

class A:
    pass
class B(A):
    pass
class C:
    pass
obj = B()
print(isinstance(obj,B))
print(isinstance(obj,A))
print(isinstance(obj,C))
"""
结果:
True
True
False
"""

issubclass:类与类的关系 True/False

issubclass(a,b):判断a类是否是b类的子孙类

class A:
    pass
class B(A):
    pass
class C:
    pass
print(issubclass(B,A))
print(issubclass(C,A))
"""
结果:
True
False
"""

12.元类type

type:获取对象从属于的类

python中一切皆对象,类在某种意义上也是一个对象,python中自己定义的类以及大部分内置类,都是有type元类(构建类)实例化来的

type与object的关系:

print(type(object))
#object类是type类的一个实例
print(issubclass(type,object))
#type类是object类的子孙类

13.反射

​ 程序对自己内部代码的一种自省方式

反射是什么:通过字符串去操作对象的方式

反射是一个组合:hasattr、getattr、setattr、delattr(四个内置函数)

1.实例化对象的角度:
class Human:
    country = '中国'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        print('is func')
obj = Human('涛涛',80)
#hasattr、getattr
#hasattr返回True/False,getattr获取对象,没有会报错,可设置默认返回值
print(hasattr(obj,'name'))
f = getattr(obj,'func')
f()
#setattr,delattr用的少
#setattr:添加属性,delattr删除属性
setattr(obj,'sex','男')
print(obj.__dict__)
delattr(obj,'name')
print(obj.__dict__)
2.从类的角度:
class Human:
    country = '中国'
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        print('is func')
        
if hasattr(A,'country'):
    print(getattr(A,'country'))
3.从其他模块:
import other
#找到other.py对象的A类,实例化对象
print(getattr(other,'A'))
obj = getattr(other,'A')('涛涛')
#对实例化对象反射取值
print(getattr(obj,'name'))
4.从当前模块:
import sys
print(sys.modules[__name__])#获取当前文件对象名
def func1():
    print('in 本模块这个对象')
    pass
getattr(sys.modules[__name__],'func1')()
#当本文件有很多函数(名字递增),反射调用所有函数:
func_list = [f'func{i}' for i in range(1,5)]
for func in func_list:
    getattr(sys.modules[__name__],func)()

14.函数与方法的区别

​ 1.总结:函数都是显性传参,方法都有隐形传参

python 中一切皆对象, 类在某种意义上也是一个对象,python中自己定义的类,以及大部分内置类,都是由type元类(构建类)实例化得来的.

python 中一切皆对象, 函数在某种意义上也是一个对象,函数这个对象是从FunctionType这个类实例化出来的.

python 中一切皆对象, 方法在某种意义上也是一个对象,方法这个对象是从MethodType这个类实例化出来的.

1.通过打印函数名的方式区分什么是方法,什么是函数
def func1():
    pass
class A:
    def func2():
        pass
    pass
print(func1)
print(A.func2)
"""
通过类名调用的类中的方法叫做函数,结果:
<function func1 at 0x0000022B99002F28>
<function A.func2 at 0x0000022B9ACDABF8>
"""
obj = A()
print(obj.func2)
"""
通过对象调用的方法叫方法,结果:
<bound method A.func2 of <__main__.A object at 0x0000022B9ACD9198>>
"""
2.借助模块判断是方法还是函数
from types import FunctionType
from types import MethodType
def func():
    pass
class A:
    def func(self):
        pass
obj = A()
#FunctionType:判断是否为函数
#MethodType:判断是否为方法
print(isinstance(func,FunctionType))  # True
print(isinstance(A.func,FunctionType))  # True
print(isinstance(obj.func,FunctionType))  # False
print(isinstance(obj.func,MethodType))  # True

15.特殊双下方法

​ 双下方法:原来是开发python的程序员在源码中使用的。

双下方法:你不知道你干了什么就触发了双下方法

双下方法要慎用。

1.__len__():

​ 必须有返回值且返回值必须为int型

#计算实例化对象的属性个数
class B:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __len__(self):#返回对象的属性个数
        return len(self.__dict__)
    pass
b = B('taotao',23)
print(b.len(b))
2.__hash__():

​ 获取哈希值,必须有返回值且返回值必须是可哈希类型

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __hash__(self):
        return hash(str(self.a)+str(self.b))
    pass
a =A()
print(hash(a))
3.__str__()、__repr__():

​ 打印对象时触发,二者同时存在时,只执行__str__()。(str对象或repr对象也会触发)–>必须有返回值且返回值必须为字符串

class A:
    def __init__(self):
        pass
    def __str__(self):
        return '哈哈'
    def __str__(self):
        return '嘿嘿'
    pass
a = A()
print(a)
print(str(a))
print('%s'%a)
print(repr(a))
4.__call__():****

​ 当对象后面加括号或类()()触发执行从属于类(父类)的__call__方法

class Foo:
    def __init__(self):
        pass
    def __call__(self,*args,**kwargs):
        print('__call__')
obj = Foo()
obj()
5.__eq__():

​ 判断是否相等

class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __eq__(self,obj):
        if self.a == obj.a and self.b == obj.b:
            return True
a = A()
b = A()
print(a == b)
6.__del__():

​ 析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

class A:
    def __del__(self):
        print(666)
obj = A()
del obj
7.__new__():***

​ new一个对象,构造方法

类名()

  1. 先触发 object的__new__方法,此方法在内存中开辟一个对象空间.
  2. 执行__init__方法,给对象封装属性.

1.__new__方法:

class A:
    def __init__(self):
        self.x = 1
        print('in init function')
    def __new__(cls,*args,**kwargs):
        print('in new function')
        return object.__new__(A)#object类中的方法
    pass
#对象时object类中的__new__方法产生了一个对象。
a = A()
#先执行__new__,在执行__init__,__init__中不能有return

2.python中的设计模式: 单例模式

​ 一个类只允许实例化一个对象

优点:节省内存

#单例模型
class A:
    __instance = None
    def __init__(self,name):
        self.name = name
    def __new__(cls,*args,**kwargs):
        if not cls.__instance:
            cls.__instance = obj.__new__(cls)
        return cls.__instance
    pass
obj = A('alex')
print(obj)
obj1 = A('taotao')
print(obj1)
8.__item__():系列

​ __getitem__ ()、__setitem__()、__delitem__():对象做类似于字典的(增删改查)触发item系列

__delattr__():对象. 属性 触发此方法

class Foo:
    def __init__(self,name):
        self.name = name
    def __getitem__(self, item):#查
        print(item)
        return self.__dict__[item]
    def __setitem__(self, key, value):#增、改
        self.__dict__[key] = value
        print(self.__dict__)
    def __delitem__(self, key):#删
        super().__delattr__(key)
        print(self.__dict__)
    #删对象.属性触发
    def __delattr__(self, item):
        super().__delattr__(item)
        print(self.__dict__)
        print(item)
f1 = Foo('sb')
print(f1['name'])
f1['ac'] = 2
del f1['ac']
print(f1.__dict__)
# del f1.ac
# print(f1.name)
9.__enter__()、__exit__ () with,上下文管理

实例化对象的第二种方式:必须基于enter和exit这两个方法

class A:
    def __init__(self,name):
        self.name = name
    def __enter__(self):#开启上下文管理器对象时触发此方法
        self.name = self.name + '侬好' #第一步
        print(111)
        return self 
        #!!!必须写,将实例化的对象(self)返回
    def __exit__(self, exc_type, exc_val, exc_tb):# 执行完上下文管理器对象f1时触发此方法
        print(333)#第三步
        self.name = self.name + '好个鸡儿'
with A('sb') as obj:
    print(222)
    print(obj.name)#第二步
print(obj.name)#第四步
"""结果:
111
222
sb侬好
333
sb侬好好个鸡儿"""
10.__iter__():将对象变成可迭代对象
class A:
    def __init__(self,name):
        self.name = name
        
    def __iter__(self):
        for i in range(10):
            yield i
    def __next__(self):
        pass
obj = A('sb')
# print('__iter__'in dir(obj))
for i in obj:
    print(i)
print(obj.name)
o = iter(obj.name)
print(next(o))

16.异常处理:

异常处理的好处:

  1. 用户的体验良好
  2. 使代码更健壮性,容错性

1.错误分类:语法错误,逻辑错误

如果你对错误信息不关心,只是想要排除错误让程序继续运行. 用万能异常

#万能异常:处理所有python识别的异常
try:
    pass
except Exception as e:
    print(e)
    pass
#单,多分支异常结构:你对错误信息要进行明确的分流,让你的程序多元化开发.  
  1. try else finally

​ except 必须依赖try,else必须依赖except和try,finally只依赖try

finally:在异常出现之前,执行finally中的语句

try:
    pass
except:
    pass
else:
    print('如果没有异常则执行这里')
finally:
    print(666)
  1. finally用处:用在关闭数据库连接,文件句柄关闭,数据保存等。
with open('test1.txt','r+',encoding = 'utf-8') as f:
    try:
        for i in f1:
            print(i)
    finally:
        f1.close()#防止出现异常,文件不能关闭。
  1. 在return结束函数之前,执行finally代码,在break之前执行:
def func():
    try:
        print(111)
        return 333
    finally:
        print(222)
        pass
    pass
print(func())
"""结果:
111
222
333"""
#在break之前执行
while 1:
    try:
        print(111)
        break
    finally:
        print(222)
    
  1. 主动触发异常:
raise ValueErro('出现了value错误')
  1. 断言:展现一种强硬的态度
#assert  条件
name = 'sb'
n1 = input('name:')
assert name == n1
print(111)
#如果name 不等于 n1 ,会直接报错
  1. 自定义异常

python中提供了很多错误类型,但不是全部的错误

class SbError(BaseException):#自定义的错误必须继承于BaseException
    def __init__(self,msg):
        self.msg = msg
     
    def __str__(self):
        return self.msg
try:
    raise SbError('你犯错了')
except SbError as e:
    print(e)
  
"""结果:你犯错了"""

https://www.cnblogs.com/Onlywang/p/11461771.html

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论