python面向对象难学_python-面向对象进阶

一、isinstance(obj,cls)和issubclass(sub,super)

isinstance(obj,cls)检查obj是否是cls的对象

issubclass(sub,super)检查sub是否是super的派生类

classBar:pass

classFoo(Bar):passobj=Foo()print(isinstance(obj,Foo))#True

print(issubclass(Foo,Bar))#True

二、反射

python面向对象中的反射:通过字符串的形式操作对象相关的属性

通过下面四个函数可以实现,适用于类和对象

hasattr(object,name):判断一个object中有没有name属性或者方法

getatrr(object,name,default=None):获取object中的name属性或方法,设置defult=None时没找到返回None,没设置报错

setattr(x,y,z)修改x中y的值为z,当y不存在时添加y的值为z

delattr(x,y)删除x中的y属性或方法

演示代码:

ContractedBlock.gif

ExpandedBlockStart.gif

classBlackMedium:

feature='Ugly'

def __init__(self,name,addr):

self.name=name

self.addr=addrdefsell_house(self):print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)defrent_house(self):print('%s 黑中介租房子啦,傻逼才租呢' %self.name)

b1=BlackMedium('万成置地','回龙观天露园')#检测是否含有某属性

print(hasattr(b1,'name'))print(hasattr(b1,'sell_house'))#获取属性

n=getattr(b1,'name')print(n)

func=getattr(b1,'rent_house')

func()#getattr(b1,'aaaaaaaa') #报错

print(getattr(b1,'aaaaaaaa','不存在啊'))#设置属性

setattr(b1,'sb',True)

setattr(b1,'show_name',lambda self:self.name+'sb')print(b1.__dict__)print(b1.show_name(b1))#删除属性

delattr(b1,'addr')

delattr(b1,'show_name')

delattr(b1,'show_name111')#不存在,则报错

print(b1.__dict__)

四个方法的使用演示

View Code

python中一切皆对象,也可以对类使用反射

三、二次加工标准类型(包装)

包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)

class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid

defappend(self, p_object):'派生自己的append:加上类型检查'

if notisinstance(p_object,int):raise TypeError('must be int')

super().append(p_object)

@propertydefmid(self):'新增自己的属性'index=len(self)//2

returnself[index]

l=List([1,2,3,4])print(l)

l.append(5)print(l)#l.append('1111111') #报错,必须为int类型

print(l.mid)#其余的方法都继承list的

l.insert(0,-123)print(l)

l.clear()print(l)

二次加工标准类型(基于继承实现)

授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__getattr__方法

ContractedBlock.gif授权示范代码一

ContractedBlock.gif

ExpandedBlockStart.gif

#_*_coding:utf-8_*_

__author__ = 'Linhaifeng'

#我们来加上b模式支持

importtimeclassFileHandle:def __init__(self,filename,mode='r',encoding='utf-8'):if 'b' inmode:

self.file=open(filename,mode)else:

self.file=open(filename,mode,encoding=encoding)

self.filename=filename

self.mode=mode

self.encoding=encodingdefwrite(self,line):if 'b' inself.mode:if notisinstance(line,bytes):raise TypeError('must be bytes')

self.file.write(line)def __getattr__(self, item):returngetattr(self.file,item)def __str__(self):if 'b' inself.mode:

res="<_io.BufferedReader name='%s'>" %self.filenameelse:

res="<_io.TextIOWrapper name='%s' mode='%s' encoding='%s'>" %(self.filename,self.mode,self.encoding)returnres

f1=FileHandle('b.txt','wb')#f1.write('你好啊啊啊啊啊') #自定制的write,不用在进行encode转成二进制去写了,简单,大气

f1.write('你好啊'.encode('utf-8'))print(f1)

f1.close()

授权示范二

授权示范代码二

四、_getattribute_

当__getattribute__与__getattr__同时存在,只会执行__getattrbute__,除非__getattribute__在执行过程中抛出异常AttributeError

classFoo:def __init__(self,x):

self.x=xdef __getattr__(self, item):print('执行的是我')#return self.__dict__[item]

def __getattribute__(self, item):print('不管是否存在,我都会执行')raise AttributeError('哈哈')

f1=Foo(10)

f1.x

f1.xxxxxx

五、_str_,_repr_,_format_

定制对象被打印时的输出信息,必须返回一个字符串类型的值! __str__,__repr__

自定制格式化字符串__format__

format_dict={'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型

'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址

'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名

}classSchool:def __init__(self,name,addr,type):

self.name=name

self.addr=addr

self.type=typedef __repr__(self):return 'School(%s,%s)' %(self.name,self.addr)def __str__(self):return '(%s,%s)' %(self.name,self.addr)def __format__(self, format_spec):#if format_spec

if not format_spec or format_spec not informat_dict:

format_spec='nat'fmt=format_dict[format_spec]return fmt.format(obj=self)

s1=School('oldboy1','北京','私立')print('from repr:',repr(s1))print('from str:',str(s1))print(s1)'''str函数或者print函数--->obj.__str__()

repr或者交互式解释器--->obj.__repr__()

如果__str__没有被定义,那么就会使用__repr__来代替输出

注意:这俩方法的返回值必须是字符串,否则抛出异常'''

print(format(s1,'nat'))print(format(s1,'tna'))print(format(s1,'tan'))print(format(s1,'asfdasdffd'))

六、__del__

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

当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

#class Foo:#def __del__(self):#print('run....')#obj = Foo()

#__call__:在对象被调用时会自动触发该方法,

classFoo:def __init__(self,x,y):

self.x=x

self.y=ydef __call__(self, *args, **kwargs):print(self,args,kwargs)

obj= Foo()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值