十:python 对象类型详解六:文件
一:文件
1.简介:内置open 函数会创建一个python 文件对象,可以作为计算机上的一个文件链接。在调用open 之后,可以通过调用返回文件对象的方法来读写相关外部文件。文件对象只是常见文件处理任务输出模块。
2,打开文件:为了打开一个文件,程序会调用内置open 函数,首先是外部名,接着是处理模式。模式典型地用字符串“r” 代表读文件,“w” 代表以写模式打开文件,“a” 代表在文件末尾追加内容而打开文件。同时,在模式字符串尾部加上 b 可以进行二进制数据处理,加上“+” 意味着同时为输入和输出打开文件。
3,使用文件:一旦存在一个文件对象,就可以调用其方法来读写相关的外部文件。注意,在任何情况下,Python 程序中的文本文件都采用字符串的形式。读取文件时会返回字符串形式的文本,文本作为字符串传递给 write 方法。
a) 文件迭代器是最好的读取行工具:现在从文本文件读取文字行的最佳方式是根本不要读取该文件。文件也有个迭代器会自动地在for 循环、列表解析或其它方式对文件进行逐行读取。
b) 内容是字符串,不是对象:注意从文件读取的数据回到脚本时是一个字符串。所以如果字符串不是你所需的,就得将其转换成其他类型的python 对象。当我们写入文件时,python 不会把对象自动转换为字符串------你必须传递一个已经格式化的字符串。str() 也许会派上用场。另外,Python 也包括一些高级标准库工具,它用来处理一般对象的存储(如 pickle 模块)以及处理文件中打包的二进制数据(例如,struct 模块)。
c) close 是通常选项:调用 close 方法将会终止对外部文件的连接。通常手动关闭没有任何坏处,而且这是个不错的习惯。
d)文件是缓冲的并且是可查找的:前面提到过手动关闭文件,因为这样既释放了操作系统资源也清空了缓冲区。默认情况下,输出文件总是缓冲的,这就是说,写入的文本不可能立即自动从内存转换到硬盘------关闭一个文件,或者允许其 flush 方法,迫使缓存的数据进入硬盘。同时,python 文件也是在字节偏移的基础上随机访问的,它们的seek 方法允许脚本跳转到指定的位置读取或写入。
二:实际应用中的文件:
1,注意write 方法不会为我们添加行终止符,所以程序必须包含它来严格地终止行。如果想要显示带有转义字符解释的文件内容,用对象的read 方法把整个文件读入到一个字符串中,并打印它:
- >>> myfile = open(r'D:\test\myfile.txt','w')
- >>> myfile.write('hello text file\n')
- 16
- >>> myfile.write('goodbye text file\n')
- 18
- >>> myfile.close
- <built-in method close of _io.TextIOWrapper object at 0x02A7BC30>
- >>> myfile = open(r'D:\test\myfile.txt','r')
- >>> myfile.readline()
- 'hello text file\n'
- >>> myfile.readline()
- 'goodbye text file\n'
- >>> myfile.readline() #已经到达文件末尾
- ''
用read 方法和print 的形式:
- >>> file = open(r'D:\test\myfile.txt','r')
- >>> file.read()
- 'hello text file\ngoodbye text file\n'
- >>> print(file.read()) #print 解释了转义字符的含义
- hello text file
- goodbye text file
如果想要一行一行地扫描一个文本文件,文件迭代器往往是最佳选择:
- >>> for line in open(r'D:\test\myfile.txt','r'):
- ... print(line,end = '') #end = ' ' 意思为不换行
- ...
- hello text file
- goodbye text file
2,Python 3.0 中的文本和二进制文件:上述实例中使用了文本文件,在3.0 和 2.6 版本中,文件类型都是由open 的第二个参数决定,模式字符串包含一个”b“ 表示二进制。python 中总是支持文本文件和二进制文件,但是在python 3.0 中,二者之间没有明显的区别:
a) 文本文件把内容表示为常规的 str 字符串,自动执行Unicode 编码和解码,并且默认执行末行转换。
b) 二进制文件把内容表示为一个特殊的bytes 字符串类型,并且允许程序不修改的访问文件内容。
Note:如果需要处理国际化应用程序或者面向字节的数据,Python 3.0 中的区别会影响到代码。通常,你必须使用bytes 字符串处理二进制文件,并且用常规的 str 字符串处理文本文件。不能以文本模式打开一个二进制文件。
3,在文件中存储并解析Python 对象:
注意,当我们写入文件的时候,一定要将内容转换为字符串,因为写入方法不会自动地替我们做任何向字符串格式转换的工作。
- >>> chars = open(r'D:\test\datafile.txt','r')
- >>> chars.read()
- "spam\n43,44,45\n[1, 2, 3]${'a': 1, 'b': 2}\n"
4,rstrip() 函数和 split() 函数用例:
- >>> line = 'end '
- >>> line.rstrip() #字符串 rstrip() 方法去掉多余的行终止符
- 'end'
- >>> line = '43,44,45\n'
- >>> line.split(',') #字符串 split() 方法,用逗号断开整行,返回字符串列表
- ['', '', '45\n']
对于存储 的列表和字典,我们可以运行 eval() 这一内置函数,eval() 能够把字符串当作可执行程序代码。也可以用来执行字符串表达式,并返回表达式的值:
- >>> parts
- ['[1,2,3]', "{'a':1,'b':2}\n"]
- >>> eval(parts[0]) #eval() 函数把字符串对象转化为对象
- [1, 2, 3]
5,用pickle 存储Python 的原生对象:使用 eval() 可以把字符串转换为对象。事实上,eval() 有时会太过于强大。eval() 会高高兴兴地执行 python 的任何表达式,甚至是有可能会删除计算机上的所有文件的表达式,只要给予必要的权限。如果想要存储 Python 原生对象,但又无法信赖文件数据的来源,Python 标准库pickle 模块会是个理想的选择。pickle 模块是能够让我们直接在文件中存储几乎任何python 对象的高级工具,也并不需要求我们把字符串转来转去。例如,如果想要在文件中存储字典,就直接用pickle 来存储:
- >>> D = {'a':1,'b':2}
- >>> F = open(r'D:\test\datafile.pkl','wb') #二进制写入模式打开
- >>> import pickle #导入pickle包
- >>> pickle.dump(D,F) #把字典D存入文件F
- >>> F.close()
- >>> F = open(r'D:\test\datafile.pkl','rb') #二进制读出模式打开
- >>> E = pickle.load(F) #将文件中的内容读出
- >>> E
- {'a': 1, 'b': 2}
pickle 模块执行所谓的对象序列化,也就是对象和字节字符串之间的相互转换。但我们要做的工作却很少。事实上,pickle 内部将字典转成字符串形式。例如
- >>> open(r'D:\test\datafile.pkl','rb').read()
- b'\x80\x03}q\x00(X\x01\x00\x00\x00aq\x01K\x01X\x01\x00\x00\x00bq\x02K\x02u.'
Note:我们用二进制模式打开用来存储pickle化的对象的文件,因为pickle程序创建和使用一个bytes 字符串对象,并且这些对象意味着二进制模式文件(文本模式文件意味着str 字符串)。
6,文件中打包二进制数据的存储与解析:struct 模块能够构造并解析打包的二进制数据。从某种意义上说,它是另一个数据转换工具,它能够把文件中的字符串解读为二进制数据。例如,要生成一个打包的二进制数据文件,用 'wb'(二进制写入)模式打开它,并将一个格式化字符串和几个Python 对象传给 struct。如下:
- >>> F = open(r'D:\test\data.bin','wb') #用‘wb’打开
- >>> import struct
- >>> data= struct.pack('ii',7,8) #打包写入数据(‘ii’ 为数据格式)
- >>> data
- b'\x07\x00\x00\x00\x08\x00\x00\x00' #十六进制转义的格式进行打印
- >>> F.write(data) #数据写入文件F
- 8
- >>> F.close()
- >>> F = open(r'D:\test\data.bin','rb') #用‘rb’进行读取
- >>> data = F.read()
- >>> data
- b'\x07\x00\x00\x00\x08\x00\x00\x00'
- >>> values = struct.unpack('ii',data) #用相同的格式进行解压缩
- >>> values
- (7, 8)
7,上下文管理器:比文件多了一个异常处理的功能,它不允许我们把文件处理代码包装到一个逻辑层中,以确保在退出后可以自动关闭文件,而不是依赖于垃圾收集上的自动关闭。
三:其他文件工具:
1,seek() 函数能够复位你在文件中的当前位置(下次读写将应用在该位置上),flush 能够强制性地将缓存输出写入磁盘(文件总会默认进行缓冲)等。
2,需要注意的是,虽然open() 函数及其返回的文件对象是 Python 脚本中通向外部文件的主要接口,Python 中还有其他类似的文件工具,例如:
a) 标准流:在sys 模块中预先打开的文件对象,例如 sys.stdout
b) os 模块中的描述文件:
c) sockets,pipes 和 FIFO 文件:文件类对象,用来同步进程或者通过网络进行通信。
d) 通过键来存取的文件:
e) Shell 命令流
四:重访类型分类:
1,共享操作:字符串、列表、元组都共享合并、长度、索引等序列操作。
2,只有可变对象(列表、字典、集合)可以原处修改;我们不能修改数字、字符串、串或者元组。
3,Python 中的bytearray 字符串类型是可变的。
4,frozenset 是集合的一个不可变的版本。
五:对象灵活性:
1,列表、字典和元组可以包含任何种类的对象。
2,列表、字典和元组可以任意嵌套。
3,列表和字典可以动态地扩大和缩小。
六:引用 VS 拷贝:
1,赋值操作总是存储对象的引用,而不是这些对象的拷贝。不过,因为赋值操作会产生相同对象的多个引用,需要意识到在原处修改可变对象时可能会影响程序中其他地方对相同对象的引用。如果你不想这么做,就需要明确地告诉Python 复制该对象。
- >>> x = [1,2,3]
- >>> L = ['a',x,'b'] #L和D共享x列表
- >>> D = {'X':x,'y':2}
- >>> x[1] = 'surprise' #改变共享列表对象
- >>> L
- ['a', [1, 'surprise', 3], 'b'] #L和D也会改变
- >>> D
- {'X': [1, 'surprise', 3], 'y': 2}
- >>>
2,如果你需要在途中产生拷贝,下面是拷贝的几种方法:
a) 没有限制条件的分片表达式 (L[ : ])能够复制序列。
b) 字典copy() 方法(X.copy())能够复制字典。
c) 有些内置函数 (例如,list)能够生成拷贝
d) copy 标准库模块能够生成完整拷贝。(深度拷贝)
3,拷贝需要注意的是,我们可以通过对原始列表进行分片而不是简单的命名操作来避免引用的副作用:
- >>> x = [1,2,3]
- >>> L = ['a',x[:],'b'] #利用分片生成一个新的对象,对L和D做修改不会影响x
- >>> D = {'X':x[:],'y':2}
4,另外,对拷贝还需要注意:无条件值的分片以及字典copy 方法只能做顶层复制。也就是说,不能够复制嵌套的数据结构。如果需要一个完整的、完全独立的拷贝,那么就要使用标准的copy模块-----包括import copy 语句,并编辑 X = copy.deepcopy(Y) 对任意嵌套对象Y做完整的复制。这一调用语句能够递归地遍历对象来复制它们所有的组成部分。
七:比较、相等值和真值:
1,所有的 Python 对象也可以支持比较操作---测试相等性、相对大小等。当嵌套对象存在时, Python 能够自动遍历数据结构,从左到右递归地应用比较。
- >>> L1 = [1,('a',3)]
- >>> L2 = [1,('a',3)]
- >>> L1 == L2 # ‘==’ 测试值的相同性
- True
- >>> L1 is L2 # ‘is’ 测试对象的一致性(是否在同一个内存地址中)
- False
注意,如果时短字符串会出现什么情况:
- >>> s1 = 'spam'
- >>> s2 = 'spam'
- >>> s1 == s2
- True
- >>> s1 is s2
- True
这是因为在Python 内部暂时存储并重复使用短字符串作为最佳化,事实上内存里只有一个字符串‘spam’供 s1 和s2 分享。
2,Python 中不同类型的比较方法如下:
a)数字通过相对大小进行比较
b)字符串是按照字典排序,一个字符一个字符地对比进行比较
c)列表和元组从左到右对每部分的内容进行比较
d)字典通过排序之后(键、值)列表进行排序。
3,在python 3.0 中,字典的大小比较删除了,替代方案:要么编写循环来根据键比较值,要么手动比较排序的键/值列表------items 字典方法和内置的sorted()足够了:
- >>> D1 = {'a':1,'b':2}
- >>> D2 = {'a':1,'b':3}
- >>> D1 == D2
- False
- >>> D1 < D2 #字典之间不支持比较
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: '<' not supported between instances of 'dict' and 'dict'
- >>> list(D1.items())
- [('a', 1), ('b', 2)]
- >>> sorted(D1.items()) #用sorted()对items 进行排序
- [('a', 1), ('b', 2)]
- >>> sorted(D1.items()) < sorted(D2.items())
- True
八:Python 中真和假的含义:
1,数字如果非零,则为真;
2,其他对象如果非空,则为真;
3,None对象: None,总被认为是假。这是Python 中一种特殊数据类型的惟一值,一般都起到一个空的占位符作用,与C语言中的NULL指针类似;
Note: None 不是意味着“未定义”,也就是说,None 是某些内容,而不是没有内容(尽管起名字是没有内容)----它是一个真正的对象,并且有一块内存,有python 给定一个内置的名称。
4,bool 类型: Python 也提供了一个内置函数bool,它可以用来测试一个对象的布尔值:>>>bool(1) >>>True
5,Type 对象:对内置函数 type(X),能够返回对象X 的类型对象,此外,python 3.0 中的类型标准库模块同样提供其他不能作为内置类型使用类型的名称,而且用 isinstance() 函数进行类型测试也是可能的。例如:
- True
- >>> type([1]) == type([])
- True
- >>> type([1]) == list
- True
- >>> isinstance([1],list)
- True
isinstance(object,class):用来判断对象是不是和指定类型相同,若相同,返回True;
九:Python 中的其它类型
1,赋值生成引用,而不是拷贝;
2,重复能够增加层次深度:
- >>> L = [1,2,3]
- >>> X = L *4
- >>> Y = [L] * 4
- >>> X
- [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
- >>> Y
- [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
由于L在第二次重复中是嵌套的,Y结束嵌套的引用,返回赋值为L的原始列表。
- >>> L = [4,5,6]
- >>> X = L * 4 #未共享引用L,L改变不影响X
- >>> Y = [L] * 4 #共享引用L,L改变影响Y
- >>> L[1] = 0
- >>> X
- [4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
- >>> Y
- [[4, 0, 6], [4, 0, 6], [4, 0, 6], [4, 0, 6]]
3,留意循环数据结构:如果遇到一个复合对象包含指向自身的引用,就称之为循环对象。
- >>> L = ['grail']
- >>> L.append(L) #自身引用自身
- >>> L
- ['grail', [...]]
4,不可变类型不可以在原处改变:如果需要的化,可以通过分片、合并等操作来创建一个新的对象,再向后赋值给原引用。
- >>> T = (1,2,3)
- >>> T[2] = 4 #不能原地修改元组
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: 'tuple' object does not support item assignment
- >>> T = T[:2] + (4,) #可以通过分片和合并操作创建一个新对象
- >>> T
- (1, 2, 4)
十:python 对象类型详解六:文件的更多相关文章
- 六:python 对象类型详解二:字符串(下)
一:字符串方法: 方法就是与特定对象相关联在一起的函数.从技术的角度来讲,它们是附属于对象的属性,而这些属性不过是些可调用的函数罢了.Python 首先读取对象方法,然后调用它,传递参数.如果一个方法 ...
- 三:python 对象类型详解一:数字(上)
一:python 的数字类型: a)整数和浮点数 b)复数 c)固定精度的十进制数 d)有理分数 e)集合 f)布尔类型 g)无穷的整数精度 h)各种数字内置函数和模块 二:各种数字类型的详解 1,数 ...
- 四:python 对象类型详解一:数字(下)
一:位操作 除了一般的数学运算,python也支持c语言中的大多数数学表达式.这包括那些把整数当作二进制位串对待的操作.例如,还可以实现位移及布尔操作: >>> x = 1 > ...
- 七:python 对象类型详解三:列表
一:列表简介: 1,列表可以包含任何种类的对象:数字.字符串甚至集合对象类型.列表都是可变对象,它们都支持在原处修改的操作,可以通过指定的偏移量和分片.列表方法调用.删除语句等方法来实现.关键的作用有 ...
- 九:python 对象类型详解五:元组
一:元组: 1,简单介绍:元组由简单的对象组构成.元组与列表非常类似,只不过元组不能在原处修改(它们)是不可变的,并且通常写成圆括号中的一系列项.虽然元组不支持任何方法调用,但元组具有列表的大多数属性 ...
- 八:python 对象类型详解四:字典
一:字典通识: 1,字典通过键而不是偏移量来读取: 2,字典是任意对象的无序集合: 3,字典可变长.异构.任意嵌套: 4,字典属于可变映射类型: 5,对象引用表(散列表): 二:实际应用中的字典: 1 ...
- 五:python 对象类型详解二:字符串(上)
一:常量字符串 常量字符串用起来相对简单,也许最复杂的事情就是在代码中有如此多的方法来编写它们. eg:单引号:'spam"m' , 双引号: “spa'm” , 三引号:‘’‘... ...
- JavaScript中的对象类型详解
To be finished 摘要 1.什么是对象? 2.引用类型和原始类型 3.对象数据属性拥有的特性(Attributes) 4.如何创建对象 a.直接定义 var mango={color:&q ...
- ECMAScript---object对象类型详解
普通对象:由大括号包裹起来的,由零到多个属性名和属性值(键值对)组成的 那什么是属性呢? 属性:描述当前对象特征的,属性名是当前具备这个特征,属性值是这个特征的描述(专业语法,属性名称为键[key], ...
随机推荐
- FLEX中一组基于button的组件
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...
- DOS 和 DDOS 攻击
<一>: ICMP 协议 01: 是什么 => 互联网信心控制协议. Internet Control Message Protocol 02: 干什么 => 用于实现链路连通 ...
- JS 对象(对象遍历,拷贝)
定义属性 直接 obj.对象 的方法 Object.defineProperty(obj, prop, descriptor) ,这种方法可以设置 或者修改对象属性的访问权限 数据描述符和存取描述符 ...
- MVC基于角色权限控制--菜单展示
在用户成功登陆后台页面后,我们需要将当前用户拥有的权限通过菜单的形式展现出来,将未具备的权限隐藏 新建一个HomeController,用于展示后台首页和获取用户权限数据 namespace CZBK ...
- nosql数据库:mongodb,redis,memcached,其优缺点和使用应用场景
1.mongodb (1)是文档型的非关系型数据库,使用bson结构.其优势在于查询功能比较强大,能存储海量数据,缺点是比较消耗内存. (2)一般可以用来存放评论等半结构化数据,支持二级索引. 适合存 ...
- C#可变参数params
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestPara ...
- 1.13.Mark1
[经济学人]双语阅读:律师事务所 标价更高 收益更少 Business 商业报道 Law firms 律师事务所 Charging more, getting less 标价更高,收益更少 L ...
- python模块sys
#!/bin/env python #-*- encoding=utf8 -*- import sys if __name__=="__main__": # 在解释器启动后, ar ...
- 如何进行SQL排序
order by 语法如下: SELECT "栏位名" FROM "表格名" [WHERE "条件"] ORDER BY "栏位名 ...
- KVM虚拟化技术(四)安装虚拟机
一.首先用比较简单的virt-manager来安装 # virt-manager 后面就是一般的安装系统流程了,这里不再复述 二.用virt-install命令行来安装 还是通过本地IOS文件来进行安 ...