类的进阶四 反射和内置方法

一 反射的基本概念

  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

  __setitem__示例

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}

  __call__

  功能:一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。 

      有更高级的用法。待续。

class A:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __call__(self,friend):
        print('{} like {}'.format(self.name,friend))
zuo=A('zuo','25')
zuo('zhangjing')

输出:

zuo like zhangjing

  单看zuo('zhangjing') 你无法确定 zuo 是一个函数还是一个类实例.

原文地址:https://www.cnblogs.com/654321cc/p/7583305.html