python面向对象

1.  isinstance

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

print(isinstance(1, int))

print(isinstance(1.0, float))

print(isinstance('aa', str))

上面都是True

 print(isinstance('aa', (int,list,str))) 

只要是后面元组中的一个,就返回True

2.   issubclass

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

class A:
    pass

class B(A):
    pass

class C(B):
    pass

class D:
    pass

print(issubclass(B,A))
print(issubclass(C,A))
print(issubclass(D,A)

结果是:

True
True
False

子类的子类,进行判断,返回也是True,不能用实例化的对象进行判断,例如:b=B(),issubclass(b,A) ,这样有语法错误

 

 

反射

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr

 

class A:
    def __init__(self,name,age):
        self.names=name
        self.ages=age

    def info(self):
        print('name: %s, age: %d' %(self.names,self.ages))

    @staticmethod
    def static_func():
        print('static method')

a=A('egon',18)

print(hasattr(a,'name'))  #判断是否有name属性,False
print(hasattr(a,'names')) #判断是否有names属性,True

#获取属性
n = getattr(a,'names')
print(n)  #egon
func = getattr(a,'info')
func()  #name: egon, age: 18
m = getattr(a,'bbbbb','不存在') #如果属性不存在,返回第三个字段内容
print(m)  #不存在
m = getattr(a,'bbbbb',None)
print(m) #None

#设置属性
setattr(a,'names','alex')
print(a.__dict__)  #{'names': 'alex', 'ages': 18}
setattr(a,'n','alex')
print(a.__dict__)  #{'names': 'alex', 'ages': 18, 'n': 'alex'} 新增了一个n属性

#删除属性

#delattr(a,'ddd') #删除的属性不存在会报错
delattr(a,'names')
print(a.__dict__)  #{'ages': 18, 'n': 'alex'} 已经删除掉了names

#可以直接获取类的属性
f = getattr(A,'static_func')
f()  #static method

 

__setattr__,__delattr__,__getattr__

__getattr__只有在使用点调用属性且属性不存在的时候才会触发
__delattr__删除属性的时候会触发
__setattr__添加/修改属性会触发它的执行
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
f1.__dict__['a']=3
f1.a

 

__setitem__,__getitem,__delitem__

当已字典的形式操作类属性的时候,会进入以上函数

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

    def __getitem__(self, item):
        print('--------getitem',self.__dict__[item])

    def __setitem__(self, key, value):  #f1['age']=18,当以操作字典的形式进行操作时,会进入该函数
        print('--------setitem')
        self.__dict__[key]=value
    def __delitem__(self, key):  #del f1['age']已字典形式删除时进入函数
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
    def __delattr__(self, item):  #del f1.age1,obj.xxx 进行操作时,进入函数
        print('del obj.key时,我执行')
        self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18  #--------setitem
f1['age1']=19 #--------setitem
del f1.age1     #del obj.key时,我执行
del f1['age']   #del obj[key]时,我执行
f1['name']='alex'   #--------setitem
print(f1.__dict__)  #{'name': 'alex'}

 

__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}',#学校类型/学校地址/学校名
}
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'))   #oldboy1-北京-私立
print(format(s1,'tna'))   #私立:oldboy1:北京
print(format(s1,'tan'))   #私立/北京/oldboy1
print(format(s1,'asfdasdffd'))  #oldboy1-北京-私立

 

 __doc__

class Foo:
    '我是描述信息'
    pass

class Bar(Foo):
    pass
print(Bar.__doc__) #该属性无法继承给子类 None
print('---------------')
print(Foo.__doc__)  #我是描述信息

 

__del__

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

class Foo:

    def __del__(self):
        print('执行我啦')

f1=Foo()
# del f1
print('------->')

结果是:

------->

执行我啦

 

posted @ 2017-12-11 18:01  大川哥  阅读(211)  评论(0编辑  收藏  举报