文件访问与函数式编程(转载)

一、文本文件读写

  1. 直接读入
file = open('pima-indians-diabetes.txt', 'r')
while True:
    line = file.readline()
    print(line)
    if not line:
        break

用open函数进行读写,第一个参数为文件名,第二个参数可以是‘r’(read),‘w’(write),‘a’(append)。'r'为只读模式,‘w’用写的模式进行打开,写入时会覆盖原来的内容,‘a’在后面添加内容。
读文件有3种方法:

  • read()将文本文件所有行读到一个字符串中。
  • readline()是一行一行的读
  • readlines()是将文本文件中所有行读到一个list中,文本文件每一行是list的一个元素。 优点:readline()可以在读行过程中跳过特定行。
  1. 文件迭代器,用for循环的方法
file2 = open("output.txt","w") 
for line in open("test.txt"): 
      #这里可以进行逻辑处理 
    file2.write('"'+line[:s]+'"'+",")
  1. 文件上下文管理器
#打开文件
#用with..open自带关闭文本的功能
with open('somefile.txt', 'r') as f: 
    data = f.read() 

# loop整个文档
with open('somefile.txt', 'r') as f: 
    for line in f: 
        # 处理每一行

# 写入文本 
with open('somefile.txt', 'w') as f: 
    f.write(text1) 
    f.write(text2) 
    ... 

# 把要打印的line写入文件中 
with open('somefile.txt', 'w') as f: 
    print(line1, file=f) 
    print(line2, file=f)

二、二进制文件读写

Python默认读取的都是文本文件。要是想要读取二进制文件,需要把刚刚的'r'改成'rb'。

f = open('EDC.jpg', 'rb'

任何非标准的文本文件(对于Py2来说,标准是ASCII,对于Py3来说,标准是unicode),你就需要用二进制读入这个文件,然后再用 .decode('...')的方法来解码这个二进制文件:

f = open('DegangGuo.txt', 'rb')
# 读入郭德纲老师的作文, 但是郭老师用的是参合着错别字的繁体编码,假设叫个"DeyunCode"
# 那么你读入以后,就需要解码它
u = f.read().decode('DeyunCode')

三、文件目录的操作

  1. 基本操作
    用Python内置的os模块直接调用操作系统提供的接口函数:
import os
os.name
# 'posix'

这里是通过OS告诉我们 我的操作系统的名字。 如果是posix,说明系统是#nix族,如果是nt,就是Windows。我们可以调用uname()来看看具体信息。

注:import xxx,默认情况下python解析器会搜索当前目录、已安装的内置模块和第三方模块,搜索路径存放在sys模块的path中。对于模块和自己写的脚本不在同一个目录下,在脚本开头加sys.path.append('xxx'):

import sys  
sys.path.append(’引用模块的地址') 
  1. 环境变量
    在操作系统中定义的环境变量,全部保存在os.environ这个dict中,可以直接查看.
os.environ
  1. 操作文件与目录
    查看、创建和删除目录可以这么调用:
# 当前目录的绝对路径
os.path.abspath('.')
# 比如这里返回:'/Users/EDC'
# 在某个目录下创建一个新目录,
# 首先把新目录的完整路径表示出来:
os.path.join('/Users/EDC', 'Pictures')  #详细用法,文末链接
# 这里你得到的是一个字符串,代表了新的文件夹是这个位置:/Users/EDC/Pictures    
# 自己也可以拼起来,但是怕不同操作系统下的区分符问题,最好是用OS接口
# 但是你还并没有创建任何的文件
# 需要用mkdir创建:
os.mkdir('/Users/EDC/Pictures/')
# 同理,删除一个文件夹
os.rmdir('/Users/EDC/Pictures/')

同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:

os.path.split('/Users/EDC/Pictures/AJiao.avi')
# ('/Users/EDC/Pictures/', 'AJiao.avi')

或者靠os.path.splitext()得到文件扩展名:

os.path.splitext('/Users/EDC/Pictures/AJiao.avi')
# ('/Users/EDC/Pictures/AJiao', '.avi')

文件重命名:

os.rename('JAV-001.avi', '学习资料')

删除文件:

os.remove('学习资料')

python 中的复制文件操作不在os模块中,需要导入第三方包进行复制:

import shutil  
shutil.copyfile('/path/to/file', '/path/to/other/file') 

四、序列化和反序列化

程序运行的过程中,所有变量都是在内存中操作的,当程序一旦执行完毕,结束退出后,变量占有的内存就被操作系统回收了。 因此我们需要将某些数据持久化存储到磁盘中,下次运行的时候从磁盘中读取相关数据。
我们将变量从内存中变成可以存储或传输的过程称之为序列化,在Python中叫做pickling,在其它语言中也称之为 serialization、marshaling、flattening等等,说的都是一个意思。 反之,则为反序列化,称之为unpickling,把变量内容从序列化的对象重新读取到内存中。

import pickle
# 此处定义一个dict字典对象
d = dict(name='思聪', age=29, score=80)
str = pickle.dumps(d) # 调用pickle的dumps函数进行序列化处理
print(str)
# 定义和创建一个file文件对象,设定模式为wb
f = open('dump.txt', 'wb')
# 将内容序列化写入到file文件中
pickle.dump(d, f)
f.close() # 最后关闭掉文件资源

刚刚的搞成的“序列化”的码,转成python看得懂的object

import pickle

# 从之前序列化的dump.txt文件里边读取内容
f = open('dump.txt', 'rb') # 设定文件选项模式为rb
d = pickle.load(f) # 调用load做反序列处理过程
f.close() # 关闭文件资源
print(d)
print('name is %s' % d['name'])

稍微注意一下,python2和python3里面的pickle不一样。为了保证2,3的和谐,你可以用这个方法来保证你import正确:

try:
    import cPickle as pickle
except ImportError:
    import pickle

五、Lambda表达式
Lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
arg 为参数列表;expression为简单的逻辑;
例如相加函数:

sum = lambda arg1, arg2: arg1 + arg2
sum(10, 20)
# 输出30

除了Lambda本身,Python还提供了其他几个辅助工具。

  • reduce
    Python中的reduce内建函数是一个二元操作函数,他用来将一个数据集合(列表,元组等)中的所有数据进行如下操作:传给reduce中的函数func() (必须是一个二元操作函数)先对集合中的第1,2个数据进行操作,得到的结果再与第三个数据用func()函数运算,最后得到一个结果。顾名思义,reduce就是要把一个list给缩成一个值。所以必须用二元操作函数。
from functools import reduce
l = [1,2,3,4,5]
print(reduce(lambda x,y: x+y, l))
# 这里代表着,把list中的值,一个个放进lamda的x,y中
# 输出15
# 如果你给出一个初始值,可以放在list后面
print(reduce(lambda x,y: x+y, l, 10))
# 这样,x开始的时候被赋值为10,然后依次
# 输出25
  1. map
    map函数应用于每一个可迭代的项,返回的是一个结果map。如果有其他的可迭代参数传进来,map函数则会把每一个参数都以相应的处理函数进行迭代处理。map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的map返回。
l = [1,2,3]
new_list = list(map(lambda i: i+1, l))
print(new_list)
# Py3里,外面需要套个list:
# 这是为了让里面的值给显示出来,要不然你会得到这是个map函数
# 而不是里面的值。
# Py2的童鞋不虚
# 输出[2, 3, 4]
# 我们也可以把两个数组搞成一个单独的数组
l2 = [4,5,6]
new_list = list(map(lambda x,y: x+y, l, l2))
print(new_list)
# 输出[5, 7, 9]
  1. filter
    filter()函数可以对序列做过滤处理,就是说可以使用一个自定的函数过滤一个序列,把序列的每一项传到自定义的过滤函数里处理,并返回结果做过滤。最终一次性返回过滤后的结果。 和map()类似,filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
l = [100, 20, 24, 50, 110]
new = list(filter(lambda x: x<50, l))
# 同理,py3得套个list来转化成list函数,便于打印出来
print(new)
# 输出 [20, 24]

【参考资料】:

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容