zoukankan      html  css  js  c++  java
  • 面向对象:反射、内置方法

    反射:通过字符串映射到对象或者类的属性

    反射的方法:

    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

  • 相关阅读:
    gridview把textbox的值修改还是旧值的解决方法
    [转载]FMS Dev Guide学习笔记(验证客户端二)
    推荐几个Adobe Flex Builder 3的插件(代码格式化和fms服务器通讯文件(main.asc)编写)
    淘宝装修新旺铺如何让店招导航栏透明?
    淘宝店面怎么装修(不花分毫,玩转淘宝)
    教你处理明暗不匀的宝贝照片
    淘宝店铺装修 免费扶植版教程
    淘宝店铺(宝贝描述模板)克隆攻略
    如何用淘宝助理上传宝贝装修模板
    淘宝商城推广方案书
  • 原文地址:https://www.cnblogs.com/neozheng/p/8495350.html
Copyright © 2011-2022 走看看