• day 27-1 反射、内置方法


    反射

    反射:通过字符串来映射到对象的属性

    class People():
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def talk(self):
            print('Name:%s,Age:%s' % (self.name, self.age))
    
    
    p = People('ysg', 21)
    
    # 判断 对象 中是否存在该属性,实际判断的是 p.__dict__  ['name']
    print(hasattr(p, 'name'))  # 结果:True
    
    # 取到 'name' 中的值
    print(getattr(p, 'name', None))     # 结果:ysg
    print(getattr(p, 'names', None))    # 结果:None
    print(getattr(p, 'talk', None))     # <bound method People.talk of <__main__.People object at 0x0000020EDF705278>>
    
    # 修改 'name' 中的值
    setattr(p, 'name', 'ysging')    # p.name = 'ysging'
    print(p.name)                   # 结果:ysging
    
    # 删除 'name' 对象
    delattr(p, 'age')       # del p.age
    print(p.__dict__)       # 结果:{'name': 'ysging'}

    有这样的需求:希望通过用户的输入内容来调用方法

    例子

    class People():
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def run(self):
            while 1:
                val = input('>>>')
                if hasattr(self, val):
                    func = getattr(self, val, None)
                    func()
        def talk(self):
            print('Name:%s,Age:%s' % (self.name, self.age))
    
    
    p = People('ysg', 21)
    p.run()
    
    # 结果
    # >>>talk
    # Name:ysg,Age:21

    反射的好处:

    好处一:实现可插拔机制

    有俩程序员,一个lili,一个是egon,lili在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,lili想到了反射,使用了反射机制lili可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现lili想要的功能。

    总之反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

    好处二:动态导入模块(基于反射当前模块成员)

    内置方法

    isinstance(obj,cls) 检查是否 obj 是否是类 cls 的对象

    class Foo():
        pass
    
    
    obj = Foo()
    g = 123
    print(isinstance(obj, Foo))     # True
    print(isinstance(g, Foo))       # False

    issubclass(sub, super) 检查 sub 类是否是 super 类的派生类

    class Foo():
        pass
    
    
    class A(Foo):
        pass
    
    
    class B():
        pass
    
    print(issubclass(A, Foo))       # True
    print(issubclass(B, Foo))       # False

    item 系列:把对象做成像字典的类型

    class Foo():
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            print('getitem...')
            return self.__dict__.get(item)
    
        def __setitem__(self, key, value):
            print('setitem...')
            print(key,value)        # name ysging
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            del self.__dict__[key]
    
    
    f = Foo('ysg')
    print(f.__dict__)       # {'name': 'ysg'}
    
    # 取值
    print(f['name'])        # ysg
    
    # 设置
    f['name'] = 'ysging'
    print(f.name)           # ysging
    
    # 删除
    del f['name']
    print(f.__dict__)       # {}

    __str__

    一般情况下打印出为内存地址

    class People():
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    
    p = People('ysg', 22)
    print(p)        # <__main__.People object at 0x000002C168D952E8>

    使用 __str__ 后,打印结果可以自定义

    class People():
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            return '<name:%s,age:%s>' % (self.name, self.age)
    
    
    p = People('ysg', 22)
    print(p)        # <name:ysg,age:22>

    __del__:如果在类内部定义了一个 __del__ 方法,则会在对象被删除的时候先自动触发这个方法,再把对象删掉

    python只会回收对象本身的资源,不会回收与对象相关的数据

    class Open():
        def __init__(self,file):
            print('open file...')
            self.file = file
    
        def __del__(self):
            print('回收与对象相关的资源:self.close()') #这里可以写上与对象相关的数据,如:操作系统中的资源
    
    f = Open('config.py')
    print('-------main-------')

    析构方法,当对象在内存中被释放时,自动触发执行。

    注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义__del__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了__del__

    典型的应用场景:

    创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中

    当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

  • 相关阅读:
    sdmenu js
    python 语言开发组合模块,为软件整合提供帮助
    星际二 地图制作过程
    mozilla
    虚拟机 装 ios
    jaxb之xjc编码问题
    抽象类注意事项(面试常常涉及)
    使用java6做webservice
    在linux上jaxb 工具的shell命令编写
    在Redhat 5.0 上安装Eclipse 3.6
  • 原文地址:https://www.cnblogs.com/ysging/p/12061077.html
Copyright © 2020-2023  润新知