python3-面向对象进阶(内置方法)

面向对象进阶:

  • isinstance和issubclass

  • 反射

  • __setattr__,__getattr,__delattr__

  • __setitem__,__getitem,__delitem__

  • __str__,__repr__,__format__

  • __del__

isinstance和issubclass

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

class Foo(object):
     pass
  
obj = Foo()
  
isinstance(obj, Foo)

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

class Foo(object):
    pass
 
class Bar(Foo):
    pass
 
issubclass(Bar, Foo)

反射

python面向对象中的反射:通过字符串的形式操作对象相关属性。python中一切皆对象(都可以使用反射)

  • hasattr
  • getattr
  • setattr
  • delattr
class Foo:
    f = '类的静态变量'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say_hi(self):
        print('hi,%s'%self.name)

obj=Foo('egon',73)

#检测是否含有某属性
print(hasattr(obj,'name'))
print(hasattr(obj,'say_hi'))

#获取属性
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi')
func()

print(getattr(obj,'aaaaaaaa','不存在啊')) # 不存在 'aaaa' 属性的时候自动设置默认值‘不存在’, 不设默认值会报错

#设置属性
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj.show_name(obj))

#删除属性
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111')#不存在,则报错

print(obj.__dict__)

类也是对象,也可以反射

class Foo(object):
 
    staticField = "old boy"
 
    def __init__(self):
        self.name = 'wupeiqi'
 
    def func(self):
        return 'func'
 
    @staticmethod
    def bar():
        return 'bar'
 
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')

反射的应用

class Service:
    def run(self):
        while True:
            inp = input('>>:').strip()      # cmd = 'get a.txt'
            cmds = inp.split()      # cmd = ['get', 'a.txt']

            if hasattr(self, cmds[0]):
                func = getattr(self, cmds[0])
                func(cmds)

    def get(self, cmds):
        print('get....')

    def put(self, cmds):
        print('put ....')

obj = Service()
obj.run()

__setattr__,__getattr,__delattr__

class Foo:
    x=1
    def __init__(self,y):
        self.y=y

    def __getattr__(self, item):
        print('----> from getattr:你找的属性不存在')


    def __setattr__(self, key, value):
        print('----> from setattr')
        # self.key=value #这就无限递归了,你好好想想
        # self.__dict__[key]=value #应该使用它

    def __delattr__(self, item):
        print('----> from delattr')
        # del self.item #无限递归了
        self.__dict__.pop(item)

#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)

#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)

#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx

三者的用法演示

__setitem__,__getitem,__delitem__

# item系列
# 把类和对象和交互转换成dict的形式

class Foo:  #Dict
    def __init__(self, name):
        self.name = name

    def __getitem__(self, item):
        return self.__dict__.get(item)

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]

obj = Foo('egon')

# 查看属性
# print(obj['name'])

# 设置属性
# obj['age'] = 18
# print(obj.age)
# print(obj.__dict__)

# 删除属性
del obj['name']
print(obj.__dict__)

__str__,__repr__,__format__

改变对象的字符串显示__str__,__repr__

自定制格式化字符串__format__

#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type

def __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 in format_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__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了__del__

#__del__      回收系统操作资源

# f=open('settings.py')
# f.read()
# f.close() #回收操作系统的资源

# print(f)
# f.read()



class Open:
    def __init__(self,filename):
        print('open file.......')
        self.filename=filename

    def __del__(self):
        print('回收操作系统资源:self.close()')

f=Open('settings.py')
# del f #f.__del__()    
原文地址:https://www.cnblogs.com/Xuuuuuu/p/10272689.html