Py-上下文管理方法,描述符的应用,错误与异常,下载模块超时

上下文管理方法:

可以在exit里面弄一些内存清理的功能

class Open:
    def __init__(self,name):
        self.name=name
    def __enter__(self):
        print('执行enter')
        return self  #enter返回self
    def __exit__(self,exc_type,exc_val,exc_tb):
        print('执行exit')
f=Open('a.txt') #直接使用时不触发
print('abcd')
with Open('a.txt') as f1: #with as时触发__enter__,然后把enter的返回值作为f1
    print(f)   #也就是self给了f,这里打印的是self的地址
    print(f.name)
    print('_____')
    print('_____')
    print('_____')
    print('_____')  #with as 完成时触发__exit__

 

可以看见一旦with as里面的代码块一旦出现异常直接触发exit

class Open:
    def __init__(self,name):
        self.name=name
    def __enter__(self):
        print('执行enter')
        return self  #enter返回self
    def __exit__(self,exc_type,exc_val,exc_tb):
        print('执行exit')
        print(exc_type)  #异常的种类
        print(exc_val)  #异常的值
        print(exc_tb)  #异常的追踪,不常用
f=Open('a.txt') #直接使用时不触发
print('abcd')
with Open('a.txt') as f1: #with as时触发__enter__,然后把enter的返回值作为f1
    print(f)   #也就是self给了f,这里打印的是self的地址
    print(fafsadasdas)  #可以看见一旦with as里面的代码块一旦出现异常直接触发exit
    print('_____')
    print('_____')
    print('_____')

 

强行跳过异常

class Open:
    def __init__(self,name):
        self.name=name
    def __enter__(self):
        print('执行enter')
        return self  #enter返回self
    def __exit__(self,exc_type,exc_val,exc_tb):
        print('执行exit')
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return True
f=Open('a.txt') #直接使用时不触发
print('abcd')
with Open('a.txt') as f1: #with as时触发__enter__,然后把enter的返回值作为f1
    print(f)   #也就是self给了f,这里打印的是self的地址
    print(fafsadasdas)  #可以看见一旦with as里面的代码块一旦出现异常直接触发exit 
    print('_____')
    print('_____')
    print('_____')
print('ass')

 

描述符的应用:

1.使用描述符来给python加上输入数据的类型检测

class Typed:
    def __get__(self,instance,owner):
        print('get way')
        print(instance)
        print(owner)
    def __set__(self, instance, value):
        print('set way')
        print(instance)   #instance得到的是p1整个实例
        print(value) #value得到的是对name写入的值
class People:
    name=Typed()  #name被描述符代理了
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
#以下弄限制name传入必须是字符串,age必须是整数
#salary必须是浮点数
p1=People('alex',13,13)  #实例化的时候对name进行写入
#由于name被代理了,,于是写入name会触发set
print(p1.__dict__) #可以看见里面没有name,因为它被代理了
p1.name='asdad' #设置也会触发set

 

2.在此基础上可以进行修改,使其具有set的设置值功能

class Typed:
    def __init__(self,key,expect_type):
        self.key=key
        self.expect_type=expect_type
    def __get__(self,instance,owner):
        print('get way')
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print('set way')
        print(self.key)
        if isinstance(value,self.expect_type):
            instance.__dict__[self.key]=value
        else:
            raise TypeError('你传入的不是字符串')
class People:
    name=Typed('name',str)  #name被描述符代理了,同时传入self.name
    age = Typed('age',int)
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
#以下弄限制name传入必须是字符串,age必须是整数
#salary必须是浮点数
p1=People('sasda',13,13)  #输入字符串的时候没有报错
print(p1.__dict__)

 

类的装饰器:

装饰器也可以加到类上

def deco(obj):
    print('-----',obj)
    obj.x=1
    obj.y=2
    return obj
@deco
class Foo:
    pass
print(Foo.__dict__)

 

利用描述符自制property

class diyproperty:
    def __init__(self,func):   #这里装载的是area的地址
        self.func=func  #func也就是area
        print('aaaa')
    def __get__(self, instance,owner):
        print('触发get')
        print('instance是那个r1实例',instance.wid)
        print(instance.wid)
        print(instance.len)
        res=self.func(instance) #在这里可以执行area函数
        return res
class room:
    def __init__(self,name,wid,len): 
        self.name=name
        self.wid=wid
        self.len=len
    @diyproperty  #area=property(area), are被代理了
    def area(self):
        return self.wid * self.len
r1=room('cesuo',10,10)  #将其实例化得到r1
print(r1.area)    #r1.area不写括号直接触发代理的get

 

元类:

元类是类的类,是类的模板
元类就是type
 

错误与异常:

错误:语法错误和逻辑错误

异常:是程序运行发生错误时的跳出信号

attrierror试图访问没有的属性出错
ioerror输入输出异常
importerror无法引入模块或者包
keyerror试图访问字典里面不存在的键
keyboardinterrupt ctrl+c被按下
nameerror 使用了一个还未被复制的对象的变量
synataxerror  python代码非法,语法错误
typeerror 传入类型和要求的不符合
unboundlocalerror  试图访问一个还未被设置的局部变量
valueerror传入一个调用者不期望的值

异常处理:在发生崩溃时进行异常处理操作,防止程序

直接跳出

1.如果错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防

AGE=10
while True:
    age=input('>>: ').strip() #strip为去除空格
    if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
        age=int(age)
        if age == AGE:
            print('you got it')
            break

 

2.如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理

基本语法为
try:
    被检测的代码块
except 异常类型:
    try中一旦检测到异常,就执行这个位置的逻辑
#举例
try:
    a=input('输入一个数字')
    a=int(a)
    print(a)
except ValueError as wrong:
    print('其实错了,应该被强退的')
    print(wrong)

 

3.上面这是检查值错误的,下面这是检查尺寸错误的

try:
    a=[123456]
    print(a[10])
except IndexError as wrong:
    print('其实错了,应该被强退的')
    print(wrong)

 

4.由此这些可能会出现很多很多异常,不同的需要写不同的很麻烦

因此需要万能异常Exception,它哪种异常都能捕捉得到

try:
    b='sata'
    int(b)
    a=[123456]
    print(a[10])
except Exception as wrong:
    print('其实错了,应该被强退的')
    print(wrong)

 

5.如果需要不同的异常用不同的处理方式用多分支

s1 = 'hello'
try:   #相应的异常先检测完,最后如果有没想到的异常用Exception吸收掉
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)

 

6.更加优良的结构

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)
else:
    print('try内代码块没有异常则执行我')
finally:
    print('无论异常与否,都会执行该模块,通常是进行清理工作')

 

7. 主动触发异常(raise)

try:
    raise TypeError('类型错误')
except Exception as e:
    print(e)

 

8.自定义异常

class zqhException(BaseException):
    def __init__(self,msg):
        self.msg=msg
try:
    raise zqhException('类型错误')
except zqhException as e:
    print(e)

 

9.assert断言条件

assert res ==1
等同于
if res !=1:
    raise AssertionError
相当于如果不是断言条件直接报错
 

python用htm下载安装超时

pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.
解决方法:pip --default-timeout=100 install pandas -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
还是不能解决的话:pip --default-timeout=1000 install -U 模块名

pip有问题,显示no module named pip

输入python -m ensurepip   直接重装pip
posted @ 2020-10-16 21:33  克莱比-Kirby  阅读(104)  评论(0)    收藏  举报