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)
自定义异常