小结
issubclass 和 isinstance
# issubclass 判断第一个类是不是第二个类的子类,返回True或者False
# class Foo:
# pass
# class Bar(Foo):
# pass
#
# class Tt(Bar):
# pass
# #print(Bar.__bases__) #(Bar.__bases__)表示查看Bar的父类#(<class '__main__.Foo'>,)
# print(issubclass(Bar, Foo)) #True
# print(issubclass(Tt,object))#True
# isinstance 判断第一个参数是不是第二个参数的对象,返回True或者False
class Foo:
pass
class Tt:
pass
f=Foo()
print(isinstance(f, Foo))#True
print(isinstance(f, Tt))#False
反射
#用户输入一段字符串,执行该字符串对应的方法
# hasattr(): 判断一个属性是否在对象中,返回True或者False
# getattr(): 通过字符串动态获取属性和方法,如果获取到了, 就会返回相应属性和方法
# setattr(): 通过字符串动态来设置属性或方法
# delattr(): 通过字符串动态来删除属性或方法
# class Foo:
# def run(self):
# print('run')
# def speak(self):
# print('speak')
#
# f=Foo()
# #print(f.__dict__)#没有放东西,所有为{}
#cmd = input('请输入命令:')
# 方案一
# print(Foo.__dict__[cmd])#<function Foo.run at 0x0000000002987620>
# Foo.__dict__[cmd](f) #run
#方法二
#print(hasattr(f,cmd)) #run #True
#print(getattr(f,cmd))#<bound method Foo.run of <__main__.Foo object at 0x00000000029C5FD0>>
#getattr(f,cmd)()run
# if hasattr(f,cmd):
# run=getattr(f,cmd)
# run()
# else:
# print('命令不存在') #run
#通过用户输入key 和 value往对象中赋值
# key = input('请输入key')
# value = input('请输入value')
# setattr(f,key,value)
# print(f.age)# age, 18 , (打印 18)
#动态的往对象中放方法
# def test(a): #(函数test是被添加的对象)
# print(a)
# #print(f.__dict__)#{}
# setattr(f, 'test', test)#(第一个test相对与变量名,第二个test是被添加的对象)
# print(f.__dict__)#{'test': <function test at 0x0000000002142E18>}
# f.test(5) #5
#动态删除方法
#原始的删除方法
# class Foo:
# def run(self):
# print('run')
# def speak(self):
# print('speak')
# f=Foo()
# f.name='lpz'
# print(f.__dict__)#{'name': 'lpz'}
# del f.name
# print(f.__dict__)#{}
#动态删除f中的属性为变量a的属性
# f.name = 'lqz'
# f.age = 18
# f.sex = 'male'
# a = input('请输入要删除的属性')#{'name': 'lqz', 'age': 18, 'sex': 'male'}
# print(f.__dict__)
# delattr(f,a)
# print(f.__dict__)#{'name': 'lqz', 'sex': 'male'}
#直接p.a是不对的 #del f.a
#删除对象中属性为name字符串的属性
#判断一下对象中有没有我输入的属性,如果有,就打印
# class Foo:
# def run(self):
# print('run')
# def speak(self):
# print('speak')
# f=Foo()
# f.name = 'lqz'
# f.age = 18
# f.sex = 'male'
# cmd = input('请输入要查询的属性')
# if hasattr(f,cmd):
# a=getattr(f,cmd)
# print(a)
# else:
# print('属性不存在')
#反射:通过字符串来获取,设置,删除对象中的属性和方法
#例子
class BlackMedium:
featuer= 'ugly'
def __init__(self, name, addr):
self.name = name
self.addr = addr
def sell_house(self):
print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' % self.name)
def rent_house(self):
print('%s 黑中介租房子啦,傻逼才租呢' % self.name)
b1 = BlackMedium('万成置地', '回龙观天露园')
# print(b1.__dict__)#{'name': '万成置地', 'addr': '回龙观天露园'}
# print(hasattr(b1,'sell_house'))#True(判断属性是否在对象中)
# a='sell_house'
# getattr(b1, 'sell_house')内存地址,下面是加括号调用
# getattr(b1,a)() #万成置地 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼
# name1 = getattr(b1,'name')
# print(name1)#万成置地
#print(sell_house)#报错
#删除属性或方法
# delattr(b1,'xxx')
# print(b1.__dict__)#报错,没有xxx
# print(b1.__dict__)#{'name': '万成置地', 'addr': '回龙观天露园'}
# delattr(b1,'name')
# print(b1.__dict__)#{'addr': '回龙观天露园'}
#模块也是对象,也可以#使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,如果有就执行,没有,就报错
# import utils
# utils.speak()
# if hasattr(utils,'speak'):
# speak=getattr(utils,'speak')
# speak()用这四种方法
# import os
# print(hasattr(os,'path1'))
#使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,如果有就执行,没有,就报错
# import utils
# utils.speak()
# if hasattr(utils,'speak'):
# speak=getattr(utils,'speak')
# speak()
#我以为它写完了
# utils.eat()
#更安全
# if hasattr(utils,'eat'):
# eat=getattr(utils,'eat')
# eat()
# else:
# print('那个人还没写完呢')
内置方法
#学过的内置方法__init__
#__str__:如果不重写__str__,print打印会打印出内存地址
#如果重写了,就会打印出你想要的
# __repr__跟 __str__类似, 在交互式命令下直接写变量名,会执行__repr__
# class Foo:
# def __init__(self, name):
# self.name = name
# def __str__(self):
# return [ self.name ] #['nick']
# f=Foo('nick')
# #print(f.__str__()) __str__是list类型
# print(f)#报错
# l=[1,2,3]
# #本质也是调用list的__str__方法
# print(l)#[1, 2, 3]
###########################重点
# __setattr__, __delattr__, __getattr__(重点, 这些都属于点拦截方法)
# 如果去对象中取属性,一旦“取不到”,则会进入__getattr__中
# 如果去对象中赋值属性,一旦“取不到”,则会进入__setattr__中
# 如果删除对象中的属性,会进入__delattr__
# class Foo:
# def __init__(self,name):
# self.name=name
# def __getattr__(self,item):
# #print('xxx')
# return '傻逼,没有这个字段'
# def __setattr__(self, key,value):
# print('yyy')
# def __delattr__(self,item):
# print('zzz')
# f=Foo('nick')
# print(f.name)#yyy/xxx/傻逼,没有这个字段
# print(f.__dict__)#{}
# print(f.name)
# f.sex = 'male'
# print(f.__dict__)#{}
#原来使用字典方式
# di = dict(name='lqz', age=18)
# print(di) #{'name': 'lqz', 'age': 18}
# print(di['name']) #lqz
# print(di['age']) #18
# di.sex = 'male'#di中没有sex属性
##写一个类继承字典,让它可以 .取值,可以中括号取值
# class Mydict(dict):
# def __init__(self, **kwargs):
# super().__init__(**kwargs)
#
# def __getattr__(self, item):
# #print(item) #item就时属性name
# return self[item]
# def __setatr__(self, key,value):
# self[key]=value
# di=Mydict(name='lqz',age=18)
# print(di.name) #lqz
# print(di['name'])#lqz
# # di.sex=19
# # print(di.sex)#19
# # print(di.__dict__)#{'sex': 19}
# di['sex']='male'
# print(di.sex)#male
# print(di.__dict__) #{}
# #di.sex='male'
# print(di.sex) #male
# #print(di.__dict__) #{'sex': 'male'}
# __item__系列, 对象通过[] 中括号取值,赋值,删除值的时候,会调用
# class Foo:
# def __init__(self,name):
# self.name = name
# def __getitem__(self,item):
# name=getattr(self,item)
#
# return name
# def __setitem__(self, key, value):
# print('obj[key]=lqz赋值我是时,执行我')
# self.__dict__[key] = value
#
# def __delitem__(self, key):
# print('del obj[key]时,执行我')
# self.__dict__.pop(key)
# f=Foo('nick')
# print(f['name']) #nick
# __call__对象加括号会调用它
# class Foo:
# def __call__(self):
# print('xxx') # f()执行后会调用__call__,所有会打印出xxx
# f= Foo()
# f()#xxx
# __enter__ 和 __exit__
#上下文管理器,本质原来
# with open()as f:
# pass
class Mydict():
def __getattr__(self):
print('xxx')
return '该属性不存在'
m=Mydict()
print(m.name)