Python笔记

变量

变量不需要赋值

指定一个值时变量对象被创建

del 删除对象引用

不可变数据的意思的如果改变数据的值,会重新分配内存空间,可以用id()查看变量地址

不可变数据:Number、String、Tuple 元组

可变数据:List、Set 集合、Dictionary 字典

string、list 和 tuple 都属于 sequence(序列)

可以用type查询,isinstance判断

>>> class A:
...     pass
... 
>>> class B(A):
...     pass
... 
>>> isinstance(A(), A)
True
>>> type(A()) == A 
True
>>> isinstance(B(), A)
True
>>> type(B()) == A
False

Number

int, float, bool, complex

float可以用科学计数法表示,2.5e2 = 2.5 x 10\(^{2}\) = 250

float也可以用八、十六进制表示

>>> 5 + 4  # 加法
9
>>> 4.3 - 2 # 减法
2.3
>>> 3 * 7  # 乘法
21
>>> 2 / 4  # 除法,得到一个浮点数
0.5
>>> 2 // 4.0 # 除法,得到一个向下取整的数,但不一定是整数类型
0.0
>>> 17 % 3 # 取余
2
>>> 2 ** 5 # 乘方
32

int(x)强制转换x,float和复数也一样


String

用单或双引号括起来,反斜杠\转义

字符串不能向单个位置赋值,即字符串不可改变,只能重新整个赋值

截取字符串:变量[头下标:尾下标],0首项开始,-1末尾开始

str = 'Runoob'

print (str)          # 输出字符串
print (str[0:-1])    # 输出第一个到倒数第二个的所有字符
print (str[0])       # 输出字符串第一个字符
print (str[2:5])     # 输出从第三个开始到第五个的字符
print (str[2:])      # 输出从第三个开始的后的所有字符
print (str * 2)      # 输出字符串两次,也可以写成 print (2 * str)
print (str + "TEST") # 连接字符串

Runoob
Runoo
R
noo
noob
RunoobRunoob
RunoobTEST

f-string:3.6后的新特性,以f开头,后边跟着字符串中变量或表达式,用{}括起来

>>> name = 'Runoob'
>>> f'Hello {name}'  # 替换变量
'Hello Runoob'
>>> f'{1+2}'         # 使用表达式
'3'

>>> w = {'name': 'Runoob', 'url': 'www.runoob.com'}
>>> f'{w["name"]}: {w["url"]}'
'Runoob: www.runoob.com'

3.8后开始支持用 = 拼接运算表达式与结果

>>> x = 1
>>> print(f'{x+1}')   # Python 3.6
2

>>> x = 1
>>> print(f'{x+1=}')   # Python 3.8
'x+1=2'

Python 的字符串内建函数要注意

序号 方法及描述
1 capitalize() 将字符串的第一个字符转换为大写
2 center(width, fillchar) 返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。
3 count(str, beg= 0,end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
4 bytes.decode(encoding="utf-8", errors="strict") Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。
5 encode(encoding='UTF-8',errors='strict') 以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是'ignore'或者'replace'
6 endswith(suffix, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False.
7 expandtabs(tabsize=8) 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。
8 find(str, beg=0, end=len(string)) 检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1
9 index(str, beg=0, end=len(string)) 跟find()方法一样,只不过如果str不在字符串中会报一个异常。
10 isalnum() 如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False
11 isalpha() 如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True, 否则返回 False
12 isdigit() 如果字符串只包含数字则返回 True 否则返回 False..
13 islower() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
14 isnumeric() 如果字符串中只包含数字字符,则返回 True,否则返回 False
15 isspace() 如果字符串中只包含空白,则返回 True,否则返回 False.
16 istitle() 如果字符串是标题化的(见 title())则返回 True,否则返回 False
17 isupper() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
18 join(seq) 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
19 len(string) 返回字符串长度
20 ljust(width[, fillchar]) 返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。
21 lower() 转换字符串中所有大写字符为小写.
22 lstrip() 截掉字符串左边的空格或指定字符。
23 maketrans() 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
24 max(str) 返回字符串 str 中最大的字母。
25 min(str) 返回字符串 str 中最小的字母。
26 replace(old, new [, max]) 把 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。
27 rfind(str, beg=0,end=len(string)) 类似于 find()函数,不过是从右边开始查找.
28 rindex( str, beg=0, end=len(string)) 类似于 index(),不过是从右边开始.
29 rjust(width,[, fillchar]) 返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串
30 rstrip() 删除字符串字符串末尾的空格.
31 split(str="", num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串
32 splitlines([keepends]) 按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。
33 startswith(substr, beg=0,end=len(string)) 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。
34 strip([chars]) 在字符串上执行 lstrip()和 rstrip()
35 swapcase() 将字符串中大写转换为小写,小写转换为大写
36 title() 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle())
37 translate(table, deletechars="") 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中
38 upper() 转换字符串中的小写字母为大写
39 zfill (width) 返回长度为 width 的字符串,原字符串右对齐,前面填充0
40 isdecimal() 检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。

List

[],里边逗号隔开,元素包括数字、字符串、列表等等,可嵌套可混搭

操作和字符串一样,但列表内的元素可变

>>> a = [1, 2, 3, 4, 5, 6]
>>> a[0] = 9
>>> a[2:5] = [13, 14, 15]
>>> a
[9, 2, 13, 14, 15, 6]
>>> a[2:5] = []   # 将对应的元素值设置为 []
>>> a
[9, 2, 6]
>>> b = a[0::2] # list[开始:结束:步长] 步长即隔多少元素取,若为负数表示逆向
>>> a
[9,6]
>>> a+b # 用+拼接
[9,6,2,9,6]

split("") 和 join(),用法和js一样

del list[n] 删除列表元素

嵌套列表:

>>>a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'
1 len(list) 列表元素个数
2 max(list) 返回列表元素最大值
3 min(list) 返回列表元素最小值
4 list(seq) 将元组转换为列表
序号 方法
1 list.append(obj) 在列表末尾添加新的对象,弱是列表、元组、字典等会嵌套显示
2 list.count(obj) 统计某个元素在列表中出现的次数
3 list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4 list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
5 list.insert(index, obj) 将对象插入列表
6 list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7 list.remove(obj) 移除列表中某个值的第一个匹配项
8 list.reverse() 反向列表中元素
9 list.sort( key=None, reverse=False) 对原列表进行排序
10 list.clear() 清空列表
11 list.copy() 浅复制列表,等于list[:]

因此列表可以方便地当做堆栈或者队列使用,但队列效率不高

堆栈:append()、pop()

队列:append()、popleft()

列表推导式:可以使用复杂表达式或嵌套函数

vec = [2, 4, 6]
[[x, x**2] for x in vec if x < 5]
# [[2, 4], [4, 6]]

del 可以从一个列表中依据索引删除元素

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]	! 清空列表
>>> a
[]

Tuple

Tuple 元组与列表类似,但它不能修改

用()括起来,两个元素以上可以不用

可以用+拼接

可以用下标索引进行截取与组合

可以用del删除整个元组,不能删除单个元素

构造空元组或一个元素的元组比较特殊:

tup1 = ()    # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号
1 len(tuple) 计算元组元素个数。 >>> tuple1 = ('Google', 'Runoob', 'Taobao') >>> len(tuple1) 3 >>>
2 max(tuple) 返回元组中元素最大值。 >>> tuple2 = ('5', '4', '8') >>> max(tuple2) '8' >>>
3 min(tuple) 返回元组中元素最小值。 >>> tuple2 = ('5', '4', '8') >>> min(tuple2) '4' >>>
4 tuple(iterable) 将可迭代系列转换为元组。

Set

是一个无序不重复元素的集

进行成员关系测试和删除重复元素

可以使用{...}或set()创建

创建空集合必须用set(),因为{}用来创建空字典

sites = {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}
print(sites)   # 输出集合,重复的元素被自动去掉
# {'Zhihu', 'Baidu', 'Taobao', 'Runoob', 'Google', 'Facebook'}

# 成员测试
if 'Runoob' in sites :
    print('Runoob 在集合中')
else :
    print('Runoob 不在集合中')
# Runoob 在集合中

# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')

print(a)
# {'b', 'c', 'a', 'r', 'd'}
print(a - b)     # a 和 b 的差集
# {'r', 'b', 'd'}
print(a | b)     # a 和 b 的并集
# {'b', 'c', 'a', 'z', 'm', 'r', 'l', 'd'}
print(a & b)     # a 和 b 的交集
# {'c', 'a'}
print(a ^ b)     # a 和 b 中不同时存在的元素,即并集与交集的差集
# {'z', 'b', 'm', 'r', 'l', 'd'}

set.add()添加元素,不会重复

set.update()添加元素,可以是列表、元组、字典等,但只添加里面的元素,不是直接添加列表

set.remove()移除元素,不存在会报错

set.discard()移除元素,不存在也不会报错

set.pop()会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除

len计算元素个数

clear清空集合

方法 描述
add() 为集合添加元素
clear() 移除集合中的所有元素
copy() 拷贝一个集合
difference() 返回多个集合的差集
difference_update() 移除集合中的元素,该元素在指定的集合也存在。
discard() 删除集合中指定的元素
intersection() 返回集合的交集
intersection_update() 返回集合的交集。
isdisjoint() 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
issubset() 判断指定集合是否为该方法参数集合的子集。
issuperset() 判断该方法的参数集合是否为指定集合的子集
pop() 随机移除元素
remove() 移除指定元素
symmetric_difference() 返回两个集合中不重复的元素集合。
symmetric_difference_update() 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。
union() 返回两个集合的并集
update() 给集合添加元素

Dictionary

用{}括起来,成员都是键值对,key必须使用不可变类型,必须唯一,如果输入相同的键,后面的值会覆盖前面的

dic = {}
dic['one'] = "1"
dic[2]     = "2"

dic = {'name': 'runoob',98.5:1, 2: 'www.runoob.com'}

print (dic['name'])       # 输出键为 'name' 的值
print (dic[2])           # 输出键为 2 的值
print (dic)          # 输出完整的字典
print (dic.keys())   # 输出所有键
print (dic.values()) # 输出所有值

del dic['Name'] # 删除键 'Name'
dic.clear()     # 清空字典
del dic         # 删除字典

# dict() 直接从键值对元组构建字典
dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
# {'sape': 4139, 'jack': 4098, 'guido': 4127}

# dict() 直接从关键字为字符串的元组构建字典
dict(sape=4139, guido=4127, jack=4098)
# {'sape': 4139, 'jack': 4098, 'guido': 4127}

# 字典推导
{x: x**2 for x in (2, 4, 6)}
# {2: 4, 4: 16, 6: 36}

序号 函数及描述 实例
1 len(dict) 计算字典元素个数,即键的总数。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} >>> len(dict) 3
2 str(dict) 输出字典,以可打印的字符串表示。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} >>> str(dict) "{'Name': 'Runoob', 'Class': 'First', 'Age': 7}"
3 type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} >>> type(dict) <class 'dict'>

image-20210302164356675


注释

单行注释#

多行注释用```或"""括起来


运算符

:= 海象运算符,可以在表达式内部为变量赋值,py3.8版本新增


image-20210302165238386

左移实际上是乘2\(^{n}\),右移是除以2\(^{n}\)


逻辑运算符 and、or、not


成员运算符 in、not in


身份运算符 is、is not

is判断两个标识符是不是引用自同一个对象,或者说比较两个对象是否在同一内存

is与区别:is判断对象,判断变量的值

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True

出于对性能的考虑,Python内部做了很多的优化工作,对于整数对象,Python把一些频繁使用的整数对象缓存起来,保存到一个叫small_ints的链表中,在Python的整个生命周期内,任何需要引用这些整数对象的地方,都不再重新创建新的对象,而是直接引用缓存中的对象。Python把这些可能频繁使用的整数对象规定在范围[-5, 256]之间的小对象放在small_ints中,但凡是需要用些小整数时,就从这里面取,不再去临时创建新的对象。因为257不再小整数范围内,因此尽管a和b的值是一样,但是他们在Python内部却是以两个独立的对象存在的,各自为政,互不干涉。

a = 2
b = 2
a is b		# true

a = 257
b = 257
a is b		# false,原因如上

但也有例外情况。

Python程序里,代码块作为程序的一个最小基本单位来执行。一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。Python出于对性能的考虑,但凡是不可变对象,在同一个代码块中的对象,只要值相同,就不会重复创建,而是直接引用已经存在的对象。

下面这段代码由两个代码块构成,c = 257作为一个代码块,函数foo作为另外一个代码块。所以 a is b就理所当然的返回True了,而c和a不在同一个代码块中,因此在Python内部创建了两个值都是257的对象。

c = 257
def foo():
	a = 257
	b = 257
	printf a is b	#True
	printf a is c	#False

结论:

  1. 小整数对象[-5,256]是全局解释器范围内被重复使用,永远不会被GC回收。
  2. 同一个代码块中的不可变对象,只要值是相等的,就不会重复创建新的对象。
  3. 字符串中单个20以内他们的内存地址一样,单个21以上,内存地址不一样
  4. 在一个py文件中,只要内容一样,内存就一样

image-20210302170702926


end可以将结果输出到同一行,并在其中添加字符

a, b = 0, 1
while b < 1000:
    print(b, end=',')
    a, b = b, a+b

条件控制:if

if ...:
	...
elif ...:
	...
else:
	...

用缩进代替其他语言里的花括号

没有switch-case

可嵌套,注意缩进


循环

无限循环在服务器上客户端的实时请求非常有用。

while-else中,else的内容在条件为flase时输出,但被break时不会输出

for-in还可用来循环字符串,每个字符会作为单独的字符串

可以用1、0代替true、false

有break和continue,需要缩进

pass空语句,用来保持程序结构完整

count = 0
while count < 5:
   print (count, " 小于 5")
   count = count + 1
else:
   print (count, " 大于或等于 5")


sites = ["Baidu", "Google","Runoob","Taobao"]
for site in sites:
    if site == "Runoob":
        print("菜鸟教程!")
        break
    print("循环数据 " + site)
else:
    print("没有循环数据!")
print("完成循环!")

"""
循环数据 Baidu
循环数据 Google
菜鸟教程!
完成循环!
"""

for i in range(5):	#range(结束)、range(开始,结束,步长)生成数字序列
	print(i)

# 可以结合range()和len()函数以遍历一个序列的索引
a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
for i in range(len(a)):
	print(i, a[i])
""""
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
"""

# 遍历字典,item()可以得到关键字和值
for key, value in dic.items():
	print(key, value)

# 遍历序列,enumerate()可以得到索引位置和对应的值
for i, v in enumerate(['tic', 'tac', 'toe']):
	print(i, v)

# zip()可以同时遍历多个序列
for a, b in zip(a, b):
	print('What is your {0}?  It is {1}.'.format(a, b))

# reverse()反向序列
for i in reversed(range(10)):
    
# sort()对序列排序
for f in sorted(set(dic)):

迭代器

访问集合元素的方式,可以记住遍历的位置

适用于字符串、列表、元组

两个方法:iter和next

list = [1,2,3,4]
it = iter(list)
print(next(it))

迭代器可以用next获取下一个元素,也可以用for-in循环


把一个类设为一个迭代器,需要实现两个方法:

__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。

__next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers()
myiter = iter(myclass)
 
print(next(myiter))
print(next(myiter))
print(next(myiter))

StopIteration 异常用于标识迭代的完成

def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration

生成器(generator):使用了 yield 的函数被称为生成器,是一个返回迭代函数的函数,也可以说是特殊的迭代器。

生成器每次运行到 yield 时,会暂停并保存当前所有的运行信息,返回 yield 的值,下一次执行 next 时从暂停的位置继续。

def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1

函数

def max(a, b):
    if a > b:
        return a
    else:
        return b

函数传递:

  1. 不可变类型类似于c++的值传递,如果想修改会重新生成对象,不影响外部变量
  2. 可变类型类似于引用传递,如果想修改,外部的变量也会受影响

关键字参数允许函数调用时参数的顺序与声明时不一致, Python 解释器能够用参数名匹配参数值。

函数声明时可以设定默认值。

不定长参数:*变量名,默认导入元组

**变量名,以字典形式导入

def printinfo( arg1, **vardict ):
   print (arg1)
   print (vardict)

printinfo(1, a=2,b=3)

"""
1
{'a': 2, 'b': 3}
"""

lambda 匿名函数,可封装简单逻辑

sum = lambda arg1, arg2: arg1 + arg2

print ("相加后的值为 : ", sum( 10, 20 ))

模块

就是一个py文件,在顶部使用import 文件名导入

同名模块只会引入最先搜索到的那个

可以通过修改sys文件里的path来引入不在默认搜索路径的模块

可以给模块函数赋予一个本地的名称:fib = fino.fib

from 模块名 import 函数名/变量名:可以导入模块里的多个特定函数或变量,用逗号隔开,这样就把import后的名称放在了当前的字符表内,可直接使用。也可以用*代表导入全部项目,单一下划线开头的名称不在此列,但不推荐使用

模块除了函数,还包括可执行代码,在第一次导入时执行,里边的变量只在该模块内部作为全局变量,不会影响其它模块。

每个模块都有__ name __ 属性,当其值是' __ main __ '时,表明该模块自身在运行,否则是被引入。因此可以用它来保证程序块被其它函数引入时不会执行

# Filename: using_name.py
if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
   
$ python using_name.py
程序自身在运行

$ python
>>> import using_name
我来自另一模块

dir()可以列出模块内定义的所有名称,以字符串的形式


是一种管理模块的形式,包.模块

不用担心不同的包之间,模块重名的问题。

目录里包含 __ init __ .py 才被认为是一个包,可以用来初始化

windows平台不区分大小写,因此导入包要精确

导入方式与模块一样,但对于*,如果 __ init __ .py 里存在 __ all __ 列表变量,那么会导入这个列表内的所有模块,否则不会导入任何模块。注意all的更新

推荐使用from-import方式导入

可以用相对路径导入包


输入和输出

输出

s = 'hello'
print(s)
print(str(s))
print(repr(s))
print('{}网址: "{}!"'.format('url', 'www.runoob.com'))

"""
hello
hello
'hello'
url: "www.runoob.com!"
"""

format里也可以指定关键字,可以用:加格式标志符指定小数点,加d指定区域宽度


输入

input() 读入一行文本

open(file, mode) 返回一个file对象,mode是打开模式

open属性其实还有更多,这里就不展开了

模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
# 打开一个文件
f = open("/tmp/foo.txt", "w")

# write返回写入的字符数,写入的内容必须是字符串,可以先进行字符串转化
f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )

# read(size)从文件中读取size大小的数据,返回字符串,size可省略,会返回全部内容
str = f.read()

# readline(size)返回指定长度,按行分割,size可省略
str = f.readline()

# 另一种按行输出
for line in f:
   print(line, end='')
   
# tell()返回文件对象当前所处的位置

# seek(offset, from_what)改变文件当前位置
# seek(x,0) :从起始位置即文件首行首字符开始移动 x 个字符
# seek(x,1) :表示从当前位置往后移动x个字符
# seek(-x,2):表示从文件的结尾往前移动x个字符

# 关闭打开的文件
f.close()


# 可以用with处理单个文件,with保证会关闭文件
with open('/tmp/foo.txt', 'r') as f:
   read_data = f.read()

pickle,序列化和反序列化

通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

import pickle

# 使用pickle模块将数据对象保存到文件
data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()
import pprint, pickle

#使用pickle模块从文件中重构python对象
pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

data2 = pickle.load(pkl_file)
pprint.pprint(data2)

pkl_file.close()

OS 文件/目录方法

也先不展开了...


异常

异常处理

用try-except语句处理

一个try可以包含多个except,但只会执行一个except

一个except可以对应多个try,这些try括起来成为一个元组

最后一个except可忽略异常名字,它也会抛出异常

else必须放在所有except之后,如果try没有触发异常,会执行else

finally无论是否发生异常都会执行,如果一个异常在try中被抛出,又没有except截住,那么它会在finally执行之后才继续被抛出

while True:
    try:
        x = int(input("请输入一个数字: "))
        break
    except ValueError:
        print("您输入的不是数字,请再次尝试输入!")
    except:
    else:

抛出异常

raise可以放在except子句里,返回当前异常

也可以使用raise Exception(描述)


用户自定义异常

可以创建自己的异常类,继承自Exception

>>> class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
   
>>> try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:', e.value)
   
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'

也可先创建继承了Exception的基础类,再创建继承了基础类的子类

posted @ 2021-03-03 15:45  一语子  阅读(90)  评论(0)    收藏  举报