zoukankan      html  css  js  c++  java
  • 6. 小数据池-编码-文件操作

    一、小数据池

    1. 小数据池定义

    小数据池(常量池),一种数据缓存机制,也被称为驻留机制。小数据池只针对:整数、字符串、布尔值。其他数据类型不存在驻留机制。

    2. 各类型数据池限定

    (1) 整型

    在python中 -5 ~ 256 之间的整数会被驻留在内存中。每次使用都是同一个对象。

    (2) 字符串

    将一定规则的字符串缓存。在使用的时候,内存中只会创建一个该数据的对象。保存在小数据池中。当使用的时候直接从小数据池中获取对象的内存应用。而不需要创建一个新的数据,这样会节省更多的内存区域。

    优点:能提高一些字符串,整数的处理速度。省略创建对象的过程

    缺点:在“池”中创建或插入新的内容会花费更多的时间

    a. 如果字符串的长度是0或者1, 都会默认进行缓存 
    b. 字符串长度大于1, 但是字符串中只包含字母, 数字, 下划线时才会缓存
    c. 用乘法得到的字符串.
    	①. 乘数为1, 仅包含数字, 字母, 下划线时会被缓存. 如果包含其他字符, 而长度<=1 也会被驻存, 
        ②. 乘数大于1 . 仅包含数字, 字母, 下划 线这个时候会被缓存. 但字符串长度不能大于20 
    d. 指定驻留留. 我们可以通过sys模块中的intern()函数来指定要驻留留的内容.
    
    >>> from sys import intern
    >>> a = intern('alex.sb.com' * 10)
    >>> b = intern('alex.sb.com' * 10)
    >>> a is b
    True
    

    3. py文件与command小数据池区别

    ​ 在代码块内的缓存机制是不一样的. 在执行同一个代码块的初始化对象的命令时, 会检查其值是否已经存在, 如果存在, 会将其重用. 换句话说: 执行同一个代码块时, 遇到初始 化对象的命令时,他会将初始化的这个变量与 值存储在一个字典中, 在遇到新的变量时, 会先在字典中查询记录, 如果有同样的记录那么它会重复使用这个字典中的之前的这个值. 所以在 你给出的例子中, 文件执行时(同一个代码块) 会把a, b两个变量指向同一个对象. 如 果是不同的代码块, 他就会看这个两个变量是否是满足小数据池的数据, 如果是满足小数据池的数据则会指向同一个地址. 所以: a, b的赋值语句分别被当作两个代码块执行, 但是他们不满足小数据池的数据所以会得到两个不同的对象, 因而is判断返回False.

    ​ py文件里. 一个代码块内部. 只会缓存int, str, bool 也有自己的小数据池。 缓存的范围会比外面的代码块的数据池要大

    ​ (1). 数字。都会缓存。 运算的结果不缓存(-5~256 会缓存)

    ​ (2). 字符串。 默认的字符串都缓存. 如果有乘法。 遵循上方的结论

    ​ (3). 布尔值。 默认缓存

    4. is 和 == 区别

    查看内存地址:id(变量)   
    
    is : 判断左右两端内容的内存地址是否一致. 如果返回True, 那可以确定这两个变量量使 用的是同一个对象
    == :判断左右两端的值是否相等. 是不是一致.
    

    二、编码

    1. python2和python编码

    (1) python2 - ASCII

    默认使用ASCII码,所以不支持中文. 如果需要在Python2中更改编码. 需要在文件的开始编写。

    # -- encoding:utf-8 -
    
    (2) python3 - UTF-8
    (1)ASCII : 最早的编码.里面有英文大写字母,小写字母,数字,一些特殊字符.没有中文,8个01代码,8b,1B  (2)GBK: 中文国标码,里面包含了ASCII编码和中文常用编码.16b, 2B
    (3)UNICODE: 万国码, 里面包含了全世界所有国家文字的编码. 32b, 4B, 包含了了 ASCII
    (4)UTF-8: 可变长度的万国码.是unicode的一种实现.最⼩字符占8位;
              英文8b,1B  欧文16b,2B  中文24bit,3B
    	      综上, 除了了ASCII码以外, 其他信息不能直接转换.
    

    2. 编解码

    ​ 在python3的内存中。 在程序运⾏阶段。 使用的是unicode编码。 因为unicode是万国码。 什么内容都可以进行显示。 那么在数据传输和存储的时候由于unicode比较浪费空间和资源。 需要把 unicode转存成UTF-8或者GBK 进行存储。 怎么转换呢。 在python中可以把文字信息进行编码。 编码之后的内容就可以进行传输了。 编码之后的数据是bytes类型的数据。其实啊。 还是原来的数据只是经过编码之后表现形式发生了改变而已。

    ​ bytes的表现形式: (1)英⽂ b'alex' 英⽂的表现形式和字符串没什么两样 (2)中文 b'xe4xb8xad' 这是一个汉字的UTF-8的bytes表现形式

    (1) 举例
    s = "alex"
    print(s.encode("utf-8"))    # 将字符串串编码成UTF-8
    print(s.encode("GBK"))  # 将字符串串编码成GBK
    结果:
    b'alex'
    b'alex'
    s = "中"
    print(s.encode("UTF-8"))    # 中?文编码成UTF-8
    print(s.encode("GBK"))  # 中?文编码成GBK
    结果:
    b'xe4xb8xad'
    b'xd6xd0
    

    备注:英⽂编码之后的结果和源字符串一致.中文编码之后的结果根据编码的不同. 编码结果也不同. 我们能看到. 一个中文的UTF-8编码是3个字节. 一个GBK的中文编码是2个字节. 编码之后的类型就是bytes类型.在网络传输和存储的时候我们python是保存和存储的bytes 类型. 那么在对方接收的时候. 也是接收的bytes类型的数据. 我们可以使用decode()来进行解码操作. 把bytes类型的数据还原回我们熟悉的字符串

    s = "我叫李李嘉诚" 
    print(s.encode("utf-8"))    
    # b'xe6x88x91xe5x8fxabxe6x9dx8exe5x98x89xe8xafx9a' 
    # 解码
    print(b'xe6x88x91xe5x8fxabxe6x9dx8exe5x98x89xe8xafx9a'.decod e("utf-8"))  
    
    s = "我是文字" 
    bs = s.encode("GBK")    # 我们这样可以获取到GBK的文字 
    # 把GBK转换成UTF-8 
    # 首先要把GBK转换成unicode. 也就是需要解码 
    s = bs.decode("GBK")  # 解码 
    # 然后需要进行重新编码成UTF-8 
    bss = s.encode("UTF-8") # 重新编码 
    print(bss)
    

    三、文件操作

    1. 初始文件操作

    ​ 使用python来读写文件时非常简单的操作。我们使用open()函数来打开一个文件,获取文件句柄,然后通过文件句柄就可以进行各种文件操作。打开文件需要close()文件。可使用with上下文进行操作文件。

    2. 文件操作模式

    ​ 文件操作流程:建立文件对象,调用文件方法进行操作,不要忘记关闭文件(文件不关闭的情况下,内容会放在缓存,虽然python会在最后自动把内容读到磁盘)

    (1) r(only-read)
    f = open("file", "r")
    # read逐个字符地全部读取出,read可以指定参数,设定要读取多少字符;无论一个英文字母还是一个汉字都是一个字符
    f_read = f.read()
    
    f = open('file1','r')
    # readlines会把内容以列表的形式输出
    f_read = f.readlines() 
    print(f_read)
    f.close()
    
    # 推荐读取方式
    
    #输出一行内容输出一个空行,一行内容一行空格... 因为文件中每行内容后面都有一个换行符,而且print()语句本身就可以换行,如果不想输出空行,就需要使用下面的语句:print(line.strip())
    f = open('file1','r')
    for line in f.readlines() 
      print(line) 
    f.close()
    
    # 读取图片、视频流文件 - rb
    f = open('file', rb)
    
    (2) w(only-write)

    ​ 在进行操作前,文件中所有内容会被清空。由于Python3的默认编码方式是Unicode,所以在写入文件的时候需要调用utf8,以utf8的方式保存,这时pycharm(默认编码方式是utf8)才能正确读取,当读取文件时,文件是utf8格式,pycharm也是utf8,就不需要调用了。写入字节文件wb

    f = open('file1','w',encoding='utf8')  
    f_w = f.write('hello world')
    #有意思的是,这里并不打印'hello world',只打印写入多少字符
    print(f_w)  
    f.close()
    
    (3) a(append)

    ​ 与w模式不同的是,a模式不会把原来内容清空,而是光标移到内容最后位置,继续写入新内容。比如在最后追加'hello world'

    f = open('file1','a')
    f_a = f.write('hello world')
    #还是会打印写入的字符数
    print(f_a) 
    f.close()
    
    (4) 读取大文件
    num = 0
    # 不要过早关闭文件,否则程序不能识别操作句柄f.
    f.close() 
    f = open('file','r')
    # for内部把f变为一个迭代器,用一行取一行
    for i in f:  
      num += 1
      if num == 5:
        i = ''.join([i.strip(),'hello world'])
      print(i.strip())
    f.close()
    

    3. 其他操作

    (1) tell 和 seek
    f = open('file','r')
    print(f.tell())  #光标默认在起始位置
    f.seek(10)    #把光标定位到第10个字符之后
    print(f.tell())  #输出10
    f.close()
    ----------------------
    f = open('file','w')
    print(f.tell())  #先清空内容,光标回到0位置
    f.seek(10)    
    print(f.tell())
    f.close()
    ----------------------
    f = open('file','a')
    print(f.tell())  #光标默认在最后位置
    f.write('你好 世界')
    print(f.tell())  #光标向后9个字符,仍在最后位置
    f.close()
    
    (2) flush

    ​ 同步将数据从缓存转移到磁盘; 如实现进度条

    import sys,time  #导入sys和time模块
    for i in range(40):
      sys.stdout.write('*')
      # flush的作用相当于照相,拍一张冲洗一张
      sys.stdout.flush()  
      time.sleep(0.2)
    
    # 下面代码也能够实现相同的功能
    import time 
    for i in range(40):
      # print中的flush参数
      print('*',end='',flush=True) 
      time.sleep(0.2)
    
    (3) truncate - 截断

    不能是r模式下执行,w模式下,已经清空所有数据,使用truncate没有任何意义,a模式下,截断指定位置后的内容。

    f = open('file','a')
    # 只显示6个字节的内容(6个英文字符或三个汉字),后面的内容被清空
    f.truncate(6) 
    
    (4) 光标位置总结
    #--------------------------光标总结head-----------------------------------
    f = open('file','r')
    print(f.read(6)) #6个字符
    print(f.tell())  #位置12字节,一个汉字两个字节
    f.close()
     
    f = open('file','r')
    f.seek(6)      #6个字节
    print(f.tell())
    f.close()
     
    f = open('file','a')
    # 光标默认在最后位置
    print(f.tell())  
    f.write('你好 世界')
    # 光标向后9个字节,一个汉字两个字节,仍在最后位置 182-->191
    print(f.tell())  
    f.close()
     
    f = open('file','a',encoding='utf-8')
    # 由于需要光标定位位置,所以也是字节。只显示6个字节的内容(6个英文字母或三个汉字,一个汉字两个字节),后面的内容被清空。
    print(f.truncate(6)) 
    f.close()
    
    (4) r+/w+/a+

    ​ r+:读写模式,光标默认在起始位置,当需要写入的时候,光标自动移到最后

    ​ w+:写读模式,先清空原内容,再写入,也能够读取

    ​ a+:追加读模式,光标默认在最后位置,直接写入,也能够读取。

    f = open('file','a')
    print(f.tell())  #末尾207位置
    f.close()
     
    f = open('file','r+')
    print(f.tell())  #0位置
    print(f.readline()) #读取第一行
    f.write('羊小羚')   #光标移到末尾207位置并写入
    print(f.tell())  #213位置
    f.seek(0)     #光标移到0位置
    print(f.readline())  #读取第一行
    f.close()
    
    (5) 修改文件内容
    由于数据存储机制的关系,我们只能把文件1中的内容读取出来,经过修改后,放到文件2中
    
    f2 = open('file2','w',encoding='utf8')  #写入的时候必须加utf8
    f1 = open('file','r')
    num = 0
    for line in f1: #迭代器
      num += 1
      if num == 5:
        line = ''.join([line.strip(),'羊小羚
    '])  #里面就是对字符串进行操作了
      f2.write(line)
    f1.close()
    f2.close()
    

    4. with语句

    可以同时对多个文件同时操作,当with代码块执行完毕时,会自动关闭文件释放内存资源,不用特意加f.close() ,我们通过下面的示例体会with的用法和好处。用with语句重写8中的代码

    num = 0
    with open('file','r') as f1,open('file2','w',encoding='utf8') as f2:
      for line in f1:
        num += 1
        if num == 5:
          line = ''.join([line.strip(),'羊小羚'])
        f2.write(line)
    
  • 相关阅读:
    SQL Server 幻读 的真实案例
    CSS hack 360浏览器 极速模式与兼容模式
    CS程序中XML编码Encode和解码Decode
    webbrowser 响应关闭事件
    asp.net Checkbox 绑定自定义属性
    企业库实现AOP的几种方法
    c# 自定义log4net过滤器
    SQL Server 并发死锁解决案例备忘
    c# 复制文件夹
    访问 iframe 内部控件方法
  • 原文地址:https://www.cnblogs.com/hq82/p/11336599.html
Copyright © 2011-2022 走看看