Python Day 24 面向对象进阶(双下方法 __new__ __del__ item系列 异常处理)

Python Day 24 面向对象进阶(双下方法 __new__  __del__ item 异常处理)

 

__init__  初始化方法

__new__  构造方法(申请内存空间)

class A:
    def __init__(self):
        print('init')
    def __new__(cls, *args, **kwargs):  #object __new__创造对象  #py2不主动继承
        print('new')
        self = object.__new__(cls)
        return self
a = A()

+++++++++++++++
python3:
new
init

+++++++++++++++
python2:
init

__init__
__new__
单例模式(多次创建对象,内存地址只有一个),创造一个类 这个类始终只有一个实例
class A:
    __instance = None
    def __init__(self,name):
        self.name = name
    def __new__(cls, *args, **kwargs):
        if not cls.__instance: #每次创建对象,会进行判断
            cls.__instance = object.__new__(cls)
        return cls.__instance
a = A('alex')
b = A('egon')
print(a)
print(b)
print(a.name)
print(b.name)
通过__new__和if创建单例模式
算法和设计模式(算法导论,设计模式)
设计模式  java开发过程中的规范或设计范式
两种学派
设计模式

__del__ 析构方法

  python解释器,能够主动回收不用的变量,在程序结束的时候所有的数据都会被清除,

  如果用户主动删除某个变量,那么这个变量将会主动的被删除,在删除一个变量之前都会主动的执行析构方法 __del__

class B:
    def __init__(self,path):
        print('init')
        self.f = open(path,encoding='utf-8',mode='w')
    def __del__(self): #对象删除之前回归一些操作系统资源
        self.f.close()
        print('__del__执行我啦')
    def __new__(cls, *args, **kwargs):  #object __new__创造对象  #py2不主动继承
        print('new')
        self = object.__new__(cls)
        return self
    def test(self):
        print('test')
b = B('userinfo')

==================
new
init
__del__执行我啦
__del__

item系列

  __getitem__       

    有一些内置模块中的内置方法是依赖__getitem__方法的或者说是依赖item['a']这种调用方式的  (list[1]  dict['key'])

  __setitem__

class Item():
    def __getitem__(self, item):
        # print('getitem',item) #getitem a
        return self.__dict__[item]  #b
    def __setitem__(self, key, value):
        self.__dict__[key] = value
        # print('setitem',key,value)  #setitem a b
item = Item()
item['a'] = 'b'   # __setitem__  设置一组对应关系
print(item['a']) #[]执行 __getitem__ ,['a'] 传进去  self.__dict__[item] 查找值
__getitem__ __setitem__

  __delitem__

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'])    # hello
item['a'] = 'b'     # setitem
print(item['a'])    # hello
print(item.a)
print(item.__dict__)
# del item.a
del item['a']
print(item.__dict__)
__delitem__
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)
乱序抽取纸牌

内置方法关联:

shuffle # __len__(self) __getitem__ __setitem__

choice #iterable,__len__,__getitem__

异常处理

  

# 什么是异常?
# 报错了就异常
# 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])
    name
except ValueError:
    print('请输入一个数字')
except IndexError:
    print('输入的数字超出范围')

#except : 万能异常
#except Exception : 万能异常
except Exception as e:  # 有多个except的时候 万能异常永远在最后
    print(e)

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

============================

else中的代码 在try中的代码全部顺利执行之后才执行
如果try中的代码出现错误,那么else就不执行
什么时候用呢?
    在代码顺利执行的时候,报成功或者报结果的时候使用的
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被执行了')

======================
finally
    不管代码是否出错,都是一个无论如何会执行的代码
    打开的操作系统的资源不管代码执行是否出错,都应该归还
    这样的代码就应该写在finally中
try except else finally格式
def func():
    try:
        f = open('file','w')
        content = f.read()
        return content
    finally: #finally总会被执行,即使函数中存在return
        f.close()

======================
finally
    不管代码是否出错,都是一个无论如何会执行的代码
    打开的操作系统的资源不管代码执行是否出错,都应该归还
        这样的代码就应该写在finally中
try finally格式

  主动的抛一个异常

raise TypeError

raise TypeError('出现了不可思议的TypeError')

=============
抛出异常后停止执行
主动抛出异常

  条件判断

assert 1==1  #断言成立,执行下一步,否则报错
print('''aaaaaa''')  

======================
if True:#成功继续,不成立也不报错
assert 断言

    自定义异常

class EvaException(BaseException):
    def __init__(self,msg):
        self.msg=msg
try:
    raise EvaException('类型错误')
except EvaException as e:
    print(e)
自定义异常


原文地址:https://www.cnblogs.com/eailoo/p/9116519.html