• 面向对象的高级编程&IO编程


    1.给类对象绑定的函数,只对这个对象生效, 而对类绑定的对象, 所有的对象都可以调用. 栗子:

    def set_score(self, score):
        self.score = score
    
    s.set_age = MethodType(set_score, s)    #对象绑定
    
    Student.set_score = MethodType(set_score, Student)    #绑定类

    动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现

    2.使用__slots__ 限制实例属性. 在定义class的时候,定义一个特殊的__slots__变量, 限制该class实例能添加的属性

    class Student(object):
        __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称

    要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

    3.使用@property可以将python定义的函数"当做"属性访问, 从而提供更加友好的访问方式, 但有时候setter/getter也是需要的.

    内置装饰器负责把一个方法变成属性调用, 它既能检查参数,又可以用类似属性这样简单的方式来访问变量.

    4.多重继承

    class Animal(object):
        pass
    
    # 大类:
    class Mammal(Animal):
        pass
    
    class Bird(Animal):
        pass
    
    # 各种动物:
    class Dog(Mammal):
        pass
    
    class Bat(Mammal):
        pass
    
    class Parrot(Bird):
        pass
    
    class Ostrich(Bird):
        pass

    IO编程

    #!/usr/bin/env python
    # encoding: utf-8
    f = open('./testdir/test.txt', 'r')  #'r'表示读
    
    f.read()    #一次读取文件的全部内容
    
    f.close()   #关闭文件
    
    #文件读写出错都可能产生IOError,一旦出错,f.close就不能调用
    #为保证无论是否出错都能正确关闭文件,我们用try...finally实现
    
    try:
        f = open('./testdir/Forever.mp3', 'rb')
        print(f.read())
    finally:
        if f:
            f.close()
    
    #每次这样写太繁琐,引入with语句自动帮我们调用方法:
    with open('./testdir/test.txt', 'r') as f:
        print(f.read())
    
    # read(size)防止一次性读取文件过多,内存负荷,可以反复调用
    # 调用readline()可以每次读取一行内容
    # 调用readlines()一次读取所有的内容并按行返回list
    
    #如果文件很小,read()一次性读取最方便;如果不能确定文件大小,
    #反复调用read(size)比较保险;
    #如果是配置文件,调用readlines()最方便
    
    for line in f.readlines():
        print(line.strip)   #把末尾的'
    '删掉
    
    ##file-like Object不要求从特定类继承,只要写个read()方法就行
    # StringIO就是在内存中创建的file-like Object,常用作临时缓冲
    
    #读取二进制文件,如图片视频音频等,用'rb'
    #要读取非UTF-8编码的文本文件,需要给open()函数传入encoding参数
    #       栗子:读取GBK编码的文件
    f = open('./testdir/Forever.mp3', 'rb')
    f.read()
    
    f = open('./testdir/test.txt', 'r', encoding = 'gbk')
    f.read()
    
    #某些不规范文件,会遇到UnicodeDecodeError,因为在文本文件中可能
    #夹杂了一些非编码的字符. 这是open()函数还接收一个errors参数,
    #表示如果遇到编码错误后如何处理. 最简单处理是直接忽略
    f = open('./testdir/Forever.mp3', 'r', encoding = 'gbk', errors = 'ignore')
    
    
    #写文件 'w'文本文件, 'wb'二进制文件
    f = open('./testdir/test.txt', 'w')
    f.write('gogleem')
    f.close()
    
    #保险的with语句,防止忘记写close
    with open('./testdir/test.txt', 'w') as f:
        f.write('Frente!')
    
    #要写入特定编码的文本文件,请给open()函数传入encoding参数,
    #        字符串自动转换成指定编码
    
    #使用with语句操作文件IO是个好习惯
    # w是覆盖, a是续写

     StringIO和BytesIO

     StringIO:内存中读写str, 要把str写入StringIO,我们需要先创建一个StringIO,然后像写文件一样写入即可

    from io import StringIO
    f = StringIO()
    f.wrie('hello')
    f.wrie(' ')
    f.wrie('world!')
    print(f.getvalue())
    #getvalue()方法用于获得写入后的str

    要读取StringIO可以用一个str初始化StringIO, 然后像读文件一样读取

    from io import StringIO
    f = StringIO('      Hello!
         Goodbye!    ')
    while True:
        s = f.readline()
        if s =='':    #不太明白这里判断这个的意思
           break    #但是没有这个,会影响下面的打印
        print(s.strip())    #strip()函数能够去掉字符串前后的空格

    BytesIO

    操作二进制数据,实现了在内存中读写bytes,我们创建 一个BytesIO, 然后写入一些bytes

    from io import BytesIO
    f = BytesIO()
    f.write('中文'.encode('utf-8'))
    print(f.getvalue())
    
    #from io import StringIO
    f = BytesIO(b'xe4xb8xadxe6x96x87')
    f.read()
    #和stringIO类似,可以用一个bytes初始化BytesIO,然后像读文件一样读取
    
    #读文件和读二进制与读文件的区别是,from import的不同,打开的不同
    #读文件使用open, 读StringIo用StringIO,而读BytesIO用的是BytesIO打开
    #其他的读写操作是一样的,接口一致

    操作文件和目录

    Python内置的os模块可以直接调用操作系统提供的接口函数.

    linux下的shell指令,前面加上os就可以在python中使用了. 栗子: os.uname()

    import os
    #import shutil
    a = os.path.abspath('.')
    #当前文件的绝对路径
    b = os.path.abspath('./animal/animal.py')
    print(a, '
    ', b)
    c = os.path.join('/yu/you', 'imhp.txt')
    #将路径和文件名连接,完整的目录表示出来
    print(c)
    os.mkdir('/home/feixiao/demo/Py_Rabbic/a')
    #创建一个目录
    os.rmdir('/home/feixiao/demo/Py_Rabbic/a')
    #注意,linux和mac下路径分隔符是/,win下是
    d = os.path.split('/home/feixiao/demo/Py_Rabbic/testdir/test2.txt')
    #把路径拆分为目录和文件名
    print(d)
    print(d[0])
    print(d[1])
    #拆分路径名不要求文件一定存在
    open('out.md', 'w')
    os.rename('out.md', 'out.txt')
    #重命名文件
    os.remove('out.txt')
    #移除文件
    
    #os模块中不存在复制文件
    
    #求一个shutil模块copyfile()函数拷贝文件的栗子~~~><~~~
    
    #os模块封装了操作系统的目录和文件操作,这些函数有的在os模块中,有的在os.path

    序列化

    序列化在这里不介绍了,上一篇文章有用CPP实现的专门的一篇

    import pickle
    #序列化头文件
    d = dict(name = 'Jared', age = 43, score = 100)
    c = pickle.dumps(d)
    #序列化字典d中的内容,打印出来
    print(c)
    #python的好处就是可以把任何东西赋值成一个变量
    
    f = open('./testdir/test.txt', 'wb')
    pickle.dump(d, f)
    #把d的内容序列化后写入f文件中
    f.close()
    
    f = open('./testdir/test.txt', 'rb')
    d = pickle.load(f)
    #读文件中序列化记录的文件, 反序列化读出
    f.close()
    print(d)

    JSON

    #在不同编程语言间传递对象
    #把对象序列化为标准格式,如XML,ini,但更好的方法是序列化为JSON
    #因为JSON表示出来是一个字符串,可被所有语言读取,也可以方便存储到磁盘或网络传输
    #JSON比XML快,可以直接在Web页面中读取
    
    #
    import json
    d = dict(name = 'Jared', age = 43, score = 100)
    c = json.dumps(d)
    #dumps()方法返回一个str, 内容就是标准的JSON.它可以把JSON写入一个file-like-Object
    #要把JSON反序列化为Python对象,用loads()或者对应的load()方法
    #前者把JSON字符反序列化,后者从file-like-object中读取字符串并反序列化
    print(c)
    
    json_str = '{"age":43, "score":100, "name":"Jared"}'
    #哈,这里很有意思的引号,开始我用的全是单引号,报错了,分析是age的前引号被当字符串后引号配对了
    #所以,就把引号中的引号换了
    c = json.loads(json_str)
    print(c)
    #JSON编码是utf-8,所以Py的str可以与之自由交换

    序列化类

    import json
    class Student(object):
        def __init__(self, name, age, score):
            self.name= name
            self.age = age
            self.score = score
    #python类的序列化函数与CPP不同,序列化函数不在类中
    #而C++中嵌入式序列化ar & a是在类中的
    def student2dict(std):
        return{#这个序列化函数,把要打印的数据放到一个dict的字符串中
                'name':std.name,
                'age':std.age,
                'score':std.score
              }
    s = Student('Jared', 43, 100)
    print(json.dumps(s, default = student2dict))
    
    #把任意class的实例变为dict:
    print(json.dumps(s, default = lambda obj:obj.__dict__))
    #这依然需要序列化函数,把类序列化到dict中
    
    #通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量.
    #也有少数例外,比如定义了__slots__的class.
    #同,要把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,
    #然后,传入 object_hook函数负责把dict转换为Student实例:
    
    #类的反序列化
    #def dict2student(d):
    #    return Student(d['name'], d['age'], s['score'])
    #json_str = '{"age":43, "score":100, "name":"Jared"}'
    #print(json.loads(json_str, object_hook = dict2student))
    #我自己写的这段不知道为啥就是会报错/V
    def dict2student(d):
            return Student(d['name'],d['age'],d['score'])
    json_str = '{"age": 20, "score": 88, "name": "Bob"}'
    print(json.loads(json_str, object_hook=dict2student))
    #打印出反序列化的Student实例对象
    
    #Python语言特定的序列化模块是pickle,但要使序列化更通用,更符合Web标准,用json
    
    # json模块的dumps()和losds()函数是定义的非常好的接口典范
    #使用时,只需传入一个必须的参数
    #当默认机制不满足要求,传入更多参数,
    #既做到了接口简单易用,又做到了充分的扩展性和灵活性
  • 相关阅读:
    MySQL 不同版本数据导入的问题
    利用 ps 命令查看进程的位置
    MySQL 重置 root 密码
    killall 中的 signal
    Kafka 的安装及启动
    TypeScript 中 Optional Chaining 和 Nullish Coalescing
    Redis 的使用
    TypeScript 中限制对象键名的取值范围
    React17 使用 JSX 的情况下无须再显式导入 React
    使用 golang 获取远程地址视频的时间
  • 原文地址:https://www.cnblogs.com/feixiao5566/p/5253496.html
Copyright © 2020-2023  润新知