类的进阶(反射)
一、反射的基本概念
1.主要是指程序可以访问,检测和修改他本身状态或行为的一种能力。
最根本的就是,操作符字符串,根据字符串找到相应的属性,映射到真正的功能上。
反射说简单点-->就是利用字符串的形式去对象(模块)中操作(寻找/检查/删除/设置)成员。
示例——
class Foo:
def foo(self):
print('from Foo.foo')
f=Foo()
print(Foo.foo)
print(getattr(Foo,'foo'))
print(f.foo)
print(getattr(f,'foo'))
输出:getattr(x,'y') is equivalent to x.y
<function Foo.foo at 0x000001F3391FA8C8>
<function Foo.foo at 0x000001F3391FA8C8>
<bound method Foo.foo of <__main__.Foo object at 0x000001F3391FC470>>
<bound method Foo.foo of <__main__.Foo object at 0x000001F3391FC470>>
示例二
class Foo:
def foo(self):
print('from Foo.foo')
f=Foo()
getattr(f,'foo')()
f.foo()
输出: 可以看出 getattr(x, 'y') is equivalent to x.y
from Foo.foo
from Foo.foo
2.好基友
getattr 与 hasattr的搭配
示例:
class Foo:
def foo(self):
print('from Foo.foo')
f=Foo()
if hasattr(f,'foo'):
getattr(f,'foo')()
if hasattr(f,'bar'):
getattr(f,'bar')()
输出:
from Foo.foo
3.setattr,delattr
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
egon=Teacher('egon',18)
setattr(egon,'level',10)
print(egon.__dict__)
delattr(egon,'name')
print(egon.__dict__)
输出:
{'name': 'egon', 'age': 18, 'level': 10}
{'age': 18, 'level': 10}
二、反射的应用。
反射非常重要
class func:
def foo(self):
print('foo')
def bar(self):
print('bar')
f=func()
cmd=input('==>')
if hasattr(f,cmd):
getattr(f,cmd)()
输出:
==>foo
foo
进阶的示例。非常重要的模型。
class Cmd:
def __init__(self,name):
self.name=name
def run(self):
while True:
cmd=input('==>')
if not cmd:continue #空就继续循环,输入
if hasattr(self,cmd): # 判断有没有字符串对应的属性
getattr(self,cmd)()
def ls(self):
print('ls func')
def dir(self):
print('dir func')
egon=Cmd('egon')
egon.run()
输出:
==>
==>foo
==>bar
==>ls
ls func
==>
二、内置方法
1.__str__
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '''
name:%s
age:%s
'''%(self.name,self.age)
egon=Teacher('egon',18)
print(egon)
输出:
name:egon
age:18
print 自动触发__str__方法,执行其代码。可以代替tell_info方法。
2 __getitem__ __setitem__ __delitem__ 列表,字典也是类的对象,所以应该会有以 [ ]取值的方法。模拟列表,字典中括号取值的方式。
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
def __getitem__(self, item):
print(self,item,type(item))
egon=Teacher('egon',18)
egon['name'] #只要以中括号调用其属性时,触发getitem方法
print(egon['name']) #没有返回值
输出:
<__main__.Teacher object at 0x000001DBF55FC438> name <class 'str'> <__main__.Teacher object at 0x000001DBF55FC438> name <class 'str'> None
__seritem__示例
class Teacher:
def __init__(self,name,age):
self.name=name
self.age=age
def __getitem__(self, item):
print(self,item,type(item))
def __setitem__(self, key, value):
# setattr(self,key,value)
self.__dict__[key]=value #这是更本质的方法
egon=Teacher('egon',18)
egon['level']=10
print(egon.__dict__)
输出:
{'name': 'egon', 'age': 18, 'level': 10}
浙公网安备 33010602011771号