Python编程进阶01-输入输出文件操作

一、输出输出

【输入】

  • Python提供了input内置函数从标准输入(键盘)读取一行文本
  • input()函数也可以接受一个Python表达式作为输入,并将运算结果返回
  • input()函数的返回值永远是字符串,当我们需要返回int型时需要使用int(input())

注:eval()函数用来执行一个字符表达式,并返回表达式的值

str = input("请输入:");
print("你的输入是:",str)
sum = input("请输入算术表达式:")
sum = eval(sum)   # eval()函数用来执行一个字符串表达式,并返回表达式的值
print(sum)

执行结果: 

请输入:Python机器学习
你的输入是: Python机器学习
请输入算术表达式:3+7
10

如果我们想要输入int型,按如下形式int(input()) ,如果不是这样输出的话,age将会是str类型的,自己试一下

>> name = input("输入姓名:")
>> print(name)

>> age = int(input())
>> print(age)
>> print(type(age))
输入姓名:Lily
Lily
20
20
<class 'int'>

【输出】

  • 用print()在括号里面加上字符串,就可以向屏幕横向输出指定的文字
  • print()函数也可以接受多个字符串,用逗号隔开,就可以连成一串输出:
  • print()会一次打印每个字符串,遇到逗号“,”会输出一个空格,因此,输出的字符串的是这样拼接起来的
>> print('The quick brown fox','jumps over','the lazy dog')
The quick brown fox jumps over the lazy dog
  • print()函数可以打印整数,或直接计算结果:
  • print()函数也可以接受多个字符串,用逗号隔开,就可以连成一串输出
>> print(300)
>> print(100+200)
>> print('100 + 200 =',100+200)
300
300
100 + 200 = 300

整数的输出:

%o--oct八进制
%d--dec十进制
%x--hex十六进制

>> print('%o'%20)
>> print('%d'%20)
>> print('%x'%20)
24
20
14

【格式化输出】

  • 浮点数的输出
>> print('%f'%1.11)   # 默认保留6位小数
>> print('%.1f'%1.11) # 取1位小数
>> print('%e'%1.11)  # 默认6位小数,用科学计数法
>> print('%.3e'%1.11) # 取3位小数,用科学计数法

>> print('%g'%111.1111) # 默认6位有效数字
>> print('%.7g'%1111.1111) # 取7位有效数字
>> print('%.2g'%1111.1111) # 取2位有效数字,自动转换为科学计数法
1.110000
1.1
1.110000e+00
1.110e+00
111.111
1111.111
1.1e+03
  • 浮点数输出:内置round()函数
round(number[,ndigits])
# 参数:
# number - 这是一个数字表达式
# ndigits - 表示从小数点到最后四舍五入的位数。默认值为0
# 返回值:该方法返回x的小数点摄入为n位数后的值
  • round()函数只有一个参数,不指定位数,返回一个整数,而且是最靠近的整数,类似四舍五入
  • 党制定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则
  • 但是碰到.5的情况时,如果要取舍的位数前的小数是奇数,则直接舍弃,如果是偶数则向上取舍
>> round(1.123)  # 四舍五入,不指定为0,取整
1

>> round (1.1135,3)    # 取3位小数,由于3位奇数,向下取舍
1.113

>> round(1.1225,3)    # 取3位小数,由于2为偶数,则向上入
1.123

>> round(2.675,2)   
2.67

注:round(2.675,2)的结果,结果应该是2.68的,但是它偏偏就是2.67,为什么?这根浮点数的精度有关,在机器中浮点数不一定精确表达,换算成一串1和0后可能是无限位数的,及其已经做出了截断处理,因此在机器中保存的2.675这个数字就比实际数字小一点点,导致它离2.67更近一点,所以保留两位小数就近似到了2.67

【字符串输出】

  • %s
  • %10s -- 右对齐,占位符10位(正数右对齐,负数左对齐)
  • %.2s -- 截取2位字符串
>> print('%s'%'hello world')
>> print('%20s'%'hello world')   # 右对齐,取20位,不够则补位
>> print('%-20s'%'hello world')  # 左对齐,取20位,不够则补位   
hello world
         hello world
hello world         

二、文件

【文件编码】

【ASCLL码】

  • ASCLL(American Standard Code for Information Interchange),是一种单字节的编码
  • ASCLL码使用指定的7或8位二进制数组合来表示128或256中可能的字符
  • 英语中,用128个符号编码便可以表示全部,但是用来表示其他语言,128个符号是不够。欧洲国家就规定,利用字节中闲置的最高位编入新的符号。欧洲国家编码体系,可以表示最多256个符号
  • 汉字多达10万左右,一个字节只能表示256中符号,就必须使用多个字节表达一个符号,比如,简体中文常见的编码方式就是GB2312,使用两个字节表示一个汉字。

【Unidcode】

  • Unicode码扩展自ASCLL字元集
  • Unicode是计算机科学领域里的一项业界标准,包括字符集、编码方案
  • Unicode通常用两个字节就表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为0即可
  • 跨语言、跨平台进行文本转换处理
  • 对每种语言中字符设定统一且唯一的二进制编码
  • 每个英文字母前都必然有一个二到三个字节是0,这对存出来说是极大的浪费

【UTF-8】(8-bit Unicode Transformation Format)

  • 可变长度的Unicode的实现方式
  • 使用1~4字节表示一个符号,根据不同的符号而变化字节长度

【文件类型】

  • 文本文件:以ASCLL码方式存储
  • 二进制文件:直接由比特0和1组成,没有统一字符编码

【文件操作】

  • 打开文件:建立磁盘上的文件与程序中的对象相关联
  • 文件操作:读取、写入、定位、其他(追加,计算等)
  • 关闭文件:切断文件与程序的联系,写如磁盘,并释放文件缓冲区

【文件打开】

  • Python通过解释器内置的open()函数打开一个文件,并实现该文件与一个程序变量的关联,open函数格式如下
<变量名> = open(<文件名>,<打开模式>)
  • open()函数有两个参数:文件名和打开模式
  • 文件名可以是文件的实际名字,也可以是包含完整路径的名字
  • 文件打开模式:只读,写入,追加等。这个参数是非强制的,默认文件访问模式为只读(r)。
模式 说明
r 读模式(默认,可省略),如果文件不存在,抛出异常
w 写模式,如果文件已存在,先清空原有内容;如果文件不存在,创建新文件
x 写模式,创建新文件,如果文件已存在则抛出异常
a 追加模式,不覆盖文件中原有内容
b 二进制模式(可与r、w、x或a模式组合使用)
t 文本模式(默认,可省略)
+ 读、写模式(可与其他模式组合使用)

【文件读取】

  • 根据打开方式不同可以对文件进行相应的读写操作,Python提供4个常用的文件内容读取方法
方法 含义
<file>.readall() 读入整个文件内容,返回一个字符串或字节流
<file>.read(size=-1) 从文件中读入整个内容,若给出参数,读入前size长度的字符串或字节流
<file>.readline(size=-1) 从文件中读入一行内容,如果给出参数,读入前size长度的字符串或字节流
<file>.readlines(hint=-1) 从文件中读入所有行,以每行为元素形成一个列表,如果给出参数,读入hint行

【文件写入】

  • Python提供3个与文件内容写入有关的方法
方法 含义
<file>.write(s) 将文件写入一个字符串或字节流
<file>.writelines(lines) 将一个元素为字符串的列表写入文件
<file>.seek(offset) 0:文件开头,1:当前位置,2:文件结尾

【上下文管理语句with】

  • 在实际开发中,读写文件应优先考虑使用上下文管理语句with。关键字with可以自动管理资源,无论因为什么原因跳出with块,总能保证文件被正确关闭。除了用于文件操作,with关键字还可以用于数据库连接、网络连接或类似场合。用途文件内容读写时,with语句的语法形式如下:
with open(filename,mode,encoding) as fp:

# 这里写通过文件对象fp读写文件内容的语句块

示例来了:

# 打开文件,'rb使用读、二进制模块

with open(r"E:\Python\program\teleAddressBook.txt",'rt',encoding='UTF-8') as ftele1:      # ftele1做文件别名
    with open(r"E:\Python\program\emailAddressBook.txt",'rt',encoding='UTF-8') as ftele2:
        ftele1.readline()  # 跳过第一行
        ftele2.readline()
        lines1 = ftele1.readlines()    # 从文件中读入所有行,以每行为元素形成一个列表,如果给出参数,读入hint行
        lines2 = ftele2.readlines()
        # 建立空列表用于存储姓名,电话,email
        list1_name=[]
        list1_tele=[]
        list2_name=[]
        list2_email=[]
        
        for line in lines1:  # 获取第一个文本中的姓名和电话信息
            elements=line.split()    # split()通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串
            list1_name.append(elements[0])
            list1_tele.append(elements[1])
            
        for line in lines2:   # 获取第二个文本中的姓名和邮件信息
            elements=line.split()
            list2_name.append(elements[0])
            list2_email.append(elements[1])
            
        # 生成新的数据,定义新列表
        lines=[]
        lines.append('姓名\t电话\t\t邮箱\n')   # 加制表符构建第一行格式
        
        # 遍历列表1
        for i in range(len(list1_name)):
            s=''
            if list1_name[i] in list2_name:   # 查看列表1中名字是否在列表2中
                j=list2_name.index(list1_name[i])
                s='\t'.join([list1_name[i],list1_tele[i],list2_email[i]])  # 按照姓名、电话和邮箱顺序添加
                s+='\n'
            else:
                s='\t'.join([list1_name[i],list1_tele[i]])
                s+='\n'
            lines.append(s)
            
        for i in range(len(list2_name)):
            s=''
            if list2_name[i] not in list1_name:
                s='\t'.join([list2_name[i],'     ----     ',list2_email[i]])
                s+='\n'
                lines.append(s)
        # 写入文件
        ftele3=open(r'E:\Python\program\addressbook.txt','w')
        ftele3.writelines(lines)   # 将一个元素为字符串的列表写入文件
        
# 关闭文件
ftele3.close()
ftele1.close()
ftele2.close()
print('新的通讯录已经合成')

上面代码如果运行成功,输出只有一句话,即“新的通讯录已经合成”。

需要注意的是:

第一,如果刚开始打开文件的时候我们不指定文件编码方式,我的是报错了,提示为

'gbk' codec can't decode byte 0xac in position 148: illegal multibyte sequence

所以我修改增加了语句"encoding = 'UTF-8'",使程序运行时能正常解码,

第二:如果你的程序运行文件和读入的文件在同一个文件夹下,可以不用指定绝对完整路径,但是我在这里用的是anaconda的jupyter notebook,指定绝对路径会更方便一下,即读入文件的路径,后面创建写入的文件也最好直接指定好。

第三:如下图,当我使用str()函数来为新文件空缺的的填充时,重现了错误,所以只能把这个删掉,但是下面的却使用正常,还未得到完美解决方法。

可以看到,最终新的文件已经生成,我们可以打开对比一下来看。

这一节里面的东西还是实践性比较强的内容,一起加油吧,多多练习,熟悉一下这个流程控制和里面需要注意的问题。

发布了51 篇原创文章 · 获赞 5 · 访问量 2007

猜你喜欢

转载自blog.csdn.net/MARS_098/article/details/103892145