zoukankan      html  css  js  c++  java
  • 内置方法

    isinstance(obj,cls)和issubclass(sub,super)

    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)

    反射

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

    class BlackMedium:
        feature='Ugly'
        def __init__(self,name,addr):
            self.name=name
            self.addr=addr
    
        def sell_house(self):
            print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
        def rent_house(self):
            print('%s 黑中介租房子啦,傻逼才租呢' %self.name)
    
    b1=BlackMedium('万成置地','回龙观天露园')
    
    #检测是否含有某属性
    print(hasattr(b1,'name'))
    print(hasattr(b1,'sell_house'))
    
    #获取属性
    n=getattr(b1,'name')
    print(n)
    func=getattr(b1,'rent_house')
    func()
    
    # getattr(b1,'aaaaaaaa') #报错
    print(getattr(b1,'aaaaaaaa','不存在啊'))
    
    #设置属性
    setattr(b1,'sb',True)
    setattr(b1,'show_name',lambda self:self.name+'sb')
    print(b1.__dict__)
    print(b1.show_name(b1))
    
    #删除属性
    delattr(b1,'addr')
    delattr(b1,'show_name')
    delattr(b1,'show_name111')#不存在,则报错
    
    print(b1.__dict__)

    setattr,delattr,getattr方法

    用法

    class Foo: #Dict
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item): #item='namexxx'
            # print('getitem...')
            return self.__dict__.get(item)
    
        def __setitem__(self, key, value):
            # print('setitem...')
            # print(key,value)
            self.__dict__[key]=value
    
        def __delitem__(self, key):
            # print('delitem...')
            # print(key)
            del self.__dict__[key]
    T = Foo('alex')
    # print(T.__dict__)
    #查,会触发getitem的运行
    print(T['name'])
    #改,会触发setitem的运行
    T['name'] = 'Alex'
    print(T['name'])
    #删除,会触发detitem的运行
    del T['name']
    print(T['name'])

    str,repr,format

    改变对象的字符串显示__str__,repr
    自定制格式化字符串__format__

    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'))

    自定format方法:

    dic_time = {
        'ymd':'{0.year}:{0.month}:{0.day}',
        'dmy':'{0.day}/{0.month}/{0.year}',
        'myd':'{0.month}--{0.year}--{0.day}',
    }
    
    class  Date:
        def __init__(self,year,month,day):
            self.year = year
            self.month = month
            self.day = day
    
        def __format__(self, format_spec):
            if not format_spec or format_spec not in dic_time:
                format_spec = 'ymd'
            fmt = dic_time[format_spec]
            return fmt.format(self)
    d1 = Date(2018,3,22)
    print(format(d1))
    print('{:dmy}'.format(d1))

    del方法

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

    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__()
    print('----main------') #del f #f.__del__()

    二次加工标准类型(包装)

    包装:python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工
    二次加工标准类型(基于继承实现)

    class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid
        def append(self, p_object):
            ' 派生自己的append:加上类型检查'
            if not isinstance(p_object,int):
                raise TypeError('must be int')
            super().append(p_object)
    
        @property
        def mid(self):
            '新增自己的属性'
            index=len(self)//2
            return self[index]
    
    l=List([1,2,3,4])
    print(l)
    l.append(5)
    print(l)
    # l.append('1111111') #报错,必须为int类型
    
    print(l.mid)
    
    #其余的方法都继承list的
    l.insert(0,-123)
    print(l)
    l.clear()
    print(l)

    练习(clear加权限限制)

    class List(list):
        def __init__(self,item,tag=False):
            super().__init__(item)
            self.tag=tag
        def append(self, p_object):
            if not isinstance(p_object,str):
                raise TypeError
            super().append(p_object)
        def clear(self):
            if not self.tag:
                raise PermissionError
            super().clear()
    
    l=List([1,2,3],False)
    print(l)
    print(l.tag)
    
    l.append('saf')
    print(l)
    
    # l.clear() #异常
    
    l.tag=True
    l.clear()
    ```py

    授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。
    实现授权的关键点就是覆盖__getattr__方法

    #**授权示范一**
    import time
    class FileHandle:
        def __init__(self,filename,mode='r',encoding='utf-8'):
            self.file=open(filename,mode,encoding=encoding)
        def write(self,line):
            t=time.strftime('%Y-%m-%d %T')
            self.file.write('%s %s' %(t,line))
    
        def __getattr__(self, item):
            return getattr(self.file,item)
    
    f1=FileHandle('b.txt','w+')
    f1.write('你好啊')
    f1.seek(0)
    print(f1.read())
    f1.close()
    #授权示范二
    #我们来加上b模式支持
    import time
    class FileHandle:
        def __init__(self,filename,mode='r',encoding='utf-8'):
            if 'b' in mode:
                self.file=open(filename,mode)
            else:
                self.file=open(filename,mode,encoding=encoding)
            self.filename=filename
            self.mode=mode
            self.encoding=encoding
    
        def write(self,line):
            if 'b' in self.mode:
                if not isinstance(line,bytes):
                    raise TypeError('must be bytes')
            self.file.write(line)
    
        def __getattr__(self, item):
            return getattr(self.file,item)
    
        def __str__(self):
            if 'b' in self.mode:
                res="<_io.BufferedReader name='%s'>" %self.filename
            else:
                res="<_io.TextIOWrapper name='%s' mode='%s' encoding='%s'>" %(self.filename,self.mode,self.encoding)
            return res
    f1=FileHandle('b.txt','wb')
    # f1.write('你好啊啊啊啊啊') #自定制的write,不用在进行encode转成二进制去写了,简单,大气
    f1.write('你好啊'.encode('utf-8'))
    print(f1)
    f1.close()

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    css3
    js的去重
    mongodb的db.collection is not function
    mongoose的关联查询 :populate
    html/css杂题
    经典的Foo和getName
    AngularJS控制器
    AJAX请求小项目
    AngularJS 依赖注入
    Canvas画布实现自定义时钟效果
  • 原文地址:https://www.cnblogs.com/yjiu1990/p/9144517.html
Copyright © 2011-2022 走看看