反射:通过字符串映射到对象或者类的属性
反射的方法:
class People: country = "China" def __init__(self,name,age): self.name = name self.age = age def talk(self): print("%s is talking" % self.name) obj = People("neo",22) """ 判断是否拥有某个属性: hasattr(o,name) # name是字符串格式 """ print(hasattr(obj,"name")) print(hasattr(obj,"talk")) print(hasattr(People,"country")) print(hasattr(People,"talk")) # 运行结果: # True # True # True # True """ 得到某个属性的值: getattr(o,name,default) # default处写上“None”,那么即使没有这个name程序也不会报错 """ print(getattr(obj,"name",None)) print(getattr(obj,"talk",None)) print(getattr(obj,"gender",None)) print(getattr(People,"country",None)) print(getattr(People,"talk",None)) # 运行结果: # neo # <bound method People.talk of <__main__.People object at 0x00000035DB166668>> # None # China # <function People.talk at 0x000000878224BA60> """ 添加、修改某个属性: setattr(object,"name",value) """ setattr(obj,"gender","male") setattr(obj,"name","NEO") print(obj.gender) print(obj.name) setattr(People,"nation","Han") print(People.__dict__) print(getattr(People,"nation",None)) print(People.nation) # 运行结果: # male # NEO # {'__module__': '__main__', 'country': 'China', '__init__': <function People.__init__ at 0x00000018D460B9D8>, 'talk': <function People.talk at 0x00000018D460BA60>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'nation': 'Han'} # Han # Han """ 删除某个属性: delattr(o,name) """ delattr(obj,"age") print(obj.__dict__) delattr(People,"country") print(People.__dict__) # 运行结果: # {'name': 'NEO', 'gender': 'male'} # {'__module__': '__main__', '__init__': <function People.__init__ at 0x0000002C1C9BB9D8>, 'talk': <function People.talk at 0x0000002C1C9BBA60>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'nation': 'Han'}
反射的使用:
"""接收用户输入,触发相应的功能""" class Service: def run(self): while True: # 输入的是格式化的内容,如: get a.txt 或者 upload a.txt cmd = input(">>>").strip().split() # cmd = ["get","a.txt"] if hasattr(self,cmd[0]): func = getattr(self,cmd[0]) func(cmd) def get(self,cmd): print("get .......%s" %cmd[1]) def upload(self,cmd): print("upload ......%s" %cmd[1]) obj = Service() obj.run()
内置方法:
一、isinstance(obj,cls)和 issubclass(sub,super)
isinstance(obj,cls) # 检查对象obj是否为 类 cls的对象 # 返回Bool值
issubclass(sub,super) # 检测sub类是否为 super类的派生类(子类) # 返回Bool值
二、item系列: __getitem__(self, item)、__setitem__(self, key, value)、__delitem__(self, key)
"""通过item系列能够把对象当做字典去处理""" class People: def __init__(self,name): self.name = name def __getitem__(self, item): print("get item test [%s]" %item) return self.__dict__.get(item) def __setitem__(self, key, value): print("set item test" ) self.__dict__[key] = value def __delitem__(self, key): print("del item test") self.__dict__.pop(key) # del self.__dict__[key] # 这种方式也可以 """下面讨论这3中item在何种情况下被触发""" p = People("neo") p["age"] # 对象["name"] 能够触发 __getitem__(self,item) # 跟__getitem__(self,item) 函数体的具体代码无关 # 运行结果: # get item test [age] p["gender"] = "male" # 对象["key"] = "value" 能够触发 __setitem__(self,key,value) # 同样, 与其函数体的具体代码无关 print(p.__dict__) # 运行结果: # set item test # {'name': 'neo', 'gender': 'male'} del p["name"] # del 对象["name"] 能够触发 __delitem__(self,key) # 与其函数体的具体代码无关 # 运行结果: # del item test
三、 __str__(self) 方法:使打印对象的输出结果格式化
""" __str__(self)方法:将print(object)的打印结果由对象的内存地址格式化成你需要的字符串形式,从而增加了打印结果的可读性 print(object)触发__str__(self), """ class People: def __init__(self,name,age): self.name = name self.age = age def __str__(self): print("=====>>>") return "aaa" # __str__只能返回字符串格式 # return "<name:%s> <age:%s>"%(self.name,self.age) # 可以自己定义打印结果的格式 p = People("neo",18) print(p) # 打印对象能够触发__str__(self) # 运行结果: # =====>>> # aaa
四、__del__ 方法
补充知识:
# 以open(file)为例 f = open("setting.py") # python没有能力自己打开硬盘文件,打开文件的动作需要操作系统去完成,所以 open其实是个命令:告诉操作系统让它打开a.txt这个文件;这个赋值过程涉及两方面的资源:变量f 是应用程序的资源,open("setting.py"):打开硬盘文件是操作系统的资源 f.read() # read()也是一个命令,是让操作系统读取文件内容 # read()需要在文件关闭之前进行 """ 资源不能一直被占用;python只能回收它自己应用程序的资源(例如python程序结束后资源都会被回收),但python没有能力回收操作系统的资源,所以在python程序结束前一定要关闭掉文件 """ f.close() # close()也是一个对操作系统发出的命令,让操作系统关闭掉硬盘上的文件,并把操作系统里面相应的资源回收;注意:python程序结束前一点要关闭掉文件,这一点不要忘 """ 虽然硬盘文件已经关闭掉,但f 还能够打印,因为f 是应用程序的资源;但文件关闭后就不能再read了 """ print(f) # 打印结果: # <_io.TextIOWrapper name='setting.py' mode='r' encoding='cp936'>
__del__(self) 的作用: 让操作系统回收掉自己的资源
触发情况:1. del f # del file(file是个对象,如上面示例中的f)能够自动调用类内部的 __del__(self) (先触发__del__再删除f这个对象)
2. 如果没有del f,那么在程序结束的之前会自动调用__del__(self)(或者说在程序运行到最后已经没有其他代码要执行了) (也是python先触发__del__,再删除python自己的f)
总结: 在类内部定义的内置方法都是绑定给对象的;而且在某种情况下会自动被触发调用
附: 其他内置方法可参考链接: http://www.cnblogs.com/linhaifeng/articles/6204014.html