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


    一 反射的基本概念

      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 是一个函数还是一个类实例.

  • 相关阅读:
    golang压力测试工具
    Gnome启动
    简单说说 Apipost 的几点使用体验
    发现一个很nice的API调试工具!
    马勒第一交响曲
    Python中使用tkinter创建透明图层、不规则组件、插入GIF动图等功能实现
    RESTful API Knife4j
    汇编语言与DOSBOX使用
    VPP初学笔记(一)
    Python3下如何对文件进行操作?
  • 原文地址:https://www.cnblogs.com/654321cc/p/7583305.html
Copyright © 2020-2023  润新知