7. 输入输出

拥有回忆 提交于 2020-02-14 14:16:24

7. 输入输出

写入文件, 输出等.
###7.1 更漂亮的输出格式
使用格式化字符串字面值, 在字符串的开始引号或者三引号之前加上一个f或者F, 在此字符串中可以在包裹的{}中使用引用的变量或字面值的Python.
Test.py:

x = "test"
y = "test1"
print(f"{x} and {y}")

运行结果:

test and test1

***Repl Closed***

字符串的str.format()方法可以提供更多的操作.
简单的传入参数.
Test.py:

x = 1
print("{}".format(x))

运行结果:

1

***Repl Closed***

7.1.1 位置传值

根据{}中数值, 按位置传入参数.从 0 开始.可以都传位置的值, 也可以都忽视位置, 但是不可以二者同时存在.
Test.py:

x = 1
y = 2
print("{1}, {0}".format(x, y))

运行结果:

2, 1

***Repl Closed***

带数字的参数可以重复使用.
Test.py:

x = 1
y = 2
print("{1}, {0}, {0}".format(x, y))

运行结果:

2, 1, 1

***Repl Closed***

7.1.2 关键字传值

使用关键字传参, 用关键字代替数字, 同样可以重复使用关键字.
Test.py:

x = 1
y = 2
print("{aaa}, {bbb}, {bbb}".format(aaa = x, bbb = y))

运行结果:

1, 2, 2

***Repl Closed***

它们还可以混合使用, 但是有一点需要注意, 位置参数必须要在关键字参数之前.
Test.py:

x = 1
y = 2
print("{0}, {1}, {2}".format("1", "2", "3"))

运行结果:

1, 2, 3

***Repl Closed***

7.1.3 元组-字典传值

使用元组和字典传值.
Test.py:

x = (1, 2, 3)
print("1:{0},2:{1},3:{2}".format(*x))

运行结果:

1:1,2:2,3:3

***Repl Closed***

Test.py:

x = {"name":"aaa", "age":"12"}
print("My name is {name} and age is {age}".format(**x))

运行结果:

My name is aaa and age is 12

***Repl Closed***

7.1.4 混合传值

所有混合使用, 但是必须记住二个原则, 位置参数一定要在关键字参数之前, 元组一定要在字典之前, 使用元组和字典之前要记得加*和**.
Test.py:

x = 1
y = "2"
z = 3, 4
k = {"name":5, "age":6}

text = "{0}, {nn}, {1}, {2}, {name}, {age}"
formatText = text.format(x, nn = y, *z, **k)
print(formatText)

运行结果:

1, 2, 3, 4, 5, 6

***Repl Closed***

至于结果怎么排序可以这样:变量(单个的如x)和元组(使用*的元组)按照从左往右的顺序排列其中元素, 不管其中是否有关键字参数, 它们排列开来的顺序就是位置下标的值, 对于字典和关键字参数只需要有key就可以获取, 不需要顺序, 只要不要二个是同名的就行.


7.1.5 []获取值

使用[] 获取元组或是列表中的元素.
Test.py:

x = (1, 2, 3)
y = [4, 5, 6]
text = "{0[0]}, {0[1]}, {0[2]}, {1[0]}, {1[1]}, {1[2]}".format(x, y)
print(text)

运行结果:

1, 2, 3, 4, 5, 6

***Repl Closed***

7.1.6 .获取值

使用 . 获取元素.
Test.py:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
p = Person("ccc", "12")
text = "My name is {0.name} and I Am {0.age}".format(p)
print(text)

运行结果:

My name is ccc and I Am 12

***Repl Closed***

类似的我们也可以获取已知类型的的属性.
Test.py:

File = open("NewFile.txt", "w")
print("{0.name}, {0.mode}".format(File))

运行结果:

NewFile.txt, w

***Repl Closed***

可以使用关键字去替换我们的对象.
Test.py:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
p = Person("ccc", "12")
text = "My name is {onePerson.name} and I Am {onePerson.age}".format(onePerson = p)
print(text)

运行结果:

My name is ccc and I Am 12

***Repl Closed***

7.1.7 转换字段

str() repr() ascii() 可以转化为字符串输出, str() 与print() 一样, 会将转义字符变化, 使用repr() 则会输出其原本的字符. ascii() 则会将不是ascii码的字符转化为 \x, \u 或 \U 编码.
Test.py:

x = "aaass你"
print(str(x))
print(ascii(x))
print(repr(x))

运行结果:

aaass你
'aaass\u4f60'
'aaass你'

***Repl Closed***

在format中使用以上三个方法.
Test.py:

x = "aaass你"
text = "{0!s}, {1!a}, {2!r}".format(x, x, x)
print(text)

运行结果:

aaass你, 'aaass\u4f60', 'aaass你'
***Repl Closed***

7.1.8 格式说明

格式说明符:
Test.py:

x = 3.1415926
text = "{0:.4f}".format(x)
print(text)

运行结果:

3.1416

***Repl Closed***

格式说明:
[[填充]对齐方式][正负号][#][0][宽度][分组选项][.精度][类型码]

7.1.8.1 填充和对齐方式

填充与对齐方式:
填充: 填充字符
对齐方式:
< : 左对齐
> : 右对齐
^ : 居中
宽度 : 限制长度.
Test.py:

x = 3.1415926
text = "{0:*>11}".format(x)
print(text)

text = "{0:*<11}".format(x)
print(text)

text = "{0:*^11}".format(x)
print(text)

运行结果:

**3.1415926
3.1415926**
*3.1415926*

***Repl Closed***
7.1.8.2 正负号格式

对于数字输出正负号.
正号 : + : 对于正数前有+
负号 : - : 对于负数前有-
空格 : : 对于正数前有空格, 以便和负数对齐
Test.py:

x = 3.1415926
text = "{0:+}".format(x)
print(text)

x = -3.1415926
text = "{0:-}".format(x)
print(text)

x = 3.1415926
text = "{0: }".format(x)
print(text)

运行结果:

+3.1415926
-3.1415926
 3.1415926

***Repl Closed***

号:

使用# + 进制 可以输出时有其进制的前缀.
Test.py:

x = 0b11
y = 0o11
z = 0x11
print("{0:#b}".format(x))
print("{0:#o}".format(y))
print("{0:#x}".format(z))

运行结果:

0b11
0o11
0x11

***Repl Closed***
7.1.8.3 最小宽度

最小宽度:
Test.py:

x = 3.1515151
print("{0:>11}".format(x))

运行结果:

  3.1515151

***Repl Closed***
7.1.8.4 分组选项

分组选项:使用逗号分割数字(以千位为单位).
Test.py:

x = 123456789
print("{0:,}".format(x))

运行结果:

123,456,789

***Repl Closed***

使用_来分割.
Test.py:

x = 123456789
print("{0:_}".format(x))

运行结果:

123_456_789

***Repl Closed***
7.1.8.5 精度

精度, 精度表示小数后面要显示几位, 需要指定类型, 不然位数会包括整数部分, 对于字符串使用此方式可以用来当作最大长度, .
Test.py:

x = 1234.12234
print("{0:.2}".format(x))
print("{0:.2f}".format(x))

x = "1234.111"
print("{0:.2}".format(x))

运行结果:

1.2e+03
1234.12
12

***Repl Closed***
7.1.8.6 类型码

类型码:

类型码
字符串 s
二进制 b
字符 c
十进制 d
八进制 o
十六进制 x
数字 n
科学记数法 e/E
浮点数 f/F
通用格式 g/G
百分号 %

Test.py:

#字符串
text = "text"
Str = "{0:s}".format(text)
print("字符串 : " + Str)

#二进制
text = 3
Str = "{0:b}".format(text)
print("二进制 : " + Str)

#保留二进制的前缀
text = 3
Str = "{0:#b}".format(text)
print("二进制 : " + Str)

#字符
text = 97
Str = "{0:c}".format(text)
print("字符 : " + Str)

#十进制
text = 11
Str = "{0:d}".format(text)
print("十进制 : " + Str)

#八进制
text = 8
Str = "{0:o}".format(text)
print("八进制 : " + Str)

#十六进制
text = 16
Str = "{0:x}".format(text)
print("十六进制 : " + Str)

#数字
text = 3
Str = "{0:n}".format(text)
print("数字 : " + Str)

#浮点数f
text = 3
Str = "{0:f}".format(text)
print("浮点数f : " + Str)

#浮点数
text = 3
Str = "{0:F}".format(text)
print("浮点数F : " + Str)

#科学记数法e
text = 3111
Str = "{0:e}".format(text)
print("科学记数法e : " + Str)

#科学记数法E
text = 3111
Str = "{0:E}".format(text)
print("科学记数法E : " + Str)

#通用格式g
text = 31111.12222
Str = "{0:g}".format(text)
print("通用格式g : " + Str)

#通用格式g
text = 311111111111111.1
Str = "{0:g}".format(text)
print("通用格式g : " + Str)

#通用格式G
text = 31111.12222
Str = "{0:g}".format(text)
print("通用格式G : " + Str)

#通用格式G
text = 311111111111111.1
Str = "{0:G}".format(text)
print("通用格式G : " + Str)

#百分号
text = 1
Str = "{0:%}".format(text)
print("百分号 : " + Str)

运行结果:

字符串 : text
二进制 : 11
二进制 : 0b11
字符 : a
十进制 : 11
八进制 : 10
十六进制 : 10
数字 : 3
浮点数f : 3.000000
浮点数F : 3.000000
科学记数法e : 3.111000e+03
科学记数法E : 3.111000E+03
通用格式g : 31111.1
通用格式g : 3.11111e+14
通用格式G : 31111.1
通用格式G : 3.11111E+14
百分号 : 100.000000%

***Repl Closed***

说明:
字符: 将数字转化为对应的Unicode 字符
通用格式:自动转换为e,f格式.

如果要输出{}:
Test.py:

print("{{}}".format(1))

运行结果:

{}

***Repl Closed***

7.1.9 手动格式化字符串

使用str.rjust(), str.ljust(), str.center(), zfill(), 进行右对齐, 左对齐, 居中, 位数不够前面补0.
Test.py:

x = "123"
print(x.rjust(10))

y = "123"
print(y.ljust(10))

z = "123"
print(z.center(10))

k = "123"
print(k.zfill(10))

运行结果:

       123
123       
   123    
0000000123
***Repl Closed***

7.1.10 使用旧的字符串格式化方式

%操作符用于格式化.
Test.py:

x = 123
y = "1234"
z = float(1.1)
print("%d, %s, %f" %(x, y, z))

运行结果:

123, 1234, 1.100000

***Repl Closed***

7.2 读写文件

使用open() 返回一个file object对象. 常用的参数有open(filename,mode). 完整的参数格式:
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
第一个参数:包含文件名的路径.
第二个参数:打开的方式.
打开方式:
读取: r
写入:w
追加:a
读写:r+
二进制: b
默认为r
file:text.txt:

成功读取到了!

读取:
Test.py:

f = open("text.txt", "r")
print(f.read())
f.close()

写入:
Test.py:

writer = open("text.txt", "w")
writer.write("写了吗?")
writer.close()

reader = open("text.txt", "r")
print(reader.read())
reader.close()

运行结果:

写了吗?

***Repl Closed***

当没有指定用什么编码格式打开文本时, python 会根据平台来决定使用的编码, 使用locale.getpreferredencoding(False) 来获取编码.
Test.py:

import locale
print(locale.getpreferredencoding(False)) 

运行结果:

UTF-8

***Repl Closed***

最好使用with来调用打开文件, 其相当于try-finally, 会自动关闭文件, 如何没有使用with记得关闭文件.
Test.py:

with open("text.txt", "r") as f:
    print(f.read())

运行结果:

写了吗?

***Repl Closed***

7.2.1 文件对象的方法

控制read的长度, read(size).
Test.py:

with open("text.txt", "r") as f:
    Str = f.read(1)
    while len(Str) > 0:
        print(Str)
        Str = f.read(1)

运行结果:

写
了
吗
?

***Repl Closed***

使用readline() 读取一行文字.
Test.py:

with open("text.txt", "r") as f:
    print(f.readline())

运行结果:

写了吗?

***Repl Closed***

读取整个文本.
Test.py:

with open("text.txt", "r") as f:
    for line in f:
        print(line, end = "")

运行结果:

写了吗?
1
2
3
34
4
5
6
***Repl Closed***

或许想将每一行文本放入列表中. 可以使用list(), readlines().
Test.py:

with open("text.txt", "r") as f:
    tmpList = list(f)
    print(tmpList)

with open("text.txt", "r") as f:
    tmpList = f.readlines()
    print(tmpList)

运行结果:

['写了吗?\n', '1\n', '2\n', '3\n', '34\n', '4\n', '5\n', '6']
['写了吗?\n', '1\n', '2\n', '3\n', '34\n', '4\n', '5\n', '6']

***Repl Closed***

使用tell() 获取文件当前读取到了哪一个字节. 使用seek(offset, whence) 可以改变读取位置的坐标.
whence = 0 : 从文件的头开始
whence = 1 : 从当前读取位置开始
whence = 2 : 从文件末尾开始
offset就是相对于whence需要移动的位置, 可以是负数.

text.txt:

写了吗?
1
2
3
4
5
6

Test.py:


with open("text.txt", "r+b") as f:
    
    #看初始位置
    print(f.tell())
    #读取一个字符(UTF-8:一个字符三个字节)
    print(f.read(3).decode("utf-8"))
    #查看读取后位置
    print(f.tell())

    #回到开始
    f.seek(-f.tell(), 1)
    print(f.tell())

    #通过seek回到第一个字节的位置
    f.seek(3, 0)
    print(f.tell())

    #输出最后一个字符
    f.seek(-3, 2)
    print(f.tell())
    print(f.read(3).decode("utf-8"))

运行结果:

0
写
3
0
3
19
5
6

***Repl Closed***∂

需要注意的是 seek() 对于不是使用二进制读取的来说有一点限制, 一般来说只能使用whence为0的时候, 还有一个例外情况——seek(0, 2)搜索到文件的尾部.
Test.py:

with open("text.txt", "r") as f:
    print(f.tell())
    f.seek(0, 2)
    print(f.tell())

运行结果:

0
22

***Repl Closed***

7.2.2 使用json保存结构化数据

可以json模块储存数据, 有类型的数据.
使用dump()函数将数据放入文件中储存, 使用load() 函数读取文件中的数据将其转化为传入时的类型和数据.
Test.py:

import json
with open("text.txt", "w") as f:
    x = [1, "1", 3]
    json.dump(x, f)

with open("text.txt", "r") as f:
    x = json.load(f)
    print(type(x[0]))
    print(type(x[1]))

运行结果:

<class 'int'>
<class 'str'>

***Repl Closed***
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!