python 课堂15 面向对象3 内部方法,类的定制
Posted qianduoduo123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 课堂15 面向对象3 内部方法,类的定制相关的知识,希望对你有一定的参考价值。
面向对象 3 高级用法
绑定方法:
绑定方法,非绑定方法
绑定方法: 对象绑定,类绑定 @ classmethod
非绑定 @ staticmethod
class Foo:
# 没有装饰器的函数,参数自动传入对象,和对象绑定,是对象绑定方法
def func1(self):
print(self)
# 使用classmethod装饰,自动传入类,和类绑定,是类的绑定方法。
@ classmethod
def func2(cls):
print(cls)
# 使用staticmethod装饰,不自动传入任何东西,就是普通方法
@ staticmethod
def func3():
print(‘普通工具类‘)
f = Foo()
f.func1() # <__main__.Foo object at 0x000001DFFED06278>
f.func2() # <class ‘__main__.Foo‘>
f.func3() # 普通工具类
绑定对象方法,绑定类方法,非绑定方法的使用
import db
import time,hashlib
class People:
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(‘my name is %s age is %s‘%(self.name,self.age))
# 函数依赖类的传入
@classmethod
def creat_obj(cls):
obj = cls(db.name,db.age)
return obj
# 独立的工具
@staticmethod
def creat_id():
hs = hashlib.md5(str(time.time()).encode(‘utf8‘))
return hs.hexdigest()
p1 = People(‘ql‘,22)
p1.info()
p2 = People.creat_obj() # 使用类方法直接创建对象
p2.info()
id = p2.creat_id()
print(id)
property
class People:
def __init__(self,name):
self.__name = name
# 将方法伪装为属性,调用时不需要加括号。
@ property # name = property(name)
def name(self):
return self.__name
# property 伪装成属性后,如果被赋值,将触发
@ name.setter # name = name.setter(name) ==>name.name.__setter__()
def name(self,name):
self.__name = name
return self.__name
# property 伪装成属性后,如果被删除,将触发
@ name.deleter # 删除name 触发
def name(self):
print(‘不准删name‘)
p = People(‘qianlei‘)
p.name = ‘qianlei123‘
print(p.name)
将name 封装,看似直接调用name,其实该name 是方法,可以对查看名称进行定制。
反射
反射就是使用字符串来作为属性名,去调用。
class People:
def __init__(self,name,age):
self.name = name
self.age = age
def info(self):
print(‘my name is %s age is %s‘%(self.name,self.age))
p = People(‘qianlei‘,22)
调用属性时,如果接收用户输入,将字符串作为属性名,则无法调用。
想调用可以使用字典 p.__dict__[‘name‘]
python 还提供了简单的解决办法
print(p.name)
反射 hasattr() getattr() setattr() delattr()
print(hasattr(p,‘name‘))
print(getattr(p,‘name‘,None)) # 第三个参数为默认返回,如果没有该属性默认返回值。
print(getattr(p,‘name1‘,None))
setattr(p,‘sex‘,‘male‘)
print(getattr(p,‘sex‘))
delattr(p,‘sex‘)
print(getattr(p,‘sex‘,‘没有这个属性‘))
反射应用
class service():
def run(self):
while True:
res = input(‘>>>>‘).strip()
# if hasattr(self,res): # 先判断是否有这个属性
# func = getattr(self,res) # 获取属性
# func() # 运行属性
mes_list = res.split()
if hasattr(self,mes_list[0]):
func = getattr(self,mes_list[0])
func(mes_list[1])
def get(self,mes):
print(‘get.......‘,mes)
def put(self,mes):
print(‘put.........‘,mes)
s = service()
s.run()
__call__ __new__ __str__
__call__ : 将类的实例变成可以调用的对象,实例+(),运行
class Foo:
def __call__(self, *args, **kwargs):
print(‘this is call func‘)
print(args)
print(kwargs)
f = Foo()
f(‘a‘, b=1)
===》this is call func
===》(‘a‘,)
===》{‘b‘: 1}
__new__ : 类实例化时自动调用,可以定制实例化。
class Foo:
def __new__(cls, *args, **kwargs):
print(‘this is new func‘)
print(args)
print(kwargs)
f = Foo(‘a‘, b=1)
===》this is new func
===》(‘a‘,)
===》{‘b‘: 1}
__str__ :打印实例时调用。
class Foo:
def __str__(self):
return ‘this is str‘
f = Foo()
print(f)
===》this is str
_getattr_ __setattr__ __delattr__
定制对象获取设置删除属性方法:_getattr_() _setattr_() _delattr_()
_getattribut_():对象调用属性时激活,但是当抛出AttributError() 则激活_getattr_(),需要自己设置。
_getattr_() :对象调用属性时没有对应属性,则激活_getattr_()
_setattr_() :对象设置属性时激活运行,并且返回该方法的返回值。可以规定修改属性时返回什么。
_delattr_():对象删除属性时激活运行,并且返回该方法的返回值。可以规定删除属性时返回什么。
class Test():
def __init__(self,name):
self.name=name
def __getattr__(self, item):
print(‘getattr is running %s was not find ‘%item)
def __setattr__(self, key, value):
print(‘setattr is running %s is seting‘%key)
# self.key=value#这个方法会调用自己,因为方法本身就是添加属性,无限递归
self.__dict__[key]=value#设置时需要使用对象字典
def __delattr__(self, item):
print(‘delattr is running %s is del‘%item)
del self.__dict__[item]#删除对象字典元素,否则会无限递归。
t=Test(‘tes‘) #只要有属性生成或变动就会触发__setattr__
print(t.erro_name)#调用不存在的属性 就会触发 __getattr__()方法
t.age=20 #只要有属性生成就会触发__setattr__
print(t.__dict__)
del t.age#只要删除属性就会触发__delattr__
print(t.__dict__)
二次加工标准模型
使用继承,定制自己的类。
就是使用继承对标准模型,进行个性化定制,
添加自己的需求,并且还可以使用标准模型的功能。
例如对列表进行定制,实例化列表时,要求必须传入字符串。
class Mylist(list):
def __init__(self, strtype):
if isinstance(strtype, str):
super().append(strtype)
else:
print(‘必须传入字符串‘)
# 这里必须传入字符串
l = Mylist(‘123‘)
print(l)
# 还可以使用原来的功能。
l.append(‘abc‘)
print(l)
授权:
利用目标类的实例,去调用目标类的方法。相当于利用目标类的实例授权目标类的方法。
1、先给类中添加目标类的实例
2、需要调用目标类中的方法时,使用__getattr__()去转接目标类的方法。
3、需要修改目标类的方法时,则利用目标类的实例给出对应的方法,并包装修改。
import time
class file_io():
def __init__(self,filename,mode,encoding=‘utf-8‘):
self.file=open(filename,mode,encoding=encoding)#给实例属性添加个open()实例,利用这个实例给自己添加open()中的方法。
self.mode=mode
self.encoding=encoding
# 自己定义write()方法,本质上还是调用文件对象的write()方法,给予了定制功能
def write(self,neirong):
#利用open()实例file,授权write方法,定制包装自己的write()方法。
#每次写入内容时添加时间。
t = time.strftime(‘%Y-%m-%d %X‘)
res=‘%s %s‘%(t,neirong)
return self.file.write(res)#返回文件句柄中的write()
# 调用本类没有的方法时,去对象的类中去找。。
def __getattr__(self, item):
#利用__getattr__()方法去授权对象调用open()的实例file,中的各种方法。
return getattr(self.file,item)#授权f对象使用标准文件句柄中的各种属性。
f=file_io(‘test.txt‘,‘w+‘)
f.file.write(‘None
‘)#f对象调用自己的属性file,file句柄中有write()方法
f.write(‘qwe
‘) #调用定制的write()方法
f.write(‘sdad
‘)
f.seek(0)
print(f.read())#f中没有read()方法,所以触发__getattr__(),返回文件句柄本身提供的read()
f.close()
以上是关于python 课堂15 面向对象3 内部方法,类的定制的主要内容,如果未能解决你的问题,请参考以下文章
阿里云名师课堂Java面向对象开发68 ~ 7073:接口的定义和使用
python课堂整理33----面向对象(我的对象又在哪里)