zoukankan      html  css  js  c++  java
  • python3-面向对象进阶(内置方法)

    面向对象进阶:

    • isinstance和issubclass

    • 反射

    • __setattr__,__getattr,__delattr__

    • __setitem__,__getitem,__delitem__

    • __str__,__repr__,__format__

    • __del__

    isinstance和issubclass

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

    class Foo(object):
         pass
      
    obj = Foo()
      
    isinstance(obj, Foo)

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

    class Foo(object):
        pass
     
    class Bar(Foo):
        pass
     
    issubclass(Bar, Foo)

    反射

    python面向对象中的反射:通过字符串的形式操作对象相关属性。python中一切皆对象(都可以使用反射)

    • hasattr
    • getattr
    • setattr
    • delattr
    class Foo:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def say_hi(self):
            print('hi,%s'%self.name)
    
    obj=Foo('egon',73)
    
    #检测是否含有某属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'say_hi'))
    
    #获取属性
    n=getattr(obj,'name')
    print(n)
    func=getattr(obj,'say_hi')
    func()
    
    print(getattr(obj,'aaaaaaaa','不存在啊')) # 不存在 'aaaa' 属性的时候自动设置默认值‘不存在’, 不设默认值会报错
    
    #设置属性
    setattr(obj,'sb',True)
    setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)
    print(obj.show_name(obj))
    
    #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    delattr(obj,'show_name111')#不存在,则报错
    
    print(obj.__dict__)

    类也是对象,也可以反射

    class Foo(object):
     
        staticField = "old boy"
     
        def __init__(self):
            self.name = 'wupeiqi'
     
        def func(self):
            return 'func'
     
        @staticmethod
        def bar():
            return 'bar'
     
    print getattr(Foo, 'staticField')
    print getattr(Foo, 'func')
    print getattr(Foo, 'bar')

    反射的应用

    class Service:
        def run(self):
            while True:
                inp = input('>>:').strip()      # cmd = 'get a.txt'
                cmds = inp.split()      # cmd = ['get', 'a.txt']
    
                if hasattr(self, cmds[0]):
                    func = getattr(self, cmds[0])
                    func(cmds)
    
        def get(self, cmds):
            print('get....')
    
        def put(self, cmds):
            print('put ....')
    
    obj = Service()
    obj.run()

    __setattr__,__getattr,__delattr__

    class Foo:
        x=1
        def __init__(self,y):
            self.y=y
    
        def __getattr__(self, item):
            print('----> from getattr:你找的属性不存在')
    
    
        def __setattr__(self, key, value):
            print('----> from setattr')
            # self.key=value #这就无限递归了,你好好想想
            # self.__dict__[key]=value #应该使用它
    
        def __delattr__(self, item):
            print('----> from delattr')
            # del self.item #无限递归了
            self.__dict__.pop(item)
    
    #__setattr__添加/修改属性会触发它的执行
    f1=Foo(10)
    print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
    f1.z=3
    print(f1.__dict__)
    
    #__delattr__删除属性的时候会触发
    f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
    del f1.a
    print(f1.__dict__)
    
    #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
    f1.xxxxxx
    
    三者的用法演示

    __setitem__,__getitem,__delitem__

    # item系列
    # 把类和对象和交互转换成dict的形式
    
    class Foo:  #Dict
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            return self.__dict__.get(item)
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            del self.__dict__[key]
    
    obj = Foo('egon')
    
    # 查看属性
    # print(obj['name'])
    
    # 设置属性
    # obj['age'] = 18
    # print(obj.age)
    # print(obj.__dict__)
    
    # 删除属性
    del obj['name']
    print(obj.__dict__)

    __str__,__repr__,__format__

    改变对象的字符串显示__str__,__repr__

    自定制格式化字符串__format__

    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    format_dict={
    'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
    'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
    'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    }
    class School:
    def __init__(self,name,addr,type):
    self.name=name
    self.addr=addr
    self.type=type

    def __repr__(self):
    return 'School(%s,%s)' %(self.name,self.addr)
    def __str__(self):
    return '(%s,%s)' %(self.name,self.addr)

    def __format__(self, format_spec):
    # if format_spec
    if not format_spec or format_spec not in format_dict:
    format_spec='nat'
    fmt=format_dict[format_spec]
    return fmt.format(obj=self)

    s1=School('oldboy1','北京','私立')
    print('from repr: ',repr(s1))
    print('from str: ',str(s1))
    print(s1)

    '''
    str函数或者print函数--->obj.__str__()
    repr或者交互式解释器--->obj.__repr__()
    如果__str__没有被定义,那么就会使用__repr__来代替输出
    注意:这俩方法的返回值必须是字符串,否则抛出异常
    '''
    print(format(s1,'nat'))
    print(format(s1,'tna'))
    print(format(s1,'tan'))
    print(format(s1,'asfdasdffd'))

    __del__

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

    #__del__      回收系统操作资源
    
    # f=open('settings.py')
    # f.read()
    # f.close() #回收操作系统的资源
    
    # print(f)
    # f.read()
    
    
    
    class Open:
        def __init__(self,filename):
            print('open file.......')
            self.filename=filename
    
        def __del__(self):
            print('回收操作系统资源:self.close()')
    
    f=Open('settings.py')
    # del f #f.__del__()    
  • 相关阅读:
    UVa LA 2965
    UVa LA 3695
    UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2
    Uva LA 3177
    Uva LA 3902
    Uva 11520
    UVa Live 3635
    python学习笔记-day05 字典
    python学习笔记-day04 元组
    python学习笔记 day04 列表增删改查
  • 原文地址:https://www.cnblogs.com/Xuuuuuu/p/10272689.html
Copyright © 2011-2022 走看看