常用类的内置方法

【反射】

作用:可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
例如:多人开发时,你不知道对面完成接口情况,可以用hasattr获取下有没有功能方法,没有的话就不去调用该功能

  • hasattr(object,name) 【检测是否含有某属性】
  • getattr(object, name, default=None) 【获取指定属性】
  • setattr(x, y, v)【设置属性】
  • delattr(x, y)【删除指定属性】
class BlackMedium:
    feature='Ugly'
    def __init__(self,name):
        self.name=name

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

b1=BlackMedium('万成置地')

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

#获取属性  
n=getattr(b1,'name')  # 判断是否存在属性
func=getattr(b1,'rent_house')
func()
# getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊'))

#设置属性
setattr(b1,'sb',True)

#删除属性
delattr(b1,'addr')
delattr(b1,'show_name111')#不存在,则报错

print(b1.__dict__)

拦截器- 【属性】将调用时执行

setattr,delattr,getattr

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

拦截器- 【值】将调用时执行

get,set,delete

class Foo:
    def __get__(self, instance, owner):
        print('触发get')
    def __set__(self, instance, value):
        print('触发set')
    def __delete__(self, instance):
        print('触发delete')

#包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法
f1=Foo()
f1.name='egon'
f1.name
del f1.name
#疑问:何时,何地,会触发这三个方法的执行

猜你喜欢

转载自blog.csdn.net/weixin_42329277/article/details/80516521