跟着官档学python 007- 格式化输出

7.1. 格式化输出

输出值的方法:表达式语句、print()函数、使用文件对象的write()方法;标准输出文件可以引用 sys.stdout。

通常你会希望更好地控制输出的格式而不是简单地打印用空格分隔的值。有两种方式格式化你的输出:第一种方式是自己做所有字符串处理;使用字符串切片和串联操作,你可以创建任何你可以想象的布局。字符串类型有一些方法,用于执行将字符串填充到指定列宽度的有用操作;这些稍后将讨论。

第二种方法是使用 str.format() 方法。

string模块包含一个Template类,提供另外一种向字符串代入值的方法。

如何将值转换为字符串?幸运的是,python已经有方法把任何值转换成字符串:使用repr() 或 str() 方法。

str()函数的用意在于返回人类可读的表现形式,而repr()的用意在于生成解释器可读的表现形式(如果没有等价的语法将会引发SyntaxError异常)。特别地,字符串有两个不同的表示。

例如:

###################有时候是一样的##########################
>>>s = 'Hello World.'
>>>str(s)
'Hello World.'
>>>repr(s)
"'Hello World.'"
>>>str(0.1)
'0.1'
>>>repr(0.1)
'0.1'
>>>x=10*3.25
>>>y=200*200
>>>s='The value of x is '+repr(x)+' ,and y is '+repr(y)+'...'
>>>print(s)
The value of x is 32.5 ,and y is 40000...
#####################有时候结果不一样########################
>>>hello='hello,world\n'
>>>hellos=repr(hello)
>>>print(hellos)
'hello,world\n'
>>>hls=str(hello)
>>>print(hls)
hello,world

#############The argument to repr() may be any Python object:###############
>>>repr((x,y,('spam','eggs')))
"(32.5, 40000, ('spam', 'eggs'))"

这里有两种方法来写一个平方值和立方值的表:

>>>for x in range(1,11):
...    print(repr(x).rjust(2),repr(x*x).rjust(3),end='')
...    print(repr(x*x*x).rjust(4))
...
 1   1   1
 2   4   8
 3   9  27
 4  16  64
 5  25 125
 6  36 216
 7  49 343
 8  64 512
 9  81 729
10 1001000
>>>for x in range(1,11):
...    print('{0:2d} {1:3d} {2:4d}'.format(x,x*x,x*x*x))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

(注意在第一个示例中,每列之间的一个空格由print()自动添加:它总会在它的参数之间添加空格。)

上面的例子演示了字符串对象的str.rjust()方法,它通过在左侧填充空格使字符串在给定宽度的列右对齐。语法为:str.rjust(宽度, 要填充的字符]),类似的方法还有str.ljust()和str.center()。这些方法不会输出任何内容,它们只返回新的字符串。如果输入的字符串太长,字符串不会被截断,会完整输出。这将会使列不对齐,但是通常这比截断好,截断会导致不知道原值(如果你真的想要截断,可以加上一个切片操作,例如x.ljust(n)[:n]。)

另外一种方法str.zfill(),它向数值字符串左侧填充零。该函数可以正确识别正负号:

>>>'12'.zfill(5)
'00012'
>>>'-3.14'.zfill(7)
'-003.14'
>>>'3.14159265359'
'3.14159265359'
>>>'3.14159265359'.zfill(5)
'3.14159265359'

str.format()方法的基本用法如下所示:

>>>print('We are the {} who say "{}!"'.format('knights','Ni'))
We are the knights who say "Ni!"

字符串内部的花括号和字符(叫做格式字段)将被传递给str.format()方法的对象所替换。花括号中的数字可以用来引用传递给str.format()方法的对象的位置。

>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam

如果str.format()方法中用到关键字参数,那么它们的值通过参数的名称引用。

>>> print('This {food} is {adjective}.'.format(
...       food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

位置参数和关键字参数可以随意组合:

>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
                                                       other='Georg'))
The story of Bill, Manfred, and Georg.

‘!a’(运用ascii())、’!s’(运用str())和’!r’(运用repr())可以用来在格式化之前转换相应的值:

>>> contents = 'eels'
>>> print('My hovercraft is full of {}.'.format(contents))
My hovercraft is full of eels.
>>> print('My hovercraft is full of {!r}.'.format(contents))
My hovercraft is full of 'eels'.

字段名后允许可选的’:'和格式指令。这允许更好地控制值是何种格式。下面的例子将 Pi 转为三位精度。

>>> import math
>>> print('The value of PI is approximately {0:.3f}.'.format(math.pi))
The value of PI is approximately 3.142.

':'后面紧跟一个整数可以限定该字段的最小宽度。这在美化表格时很有用。

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, phone))
...
Jack       ==>       4098
Dcab       ==>       7678
Sjoerd     ==>       4127

如果你有一个不想分裂的非常长的格式字符串,如果你通过名称而不是位置来格式化这个变量会更好一点。有个简单的方法,可以传入一个字典,然后使用’[]'访问。

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
...       'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

这也可以用 ‘**’ 标志将这个字典以关键字参数的方式传入。

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

这种方式与内置函数vars()组合起来将更加有用,该函数返回一个包含所有局部变量的字典。

7.1.1. 旧式的字符串格式化

% 也可以用来字符串格式化。它将左边类似sprintf()-风格的参数应用到右边的参数,然后返回这种格式化操作生成的字符串。例如:

>>> import math
>>> print('The value of PI is approximately %5.3f.' % math.pi)
The value of PI is approximately 3.142.

7.2. 读写文件

open()返回一个文件对象,最常见的用法带有两个参数:open(filename, mode)。

C:\Users\Administrator.USER-20160830MU>cd  C:/

C:\>python
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('workfile','w')

workfile
参数1是含有文件名的字符串。参数2也是字符串,以几个字符说明该文件的使用方式。
mode参数是可选的;如果省略,则默认为’r’。

  • 'r’表示文件只读;
  • w表示文件只进行写入(已存在的同名文件将被删掉);
  • 'a’表示打开文件进行追加;写入到文件中的任何数据将自动添加到末尾。
  • 'r+'表示打开文件进行读取和写入。

通常,文件以文本模式打开,它表示你从文件读取以及向文件写入的字符串是经过特定的编码的。如果没有指定编码,则默认值取操作系统的编码。在mode后面附加’b’将以二进制模式打开文件:现在数据以字节对象的形式读取和写入。这个模式应该用于所有不包含文本的文件。

在文本模式中,读取的默认行为是将平台相关的换行(Unix上的\n、Windows上的\r\n)仅仅转换为\n。当在文本模式中写入时,默认的行为是将\n转换为平台相关的换行。这种对文件数据的修改对文本文件没有问题,但会损坏JPEG或EXE这样的二进制文件中的数据。使用二进制模式读写此类文件时要特别小心。

7.2.1. 文件对象的方法

本节中的示例已经新建文件对象mfile.txt,并写入了文件内容This is the entire file.This is the entire file.This is the entire file.。

要读取文件内容,可以调用f.read(size) ,该方法读取若干数量的数据并以字符串(在文本模式中)或字节对象(在二进制模式中)形式返回它。size 是可选的数值参数。当 size被省略或为负数时,将会读取并返回整个文件;若文件大小是你机器内存的两倍,那是你自己的问题。否则,至多读取和返回 size 大小的字节数据。如果到了文件末尾,f.read() 会返回一个空字符串("")。

>>> m=open(r'c:/mfile.txt','r+')
>>> m.read()
'This is the entire file.This is the entire file.This is the entire file.'
>>> m.read()
''
#####python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。
#####想要重新从头开始读的话用m.seek(0),必须指定参数(位置)
>>> m.seek()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: seek() takes at least 1 argument (0 given)
>>> m.seek(0)
0
>>> m.read()
'This is the entire file.This is the entire file.This is the entire file.'
>>> m.seek(0)
0
#######只读15个字符
>>> m.read(15)
'This is the ent'
>>>
#######查看当前光标位置
>>> m.tell()
15
####再读第16-24个字符
>>> m.read(24)
'ire file.This is the ent'

f.readline()从文件读取一行数据;字符串结尾会带有一个换行符 (\n) ,只有当文件最后一行没有以换行符结尾时才会省略。这样返回值就不会有混淆;如果f.readline()返回一个空字符串,那就表示已经达到文件的末尾,而如果返回一个只包含一个换行符的字符串’\n’,则表示遇到一个空行。

####定义ffile.txt,并读取
>>> f=open(r'c:/ffile.txt','r+')
>>> f.readline()
'This is the first line.\n'
>>> f.readline()
'This is the second line.\n'
>>> f.readline()
'This is the last line.'

你可以循环遍历文件对象来读取文件中的每一行。这让内存高效,快速,并简化代码:

>>> for line in f:
...     print(line,end='')
...
>>>
>>> f.seek(0)
0
>>> for line in f:
...     print(line,end='')
...
This is the first line.
This is the second line.
This is the last line.>>>

如果你想要读取文件列表中所有行的数据,你也可以使用 list(f) 或 f.readlines()。

>>> f.read()
'This is the first line.\nThis is the second line.\nThis is the last line.'
>>> list(f)
[]
>>> f.seek(0)
0
>>> list(f)
['This is the first line.\n', 'This is the second line.\n', 'This is the last li
ne.']
>>> f.seek(0)
0
>>> f.readlines()
['This is the first line.\n', 'This is the second line.\n', 'This is the last li
ne.']

f.write(string) 将 字符串 的内容写入到该文件,返回写入的字符数。

>>> f.write('This is a test\n')
15
>>> f.readlines()
[]
>>> f.seek(0)
0
>>> f.readlines()
['This is the first line.\n', 'This is the second line.\n', 'This is the last li
ne.This is a test\n']

其他类型的对象,在写入之前则需要转换成 字符串 (在文本模式下) 或 字节对象 (以二进制模式)

>>> value=('the answer',42)
>>> s=str(value)
>>> f.write(s)
18
>>> f.seek(0)
0
>>> f.readlines()
['This is the first line.\n', 'This is the second line.\n', 'This is the last li
ne.This is a test\n', "('the answer', 42)"]

f.tell()返回一个整数,代表文件对象在文件中的当前的位置,在二进制模式中该数值表示自文件开头到指针处的字节数,在文本模式中则是不准确的。

若要更改该文件对象的位置,可以使用f.seek(offset, from_what)。位置由参考点加上offset 计算得来;参考点的选择则来自于from_what参数。当from_what的值为0,1,2 时,分别使用文件开头、当前文件位置和文件结尾作为参考点。from_what 可以省略,默认值为 0,表示以文件的开始作为参考点。

>>> f=open('workfile','rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)
5
>>> f.read(1)
b'5'
>>> f.seek(1)
1 
####这个没懂。。。
>>> f.seek(-3,2)
69

在文本文件中(没有以b模式打开的文件),只允许从文件的开始查找(有个例外是查找到文件的末尾seek(0, 2)),而且offset只有是从f.tell()返回的值或者是0才是合法的。其它任何偏移 值都会产生未定义的行为。

使用完一个文件后,调用f.close()可以关闭它并释放其占用的所有系统资源。调用f.close()后,再尝试使用该文件对象将自动失败。

>>> f.close()
>>> m.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: read of closed file

处理文件对象时使用with关键字是很好的做法。这样做的好处在于文件用完后会自动关闭,即使过程中发生异常也没关系。它还比编写一个等同的try-finally语句要短很多:

>>> with open('workfile','r') as f:
...     read_data=f.read()
...
>>> f.closed
True

文件对象还有一些不太常用的方法,例如isatty()和truncate();有关文件对象的完整指南,请参阅库参考手册。

7.2.2. 使用json存储结构化数据

从文件中读写字符串很容易。数值就要多费点儿周折,因为read ()方法只会返回字符串,应将其传入int()这样的函数,就可以将’123’这样的字符串转换为对应的数值123。当你想要保存更为复杂的数据类型,例如嵌套的列表和字典,手工解析和序列化它们将变得更复杂。

好在用户不是非得自己编写和调试保存复杂数据类型的代码,Python 允许你使用常用的数据交换格式JSON(JavaScript Object Notation)。标准模块json可以接受 Python 数据结构,并将它们转换为字符串表示形式;此过程称为序列化。从字符串表示形式重新构建数据结构称为反序列化。在序列化和反序列化之间,表示对象的字符串可能已经存储在文件或数据中,或者通过网络连接发送到一些远程机器。

如果你有一个对象x,你可以用简单的一行代码查看其JSON字符串表示形式:

>>> import json
>>> json.dumps([1,'simple','list'])
'[1, "simple", "list"]'

dumps()函数的另外一个变体dump(),直接将对象序列化到一个文本文件。所以如果f是为写入而打开的一个文件对象,我们可以这样做:

>>> x=[1,'simple','list']
>>> f=open('workfile','r+')
>>> json.dump(x,f)

为了重新解码对象,如果f是为读取而打开的文本文件对象 :

x = json.load(f)

这种简单的序列化技术可以处理列表和字典,但序列化任意类实
例为 JSON 需要一点额外的努力

请参阅pickle - pickle模块
与JSON不同,pickle是一个协议,它允许任意复杂的Python对象的序列化。因此,它只能用于 Python 而不能用来与其他语言编写的应用程序进行通信。默认情况下它也是不安全的:如果数据由熟练的攻击者精心设计, 反序列化来自一个不受信任源的 pickle 数据可以执行任意代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中,我们可以使用百分号%f来格式化输出浮点数。百分号%f后面可以跟着一个小数点和一个数字,表示保留的小数位数。例如,如果我们想要保留2位小数,可以使用"%.2f"的格式。 示例代码如下: ``` num = 3.1415926 print("保留两位小数:%0.2f" % num) ``` 输出结果为: ``` 保留两位小数:3.14 ``` 另外,我们也可以使用format函数来格式化输出浮点数。通过在大括号中使用冒号来指定格式,其中冒号后面的部分表示浮点数的格式。 示例代码如下: ``` num = 3.1415926 print("保留两位小数:{:.2f}".format(num)) ``` 输出结果为: ``` 保留两位小数:3.14 ``` 最后,我们还可以使用f-string来格式化输出浮点数。在f-string中,可以直接在大括号中使用冒号来指定格式。 示例代码如下: ``` num = 3.1415926 print(f"保留两位小数:{num:.2f}") ``` 输出结果为: ``` 保留两位小数:3.14 ``` 综上所述,我们可以使用百分号%f、format函数和f-string来实现Python中的浮点数格式化输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [技巧 | 5000字超全解析Python三种格式化输出方式【% / format / f-string】](https://blog.csdn.net/weixin_42152811/article/details/115264013)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [从零开始学Python编程之格式化输出](https://blog.csdn.net/m0_46388260/article/details/129568763)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值