• 异常处理,内置方法(__new__,__init__,__del__析构方法,单例模式,item系列)


    __new__ 创建一个对象

    class A:
        def __init__(self):
            print('in init')
        def __new__(cls):
            print('in new')
            self=object.__new__(cls)#创建一个对象
            return self #再返回给self
    # object.__new__()#创造对象
    a=A
    __new__ 构造方法
    __init__ 初始化方法

    算法和设计模式
    设计模式--java开发过程中的一种规范或者设计模式

    单例模式*****
    创造一个类,这个类始终只有一个实例 ——单例模式
    class A:
        __mmp=None
        def __init__(self,name):
            self.name=name
        def __new__(cls,*args,**kwars):
            if not cls.__mmp:
                cls.__mmp=object.__new__(cls)#创造一个空间(对象),cls相当于A
            return cls.__mmp#再返回给self
    a=A('aaa')
    b=A('bbb')
    print(a)#打印的是内存地址
    print(b)#a,b内存地址相同
    print(a.name)#bbb
    print(b.name)#bbb

    图解

    __del__析构方法
    对应着一个对象删除之前执行的内容
    @property deleter 将方法伪装成属性,执行删除该属性
    delattr 使用字符串变量名从命名空间中删除这个变量
    class B:
        def __del__(self):print('执行我了')#2
    b=B()
    print(b.__dict__)#{} 1
    del b #调用__del__方法,从内存中将d删除  3
    print(b.__dict__)
    python 解释器
    能够主动回收不用的变量
    在程序结束的时候所有的数据都会被清除
    如果用户主动删除某个变量
    那么这个变量将会主动被删除
    无论上述哪种方法
    在删除一个变量之前都会主动的执行析构方法__del__
    class B:
        def __init__(self,path):
            self.f=open(path)
        def __del__(self):#对象删除之前回归一些系统资源
            self.f.close()
    b=B('userinfo')
    item 系列--打辅助的功能
    实现了之后,就可以使用对象[]去做一些事情了
    lst=[1,2,3]
    print(lst[0])
    dic={'k':'v'}
    print(dic['k'])
    有些内置模块中的内置方法
    是依赖__getitem__方法的
    或者说是依赖item['a']这种调用方式的
    class Item:
        def __getitem__(self,item):  # ***
            print('-->',item)
            return 'hello'
        def __setitem__(self,key,value):
            print(key,value)#a,b
    
    item=Item()
    print(item['a'])#--> a   hello 此时的item['a']是查看值,调用的是__getitem__函数
    item['a']='b'#赋值时调用的是__setitem__函数
    print(item['a'])#--> a   hello
    此时__getitem__和__setitem__没有一点关系
    
    
    class Item:
        def __getitem__(self,item):  # ***
            print('-->',item)
            return self.__dict__[item]
        def __setitem__(self,key,value):
            self.__dict__[key]=value
            print(key,value)#a,b
    
    item=Item()
    print(item.__dict__)#{}
    # print(item['a'])#不能先调用self.__dict__[item],此时self没值,self.__dict__空间是空的,会报错。
    item['a']='b'#赋值时调用的是__setitem__函数
    print(item['a'])#--> a   hello 此时的item['a']是查看值,调用的是__getitem__函数
    此时__getitem__和__setitem__没有一点关系
    
    
    class Item:?
        def __getitem__(self,item):  # ***
            print('-->',item)
            return self.__dict__[item]
        def __setitem__(self,key,value):
            self.__dict__[key]=value
            print(key,value)
        def __delitem__(self,key):
            self.__dict__.pop(key)
    item=Item()
    print(item.__dict__)#{}
    # print(item['a'])#不能先调用self.__dict__[item],此时self没值,self.__dict__空间是空的,会报错。
    item['a']='b'#a,b
    print(item['a'])#-->a, b    ?
    print(item.a)#b    ?
    print(item.__dict__)#{'a': 'b'}
    # del item.a
    del item['a']
    print(item.__dict__)#{}
    python魔法方法__len__,__getitem__,__setitem__,__delitem__
    python中除了可以使用内建的类型,如list,tuple,dict,还可以创建自己的对象来实现像这些内建类型的访问,
    不过需要在定义类的时候对一些魔法方法逐一实现
    class DictDemo:
          def __init__(self,key,value):
                self.dict = {}
                self.dict[key] = value
          def __getitem__(self,key):
                return self.dict[key]
          def __setitem__(self,key,value):
                self.dict[key] = value
    dictDemo = DictDemo('key0','value0')
    print(dictDemo['key0']) #value0
    dictDemo['key1'] = 'value1'
    print(dictDemo['key1']) #value1
    上面的对象就相当于自己创建了一个内建类型相似的字典,当实例中有类似字典的操作的时候
    比如:
    [python] view plain copy
    dictDemo1 = {"key0":"value0"}
    print(dictDemo1["key0"]) #value0
    实例dictDemo["key0"]就类似上面的的操作,则会自动调用类中定义的方法__getitem__,输出在该方法返回的值
    再看看dictDemo["key1"] = "value1",就是字典的操作,会自动调用类中定义的方法__setitem__,来设置相应的值

    还有一个__del__,就是当我们要删除一个元素的时候调用(魔法方法会自动调用)

    __len__ 如下:

    当要使用内建函数len(),而参数是DictDemo的实例的时候,那一定要实现类型中的__len__()方法
    [python] view plain copy
    class DictDemo:
        def __init__(self,key,value):
            self.dict = {}
            self.dict[key] = value
        def __getitem__(self,key):
            return self.dict[key]
        def __setitem__(self,key,value):
            self.dict[key] = value
        def __len__(self):
            return len(self.dict)
    dictDemo = DictDemo('key0','value0')
    print(dictDemo['key0']) #value0
    dictDemo['key1'] = 'value1'
    print(dictDemo['key1']) #value1
    print(len(dictDemo)) #2
    
    
    class List(list):
        def append(self, obj):
            if type(obj) is str:
                super().append(obj)#调用父类的方法,list.append(obj)
            else:
                # print(f'{obj}不是字符串类型')
                print('%s不是字符串类型' % obj)
    
        def show_middle(self):
            return self[int(len(self) / 2)]#返回以长度的一半为索引的self的值
    
    
    li = List('hello word22222')#['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'd', '2', '2', '2', '2', '2', '18', 'abc']
    li.append('18')
    li.append('abc')
    print(li)
    print(li.show_middle())#r
    扑克牌
    from collections import namedtuple
    Card = namedtuple('Card',['rank','suit'])  # 属性一旦创建就不再改变了,且可以使用属性名直接访问值
    card1 = Card('K','黑桃')
    print(card1.rank)
    print(card1.suit)
    
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
    deck = FranchDeck()
    # print(deck._cards[0])   #
    print(deck[0])
    from random import choice
    print(choice(deck))   # choice接收iterable,__len__,__getitem__
    print(choice(deck._cards))   # choice接收iterable,__len__,__getitem__
    print(choice(deck))
    print(choice(deck))
    print(choice(deck))
    print(choice(deck))
    
    
    from collections import namedtuple
    Card = namedtuple('Card',['rank','suit'])
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')
        suits = ['红心','方板','梅花','黑桃']
    
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self, item):
            return self._cards[item]
    
        def __setitem__(self, item,value):
            self._cards[item]  = value
    
    deck = FranchDeck()
    from random import shuffle
    # shuffle(deck._cards)
    # print(deck._cards)
    shuffle(deck)     # __len__(self) __getitem__ __setitem__
    print(deck._cards)

    异常处理

    捕捉异常可以使用try/except语句。

    try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。

    如果你不想在异常发生时结束你的程序,只需在try里捕获它。

    语法:

    以下为简单的try....except...else的语法:

    try:
    <语句>        #运行别的代码
    except <名字><语句>        #如果在try部份引发了'name'异常
    except <名字>,<数据>:
    <语句>        #如果引发了'name'异常,获得附加的数据
    else:
    <语句>        #如果没有异常发生

    try的工作原理:

      当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。

    • 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
    • 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
    • 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
    aaa      # NameError
    int('a') #ValueError
    [][4]    #IndexError
    class A:pass
    a = A()
    a.name   #AttributeError
    print('aaaa')
    
    def func():name
    def main():
        func()
    main()
    语法错误和逻辑错误
    l = [1,2,3,4]
    num = input('num : ')
    if num.isdigit():
    num = int(num)
    if num < len(l)-1 and num >0:
    print(l[num])

    l = [1,2,3,4]
    try:
        num = int(input('num : '))
        print(l[num])
    except ValueError:
        print('请输入一个数字')
    except IndexError:
        print('输入的数字超出范围')
    try中的代码
    一旦在一个地方发生错误
    后面的代码就不执行了
    会直接跳到except的位置
    一个错误类型只能处理一种错误
    出现异常之后
    会从上到下去匹配except中的error
    一旦匹配上就会执行except中的代码
    执行完之后不再执行其他except

    万能异常
    l = [1,2,3,4]
    try:
        num = int(input('num : '))
        print(l[num])
    # except:                  # 所有的错误都能处理
    #     print('万能的异常')
    # except Exception:
    #     print('万能的异常')
    except Exception as e: 
        print(e)
    
    
    l = [1,2,3,4]
    try:
        num = int(input('num : '))
        print(l[num])
        name
    except ValueError:
        print('请输入一个数字')
    except IndexError:
        print('输入的数字超出范围')
    except Exception as e:
        print(e)
    有多个except的时候 万能异常永远在最后
    
    
    l = [1,2,3,4]
    try:
        num = int(input('num : '))
        print(l[num])
    except ValueError:
        print('请输入一个数字')
    except IndexError:
        print('输入的数字超出范围')
    else:
        print('执行我了')
    
    else中的代码 在try中的代码全部顺利执行之后才执行
    如果try中的代码出现错误,那么else就不执行
    else中的代码什么时候用呢?
    在代码顺利执行的时候,报成功或者报结果的时候使用的

    try except格式
    try except else格式
    l = [1,2,3,4]
    try:
        f = open('')
        # num = int(input('num : '))
        # print(l[num])
    # except ValueError:
    #     print('请输入一个数字')
    # except IndexError:
    #     print('输入的数字超出范围')
    # else:
    #     print('执行我了')
    finally:
        print('finally被执行了')
    
    
    def func():
        try:
            f = open('file','w')
            content = f.read()
            return content
        finally:
            f.close()
    finally
    不管代码是否出错,都是一个无论如何会执行的代码
    打开的操作系统的资源不管代码执行是否出错,都应该归还

    这样的代码就应该写在finally中
    try except格式
    try except else格式
    try except else finally格式
    try finally格式

    主动的抛一个异常
    raise TypeError
    raise TypeError('出现了不可思议的TypeError')
    条件判断
    assert 1==1
    print('''aaaaaa''')
    
    class EvaException(BaseException):
        def __init__(self,msg):
            self.msg=msg
    
    raise EvaException('类型错误')
    eva = EvaException('类型错误')
    try:
        raise EvaException('类型错误')
    except EvaException as e:
        print(e)

    123

  • 相关阅读:
    delphi 如何让ScrollBox的内容与滚动条一起实时滚动
    C# Wpf集合双向绑定
    C# Wpf异步修改UI,多线程修改UI(二)
    C# 自定义线程修改UI(一)
    WPF FindName()查找命名注册的元素
    数据绑定
    WPF绑定Binding及模式
    WPF-Binding的源
    WPF-Binding对数据的检验
    WPF-数据转换
  • 原文地址:https://www.cnblogs.com/daofaziran/p/9116279.html
Copyright © 2020-2023  润新知