快速过一下Python3的语法知识,菜鸟教程 https://www.runoob.com/python3/
建议使用pyenv来管理python环境版本,问chatGPT就好可以轻松使用pyenv.
Python环境变量
下面几个重要的环境变量,它应用于Python:
变量名 | 描述 |
---|---|
PYTHONPATH | PYTHONPATH是Python搜索路径,默认我们import的模块都会从PYTHONPATH里面寻找。 |
PYTHONSTARTUP | Python启动后,先寻找PYTHONSTARTUP环境变量,然后执行此变量指定的文件中的代码。 |
PYTHONCASEOK | 加入PYTHONCASEOK的环境变量, 就会使python导入模块的时候不区分大小写. |
PYTHONHOME | 另一种模块搜索路径。它通常内嵌于的PYTHONSTARTUP或PYTHONPATH目录中,使得两个模块库更容易切换。 |
默认情况下,Python3 源码以UTF-8编码,所有字符串都是unicode字符串。
合法标识符:
= 25
age = "Alice"
user_name = 100
_total = 1024
MAX_SIZE
calculate_area()
StudentInfo __private_var
非法标识符:
2nd_place = "silver" # 错误:以数字开头
-name = "Bob" # 错误:包含连字符
userclass = "Math" # 错误:使用关键字
= 9.99 # 错误:包含特殊字符
$price for = "loop" # 错误:使用关键字
Python 3 允许使用 Unicode 字符作为标识符,可以用中文作为变量名,非 ASCII 标识符也是允许的了。
= "张三" # 合法
姓名 = 3.14159 # 合法 π
测试标识符是否合法:
def is_valid_identifier(name):
try:
exec(f"{name} = None")
return True
except:
return False
print(is_valid_identifier("2var")) # False
print(is_valid_identifier("var2")) # True
保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
>>> import keyword
>>> keyword.kwlist
'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
[>>>
Python中单行注释以#开头
#!/usr/bin/python3
# 第一个注释
print ("Hello, Python!") # 第二个注释
多行注释可以用#好,还有 '''
和 """
#!/usr/bin/python3
# 第一个注释
# 第二个注释
'''
第三注释
第四注释
'''
"""
第五注释
第六注释
"""
print ("Hello, Python!")
python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {} 。
缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。实例如下:
if True:
print ("True")
else:
print ("False")
以下代码最后一行语句缩进数的空格数不一致,会导致运行错误:
if True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误
以上程序由于缩进不一致,执行后会出现类似以下错误:
"test.py", line 6
File print ("False") # 缩进不一致,会导致运行错误
^
IndentationError: unindent does not match any outer indentation level
Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 来实现多行语句,例如:
= item_one + \
total + \
item_two item_three
实例
= 1
item_one = 2
item_two = 3
item_three = item_one + \
total + \
item_two
item_threeprint(total) # 输出为 6
在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 ,例如:
= ['item_one', 'item_two', 'item_three',
total 'item_four', 'item_five']
python中数字有四种类型:整数、布尔型、浮点数和复数。
str[start:end]
,其中
start(包含)是切片开始的索引,end(不包含)是切片结束的索引。str[start:end:step]
= '字符串'
word = "这是一个句子。"
sentence = """这是一个段落,
paragraph 可以由多行组成"""
#!/usr/bin/python3
str='123456789'
print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第六个的字符(不包含)
print(str[2:]) # 输出从第三个开始后的所有字符
print(str[1:5:2]) # 输出从第二个开始到第五个且每隔一个的字符(步长为2)
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串
print('------------------------------')
print('hello\nrunoob') # 使用反斜杠(\)+n转义特殊字符
print(r'hello\nrunoob') # 在字符串前面添加一个 r,表示原始字符串,不会发生转义
这里的r指raw,即raw string,会自动将反斜杠转义,例如:
>>> print('\n') # 输出空行
>>> print(r'\n') # 输出 \n
\n>>>
以上实例输出结果
123456789
12345678
1
345
3456789
24
123456789123456789
123456789你好
------------------------------
hello
runoob
hello\nrunoob
函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
记住:空行也是程序代码的一部分。
执行下面的程序在按回车键就会等待用户输入
#!/usr/bin/python3
input("\n\n按下 enter 键后退出。")
以上代码中 ,\n\n
在结果输出前会输出两个新的空行。一旦用户按下 enter
键时,程序将退出。
Python 可以在同一行中使用多条语句,语句之间使用分号 ; 分割,以下是一个简单的实例:
#!/usr/bin/python3
import sys; x = 'runoob'; sys.stdout.write(x + '\n')
使用脚本执行以上代码,输出结果为:
runoob
使用交互式命令执行,输出结果为:
>>> import sys; x = 'runoob'; sys.stdout.write(x + '\n')
runoob7
此处的 7 表示字符数,runoob 有 6 个字符,表示一个字符,加起来 7 个字符。
>>> import sys
>>> sys.stdout.write(" hi ") # hi 前后各有 1 个空格
4 hi
缩进相同的一组语句构成一个代码块,我们称之代码组。
像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。
我们将首行及后面的代码组称为一个子句(clause)。
如下面实例:
if expression :
suiteelif expression :
suite else :
suite
print默认输出是换行的,如果要实现不换行需要在变量末尾加上 end=““;
#!/usr/bin/python3
="a"
x="b"
y# 换行输出
print( x )
print( y )
print('---------')
# 不换行输出
print( x, end=" " )
print( y, end=" " )
print()
以上实例执行结果为:
a
b---------
a b
在 python 用 import 或者 from…import 来导入相应的模块。
import somemodule
from somemodule import somefunction
from somemodule import firstfunc, secondfunc, thirdfunc
from somemodule import *
导入sys模块:
import sys
print('================Python import mode==========================')
print ('命令行参数为:')
for i in sys.argv:
print (i)
print ('\n python 路径为',sys.path)
导入sys模块的argv.path成员
from sys import argv,path # 导入特定的成员
print('================python from import===================================')
print('path:',path) # 因为已经导入path成员,所以此处引用时不需要加sys.path
很多程序可以执行一些操作来查看一些基本信息,Python可以使用-h参数查看各参数帮助信息:
gaowanlu@DESKTOP-QDLGRDB:/mnt/c/Users/gaowanlu$ python -h
usage: /mnt/e/pyenv/pyenv-2.5.5/pyenv-2.5.5/versions/3.9.22/bin/python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Options and arguments (and corresponding environment variables):
-b : issue warnings about str(bytes_instance), str(bytearray_instance)
and comparing bytes/bytearray with str. (-bb: issue errors)
-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x
-c cmd : program passed in as string (terminates option list)
-d : turn on parser debugging output (for experts only, only works on
debug builds); also PYTHONDEBUG=x
-E : ignore PYTHON* environment variables (such as PYTHONPATH)
-h : print this help message and exit (also --help)
-i : inspect interactively after running script; forces a prompt even
if stdin does not appear to be a terminal; also PYTHONINSPECT=x
......
#!/usr/bin/python3
= 100 # 整型变量
counter = 1000.0 # 浮点型变量
miles = "runoob" # 字符串
name
print (counter)
print (miles)
print (name)
= b = c = 1
a = 1, 2, "runoob" a, b, c
# 变量定义
= 10 # 整数
x = 3.14 # 浮点数
y = "Alice" # 字符串
name = True # 布尔值
is_active
# 多变量赋值
= 1, 2, "three"
a, b, c
# 查看数据类型
print(type(x)) # <class 'int'>
print(type(y)) # <class 'float'>
print(type(name)) # <class 'str'>
print(type(is_active)) # <class 'bool'>
不可变数据
:Number(数字)、String(字符串)、Tuple(元组)。
可变数据
:List(列表)、Dictionary(字典)、Set(集合)。
此外还有一些高级的数据类型,如:字节数组类型(bytes)。
Python3 支持 int、float、bool、complex(复数)。
在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
像大多数语言一样,数值类型的赋值和计算都是很直观的。
内置的 type() 函数可以用来查询变量所指的对象类型。
>>> a, b, c, d = 20, 5.5, True, 4+3j
>>> print(type(a), type(b), type(c), type(d))
<class 'int'> <class 'float'> <class 'bool'> <class 'complex'>
此外还可以用 isinstance 来判断
>>> a = 111
>>> isinstance(a, int)
True
>>>
>>> class A:
pass
...
... >>> class B(A):
pass
...
... >>> isinstance(A(), A)
True
>>> type(A()) == A
True
>>> isinstance(B(), A)
True
>>> type(B()) == A
False
注意:Python3 中,bool 是 int 的子类,True 和 False 可以和数字相加, True==1、False==0 会返回 True,但可以通过 is 来判断类型。
>>> issubclass(bool, int)
True
>>> True==1
True
>>> False==0
True
>>> True+1
2
>>> False+1
1
>>> 1 is True
<python-input-12>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
1 is True
False
>>> 0 is False
<python-input-13>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
0 is False
False
什么会出现 SyntaxWarning?
Python 检测到你在用 is 比较一个字面量整数(如 1)和 True,这通常是代码错误(因为 is 比较的是身份,而不是值)。
Python 建议你使用 == 来比较值是否相等,除非你确实想检查是否是同一个对象。
在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。
当你指定一个值时,Number对象就会被创建
= 1
var1 = 10 var2
也可以使用del语句删除一些对象引用.
del var
del var_a, var_b
>>> 5 + 4 # 加法
9
>>> 4.3 - 2 # 减法
2.3
>>> 3 * 7 # 乘法
21
>>> 2 / 4 # 除法,得到一个浮点数
0.5
>>> 2 // 4 # 除法,得到一个整数
0
>>> 17 % 3 # 取余
2
>>> 2 ** 5 # 乘方
32
nt | float | complex |
---|---|---|
10 | 0.0 | 3.14j |
100 | 15.20 | 45.j |
-786 | -21.9 | 9.322e-36j |
080 | 32.3e+18 | .876j |
-0490 | -90. | -.6545+0J |
-0x260 | -32.54e100 | 3e+26J |
0x69 | 70.2E-12 | 4.53e-7j |
Python 还支持复数,复数由实数部分和虚数部分构成,可以用 a + bj,或者 complex(a,b) 表示, 复数的实部 a 和虚部 b 都是浮点型。
Python中的字符串用单引号 '
或双引号 "
括起来,同时使用反斜杠 \
转义特殊字符。
字符串的截取的语法格式如下:
变量[头下标:尾下标]
索引值以 0 为开始值,-1 为从末尾的开始位置。
加号 + 是字符串的连接符, 星号 * 表示复制当前字符串,与之结合的数字为复制的次数。实例如下:
#!/usr/bin/python3
str = 'Runoob' # 定义一个字符串变量
print(str) # 打印整个字符串
print(str[0:-1]) # 打印字符串第一个到倒数第二个字符(不包含倒数第一个字符)
print(str[0]) # 打印字符串的第一个字符
print(str[2:5]) # 打印字符串第三到第五个字符(不包含索引为 5 的字符)
print(str[2:]) # 打印字符串从第三个字符开始到末尾
print(str * 2) # 打印字符串两次
print(str + "TEST") # 打印字符串和"TEST"拼接在一起
执行以上程序会输出如下结果:
Runoob
Runoo
R
noo
noob
RunoobRunoob RunoobTEST
Python 使用反斜杠 转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:
>>> print('Ru\noob')
Ru
oob>>> print(r'Ru\noob')
Ru\noob>>>
另外,反斜杠(\)
可以作为续行符,表示下一行是上一行的延续。也可以使用
"""..."""
或者 '''...'''
跨越多行。
注意,Python 没有单独的字符类型,一个字符就是长度为1的字符串。
>>> word = 'Python'
>>> print(word[0], word[5])
P n>>> print(word[-1], word[-6])
n P
与 C 字符串不同的是,Python
字符串不能被改变。向一个索引位置赋值,比如 word[0] = 'm'
会导致错误。
注意:
布尔类型即True或False。
在 Python 中,True 和 False 都是关键字,表示布尔值。
布尔类型可以用来控制程序的流程,比如判断某个条件是否成立,或者在某个条件满足时执行某段代码。
布尔类型特点:
# 布尔类型的值和类型
= True
a = False
b print(type(a)) # <class 'bool'>
print(type(b)) # <class 'bool'>
# 布尔类型的整数表现
print(int(True)) # 1
print(int(False)) # 0
# 使用 bool() 函数进行转换
print(bool(0)) # False
print(bool(42)) # True
print(bool('')) # False
print(bool('Python')) # True
print(bool([])) # False
print(bool([1, 2, 3])) # True
# 布尔逻辑运算
print(True and False) # False
print(True or False) # True
print(not True) # False
# 布尔比较运算
print(5 > 3) # True
print(2 == 2) # True
print(7 < 4) # False
# 布尔值在控制流中的应用
if True:
print("This will always print")
if not False:
print("This will also always print")
= 10
x if x:
print("x is non-zero and thus True in a boolean context")
注意:在 Python 中,所有非零的数字和非空的字符串、列表、元组等数据类型都被视为 True,只有 0、空字符串、空列表、空元组等被视为 False。因此,在进行布尔类型转换时,需要注意数据类型的真假性。
List(列表) 是 Python 中使用最频繁的数据类型。
列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
列表是写在方括号 []
之间、用逗号分隔开的元素列表。
和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。
列表截取的语法格式如下:
变量[头下标:尾下标]# 索引值以 0 为开始值,-1 为从末尾的开始位置。
加号 + 是列表连接运算符,星号 * 是重复操作。如下实例:
#!/usr/bin/python3
list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ] # 定义一个列表
= [123, 'runoob']
tinylist
print (list) # 打印整个列表
print (list[0]) # 打印列表的第一个元素
print (list[1:3]) # 打印列表第二到第四个元素(不包含第四个元素)
print (list[2:]) # 打印列表从第三个元素开始到末尾
print (tinylist * 2) # 打印tinylist列表两次
print (list + tinylist) # 打印两个列表拼接在一起的结果
以上实例输出结果:
'abcd', 786, 2.23, 'runoob', 70.2]
[
abcd786, 2.23]
[2.23, 'runoob', 70.2]
[123, 'runoob', 123, 'runoob']
['abcd', 786, 2.23, 'runoob', 70.2, 123, 'runoob'] [
与Python字符串不一样的是,列表中的元素是可以改变的:
>>> 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] [
List 内置了有很多方法,例如 append()、pop() 等等,这在后面会讲到。
注意:
Python 列表截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串:如果第三个参数为负数表示逆向读取,以下实例用于翻转字符串:
def reverseWords(input):
# 通过空格将字符串分隔符,把各个单词分隔为列表
= input.split(" ")
inputWords
# 翻转字符串
# 假设列表 list = [1,2,3,4],
# list[0]=1, list[1]=2 ,而 -1 表示最后一个元素 list[-1]=4 ( 与 list[3]=4 一样)
# inputWords[-1::-1] 有三个参数
# 第一个参数 -1 表示最后一个元素
# 第二个参数为空,表示移动到列表末尾
# 第三个参数为步长,-1 表示逆向
=inputWords[-1::-1]
inputWords
# 重新组合字符串
= ' '.join(inputWords)
output
return output
if __name__ == "__main__":
input = 'I like runoob'
= reverseWords(input)
rw print(rw)
输出结果为:
runoob like I
元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。
元组中的元素类型也可以不相同:
#!/usr/bin/python3
tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2 )
= (123, 'runoob')
tinytuple
print (tuple) # 输出完整元组
print (tuple[0]) # 输出元组的第一个元素
print (tuple[1:3]) # 输出从第二个元素开始到第三个元素
print (tuple[2:]) # 输出从第三个元素开始的所有元素
print (tinytuple * 2) # 输出两次元组
print (tuple + tinytuple) # 连接元组
以上实例输出结果:
'abcd', 786, 2.23, 'runoob', 70.2)
(
abcd786, 2.23)
(2.23, 'runoob', 70.2)
(123, 'runoob', 123, 'runoob')
('abcd', 786, 2.23, 'runoob', 70.2, 123, 'runoob') (
元组与字符串类似,可以被索引且下标索引从0开始,-1 为从末尾开始的位置。也可以进行截取(看上面,这里不再赘述)。
其实,可以把字符串看作一种特殊的元组。
>>> tup = (1, 2, 3, 4, 5, 6)
>>> print(tup[0])
1
>>> print(tup[1:5])
2, 3, 4, 5)
(>>> tup[0] = 11 # 修改元组元素的操作是非法的
Traceback (most recent call last):"<stdin>", line 1, in <module>
File TypeError: 'tuple' object does not support item assignment
>>>
虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表。
构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:
= () # 空元组
tup1 = (20,) # 一个元素,需要在元素后添加逗号 tup2
如果你想创建只有一个元素的元组,需要注意在元素后面添加一个逗号,以区分它是一个元组而不是一个普通的值,这是因为在没有逗号的情况下,Python会将括号解释为数学运算中的括号,而不是元组的表示。
如果不添加逗号,如下所示,它将被解释为一个普通的值而不是元组:
= (42) not_a_tuple
这样的话,not_a_tuple 将是整数类型而不是元组类型。
string、list 和 tuple 都属于 sequence(序列)。
注意:
Python
中的集合(Set)是一种无序、可变的数据类型,用于存储唯一的元素。
集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。
在 Python 中,集合使用大括号 {}
表示,元素之间用逗号 ,
分隔。
另外,也可以使用 set()
函数创建集合。
注意:创建一个空集合必须用 set()
而不是
{ }
,因为 { }
是用来创建一个空字典。
创建格式:
= {value01,value02,...}
parame
或者set(value)
#!/usr/bin/python3
= {'Google', 'Taobao', 'Runoob', 'Facebook', 'Zhihu', 'Baidu'}
sites
print(sites) # 输出集合,重复的元素被自动去掉
# 成员测试
if 'Runoob' in sites :
print('Runoob 在集合中')
else :
print('Runoob 不在集合中')
# set可以进行集合运算
= set('abracadabra')
a = set('alacazam')
b
print(a)
print(a - b) # a 和 b 的差集
print(a | b) # a 和 b 的并集
print(a & b) # a 和 b 的交集
print(a ^ b) # a 和 b 中不同时存在的元素
以上实例输出结果
'Zhihu', 'Baidu', 'Taobao', 'Runoob', 'Google', 'Facebook'}
{
Runoob 在集合中'b', 'c', 'a', 'r', 'd'}
{'r', 'b', 'd'}
{'b', 'c', 'a', 'z', 'm', 'r', 'l', 'd'}
{'c', 'a'}
{'z', 'b', 'm', 'r', 'l', 'd'} {
字典(dictionary)是Python中另一个非常有用的内置数据类型。
列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
字典是一种映射类型,字典用 { }
标识,它是一个无序的 键(key)
: 值(value) 的集合。
键(key)必须使用不可变类型。
在同一个字典中,键(key)必须是唯一的。
#!/usr/bin/python3
dict = {}
dict['one'] = "1 - 菜鸟教程"
dict[2] = "2 - 菜鸟工具"
= {'name': 'runoob','code':1, 'site': 'www.runoob.com'}
tinydict
print (dict['one']) # 输出键为 'one' 的值
print (dict[2]) # 输出键为 2 的值
print (tinydict) # 输出完整的字典
print (tinydict.keys()) # 输出所有键
print (tinydict.values()) # 输出所有值
以上实例输出结果:
1 - 菜鸟教程
2 - 菜鸟工具
'name': 'runoob', 'code': 1, 'site': 'www.runoob.com'}
{'name', 'code', 'site'])
dict_keys(['runoob', 1, 'www.runoob.com']) dict_values([
构造函数dict()可以直接从键值对序列中构建字典如下:
>>> dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)])
'Runoob': 1, 'Google': 2, 'Taobao': 3}
{>>> {x: x**2 for x in (2, 4, 6)}
2: 4, 4: 16, 6: 36}
{>>> dict(Runoob=1, Google=2, Taobao=3)
'Runoob': 1, 'Google': 2, 'Taobao': 3} {
{x: x**2 for x in (2, 4, 6)}
该代码使用的是字典推导式,更多推导式内容可以参考:Python 推导式。
另外,字典类型也有一些内置的函数,例如 clear()、keys()、values() 等。
注意:
在 Python3 中,bytes 类型表示的是不可变的二进制序列(byte sequence)。
与字符串类型不同的是,bytes 类型中的元素是整数值(0 到 255 之间的整数),而不是 Unicode 字符。
bytes 类型通常用于处理二进制数据,比如图像文件、音频文件、视频文件等等。在网络编程中,也经常使用 bytes 类型来传输二进制数据。
创建 bytes 对象的方式有多种,最常见的方式是使用 b 前缀:
此外,也可以使用 bytes() 函数将其他类型的对象转换为 bytes 类型。bytes() 函数的第一个参数是要转换的对象,第二个参数是编码方式,如果省略第二个参数,则默认使用 UTF-8 编码:
= bytes("hello", encoding="utf-8") x
与字符串类型类似,bytes 类型也支持许多操作和方法,如切片、拼接、查找、替换等等。同时,由于 bytes 类型是不可变的,因此在进行修改操作时需要创建一个新的 bytes 对象。例如:
= b"hello"
x = x[1:3] # 切片操作,得到 b"el"
y = x + b"world" # 拼接操作,得到 b"helloworld" z
需要注意的是,bytes类型中的元素是整数值,因此在进行比较操作时需要使用相应的整数值,例如:
= b"hello"
x if x[0] == ord("h"):
print("The first element is 'h'")
其中 ord() 函数用于将字符转换为相应的整数值。
有时候,我们需要对数据内置的类型进行转换,数据类型的转换,一般情况下你只需要将数据类型作为函数名即可。
Python数据类型转换可以分为两种:
在隐式类型转换中,Python会自动将一种数据类型转换为另一种数据类型,不需要我们去干预。
以下实例中,我们对两种不同类型的数据进行运算,较低数据类型(整数)就会转换为较高数据类型(浮点数)以避免数据丢失。
= 123
num_int = 1.23
num_flo
= num_int + num_flo
num_new
print("num_int 数据类型为:",type(num_int))
print("num_flo 数据类型为:",type(num_flo))
print("num_new 值为:",num_new)
print("num_new 数据类型为:",type(num_new))
以上实例输出结果为
<class 'int'>
num_int 数据类型为: <class 'float'>
num_flo 数据类型为: 124.23
num_new: 值为: <class 'float'> num_new 数据类型为:
代码解析:
我们再看一个实例,整形数据与字符串类型的数据进行相加:
= 123
num_int = "456"
num_str
print("num_int 数据类型为:",type(num_int))
print("num_str 数据类型为:",type(num_str))
print(num_int+num_str)
以上实例输出结果为:
<class 'int'>
num_int 数据类型为: <class 'str'>
num_str 数据类型为:
Traceback (most recent call last):"/runoob-test/test.py", line 7, in <module>
File print(num_int+num_str)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
从输出中可以看出,整形和字符串类型运算结果会报错,输出 TypeError。 Python 在这种情况下无法使用隐式转换。
但是,Python 为这些类型的情况提供了一种解决方案,称为显式转换。
在显式类型转换中,用户将对象的数据类型转换为所需的数据类型。我们使用 int()、float()、str() 等预定义函数来执行显式类型转换。
int()
强制转换为整形:
= int(1) # x 输出结果为 1
x = int(2.8) # y 输出结果为 2
y = int("3") # z 输出结果为 3 z
float()
强制转换为浮点型:
= float(1) # x 输出结果为 1.0
x = float(2.8) # y 输出结果为 2.8
y = float("3") # z 输出结果为 3.0
z = float("4.2") # w 输出结果为 4.2 w
str()
强制转换为字符串类型:
= str("s1") # x 输出结果为 's1'
x = str(2) # y 输出结果为 '2'
y = str(3.0) # z 输出结果为 '3.0' z
整型和字符串类型进行运算,就可以用强制类型转换来完成:
= 123
num_int = "456"
num_str
print("num_int 数据类型为:",type(num_int))
print("类型转换前,num_str 数据类型为:",type(num_str))
= int(num_str) # 强制转换为整型
num_str print("类型转换后,num_str 数据类型为:",type(num_str))
= num_int + num_str
num_sum
print("num_int 与 num_str 相加结果为:",num_sum)
print("sum 数据类型为:",type(num_sum))
以上实例输出结果为:
<class 'int'>
num_int 数据类型为: <class 'str'>
类型转换前,num_str 数据类型为: <class 'int'>
类型转换后,num_str 数据类型为: 579
num_int 与 num_str 相加结果为: sum 数据类型为: <class 'int'>
以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。
函数 | 描述 |
---|---|
int(x [,base]) |
将x转换为一个整数 |
float(x) |
将x转换到一个浮点数 |
complex(real [,imag]) |
创建一个复数 |
str(x) |
将对象 x 转换为字符串 |
repr(x) |
将对象 x 转换为表达式字符串 |
eval(str) |
用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) |
将序列 s 转换为一个元组 |
list(s) |
将序列 s 转换为一个列表 |
set(s) |
转换为可变集合 |
dict(d) |
创建一个字典。d 必须是一个 (key, value)元组序列。 |
frozenset(s) |
转换为不可变集合 |
chr(x) |
将一个整数转换为一个字符 |
ord(x) |
将一个字符转换为它的整数值 |
hex(x) |
将一个整数转换为一个十六进制字符串 |
oct(x) |
将一个整数转换为一个八进制字符串 |
以下假设变量 a=10,变量 b=21:
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | a + b 输出结果 31 |
- | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
* | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 210 |
/ | 除 - x 除以 y | b / a 输出结果 2.1 |
% | 取模 - 返回除法的余数 | b % a 输出结果 1 |
** | 幂 - 返回 x 的 y 次幂 | a**b 为 10 的 21 次方 |
// | 取整除 - 往小的方向取整数 | 9//2 输出 4 -9//2 输出 -5 |
以下实例演示了Python所有算术运算符的操作:
#!/usr/bin/python3
= 21
a = 10
b = 0
c
= a + b
c print ("1 - c 的值为:", c)
= a - b
c print ("2 - c 的值为:", c)
= a * b
c print ("3 - c 的值为:", c)
= a / b
c print ("4 - c 的值为:", c)
= a % b
c print ("5 - c 的值为:", c)
# 修改变量 a 、b 、c
= 2
a = 3
b = a**b
c print ("6 - c 的值为:", c)
= 10
a = 5
b = a//b
c print ("7 - c 的值为:", c)
以上实例输出结果
1 - c 的值为: 31
2 - c 的值为: 11
3 - c 的值为: 210
4 - c 的值为: 2.1
5 - c 的值为: 1
6 - c 的值为: 8
7 - c 的值为: 2
以下假设变量 a 为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 - 比较对象是否相等 | (a == b) 返回 False |
!= | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True |
> | 大于 - 返回 x 是否大于 y | (a > b) 返回 False |
< | 小于 - 返回 x 是否小于 y。所有比较运算符返回 1 表示真,返回 0 表示假。这分别与特殊的变量 True 和 False 等价。注意,这些变量名的大写。 | (a < b) 返回 True |
>= | 大于等于 - 返回 x 是否大于等于 y | (a >= b) 返回 False |
<= | 小于等于 - 返回 x 是否小于等于 y | (a <= b) 返回 True |
以下实例演示了Python所有比较运算符的操作:
#!/usr/bin/python3
= 21
a = 10
b = 0
c
if ( a == b ):
print ("1 - a 等于 b")
else:
print ("1 - a 不等于 b")
if ( a != b ):
print ("2 - a 不等于 b")
else:
print ("2 - a 等于 b")
if ( a < b ):
print ("3 - a 小于 b")
else:
print ("3 - a 大于等于 b")
if ( a > b ):
print ("4 - a 大于 b")
else:
print ("4 - a 小于等于 b")
# 修改变量 a 和 b 的值
= 5
a = 20
b if ( a <= b ):
print ("5 - a 小于等于 b")
else:
print ("5 - a 大于 b")
if ( b >= a ):
print ("6 - b 大于等于 a")
else:
print ("6 - b 小于 a")
以上实例输出结果:
1 - a 不等于 b
2 - a 不等于 b
3 - a 大于等于 b
4 - a 大于 b
5 - a 小于等于 b
6 - b 大于等于 a
以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
:= | 海象运算符,这个运算符的主要目的是在表达式中同时进行赋值和返回赋值的值。Python3.8 版本新增运算符。 | python<br>if (n := len(a)) > 10:<br> print(f"List is too long ({n} elements, expected <= 10)")<br> |
以下实例演示了Python所有赋值运算符的操作:
#!/usr/bin/python3
= 21
a = 10
b = 0
c
= a + b
c print ("1 - c 的值为:", c)
+= a
c print ("2 - c 的值为:", c)
*= a
c print ("3 - c 的值为:", c)
/= a
c print ("4 - c 的值为:", c)
= 2
c %= a
c print ("5 - c 的值为:", c)
**= a
c print ("6 - c 的值为:", c)
//= a
c print ("7 - c 的值为:", c)
以上实例输出结果:
1 - c 的值为: 31
2 - c 的值为: 52
3 - c 的值为: 1092
4 - c 的值为: 52.0
5 - c 的值为: 2
6 - c 的值为: 2097152
7 - c 的值为: 99864
在 Python 3.8 及更高版本中,引入了一种新的语法特性,称为”海象运算符”(Walrus Operator),它使用 := 符号。这个运算符的主要目的是在表达式中同时进行赋值和返回赋值的值。
使用海象运算符可以在一些情况下简化代码,尤其是在需要在表达式中使用赋值结果的情况下。这对于简化循环条件或表达式中的重复计算很有用。
下面是一个简单的实例,演示了海象运算符的使用:
# 传统写法
= 10
n if n > 5:
print(n)
# 使用海象运算符
if (n := 10) > 5:
print(n)
海象运算符的优点:
按位运算符是把数字看作二进制来进行计算的。Python中的按位运算法则如下:
下表中变量 a 为 60,b 为 13二进制格式如下:
= 0011 1100
a
= 0000 1101
b
-----------------
&b = 0000 1100
a
|b = 0011 1101
a
^b = 0011 0001
a
~a = 1100 0011
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释:
0000 1100 |
| | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | (a \| b) 输出结果 61 ,二进制解释:
0011 1101 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释:
0011 0001 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 | (~a) 输出结果 -61 ,二进制解释:
1100 0011 ,在一个有符号二进制数的补码形式。 |
<< | 左移动运算符:运算数的各二进位全部左移若干位,由”<<“右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释:
1111 0000 |
>> | 右移动运算符:把”>>“左边的运算数的各二进位全部右移若干位,”>>“右边的数指定移动的位数 | a >> 2 输出结果 15 ,二进制解释:
0000 1111 |
以下实例演示了Python所有位运算符的操作:
#!/usr/bin/python3
= 60 # 60 = 0011 1100
a = 13 # 13 = 0000 1101
b = 0
c
= a & b # 12 = 0000 1100
c print ("1 - c 的值为:", c)
= a | b # 61 = 0011 1101
c print ("2 - c 的值为:", c)
= a ^ b # 49 = 0011 0001
c print ("3 - c 的值为:", c)
= ~a # -61 = 1100 0011
c print ("4 - c 的值为:", c)
= a << 2 # 240 = 1111 0000
c print ("5 - c 的值为:", c)
= a >> 2 # 15 = 0000 1111
c print ("6 - c 的值为:", c)
以上实例输出结果:
1 - c 的值为: 12
2 - c 的值为: 61
3 - c 的值为: 49
4 - c 的值为: -61
5 - c 的值为: 240
6 - c 的值为: 15
Python语言支持逻辑运算符,以下假设变量a为10,b为20:
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔”与” - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值。 | (a and b) 返回 20 |
or | x or y | 布尔”或” - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10 |
not | not x | 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
以上实例输出结果:
#!/usr/bin/python3
= 10
a = 20
b
if ( a and b ):
print ("1 - 变量 a 和 b 都为 true")
else:
print ("1 - 变量 a 和 b 有一个不为 true")
if ( a or b ):
print ("2 - 变量 a 和 b 都为 true,或其中一个变量为 true")
else:
print ("2 - 变量 a 和 b 都不为 true")
# 修改变量 a 的值
= 0
a if ( a and b ):
print ("3 - 变量 a 和 b 都为 true")
else:
print ("3 - 变量 a 和 b 有一个不为 true")
if ( a or b ):
print ("4 - 变量 a 和 b 都为 true,或其中一个变量为 true")
else:
print ("4 - 变量 a 和 b 都不为 true")
if not( a and b ):
print ("5 - 变量 a 和 b 都为 false,或其中一个变量为 false")
else:
print ("5 - 变量 a 和 b 都为 true")
以上实例输出结果:
1 - 变量 a 和 b 都为 true
2 - 变量 a 和 b 都为 true,或其中一个变量为 true
3 - 变量 a 和 b 有一个不为 true
4 - 变量 a 和 b 都为 true,或其中一个变量为 true
5 - 变量 a 和 b 都为 false,或其中一个变量为 false
除了以上的一些运算符之外,Python还支持成员运算符,测试实例中包含了一系列的成员,包括字符串,列表或元组。
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
以下实例演示了Python所有成员运算符的操作:
#!/usr/bin/python3
= 10
a = 20
b list = [1, 2, 3, 4, 5 ]
if ( a in list ):
print ("1 - 变量 a 在给定的列表中 list 中")
else:
print ("1 - 变量 a 不在给定的列表中 list 中")
if ( b not in list ):
print ("2 - 变量 b 不在给定的列表中 list 中")
else:
print ("2 - 变量 b 在给定的列表中 list 中")
# 修改变量 a 的值
= 2
a if ( a in list ):
print ("3 - 变量 a 在给定的列表中 list 中")
else:
print ("3 - 变量 a 不在给定的列表中 list 中")
以上实例输出结果:
1 - 变量 a 不在给定的列表中 list 中
2 - 变量 b 不在给定的列表中 list 中
3 - 变量 a 在给定的列表中 list 中
身份运算符用于比较两个对象的存储单元:
运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用自一个对象 | x is y , 类似 id(x) == id(y) ,
如果引用的是同一个对象则返回 True,否则返回 False |
is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似
id(x) != id(y) 。如果引用的不是同一个对象则返回结果
True,否则返回 False |
注: id() 函数用于获取对象内存地址。
以下实例演示了Python所有身份运算符的操作:
#!/usr/bin/python3
= 20
a = 20
b
if ( a is b ):
print ("1 - a 和 b 有相同的标识")
else:
print ("1 - a 和 b 没有相同的标识")
if ( id(a) == id(b) ):
print ("2 - a 和 b 有相同的标识")
else:
print ("2 - a 和 b 没有相同的标识")
# 修改变量 b 的值
= 30
b if ( a is b ):
print ("3 - a 和 b 有相同的标识")
else:
print ("3 - a 和 b 没有相同的标识")
if ( a is not b ):
print ("4 - a 和 b 没有相同的标识")
else:
print ("4 - a 和 b 有相同的标识")
以上实例输出结果:
1 - a 和 b 有相同的标识
2 - a 和 b 有相同的标识
3 - a 和 b 没有相同的标识
4 - a 和 b 没有相同的标识
s 与 == 区别: is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
>>>a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True
以下表格列出了从最高到最低优先级的所有运算符, 相同单元格内的运算符具有相同优先级。 运算符均指二元运算,除非特别指出。 相同单元格内的运算符从左至右分组(除了幂运算是从右至左分组):
运算符或表达式 | 描述 |
---|---|
(expressions...) , [expressions...] ,
{key: value...} , {expressions...} |
圆括号的表达式 |
x[index] , x[index:index] ,
x(arguments...) , x.attribute |
读取,切片,调用,属性引用 |
await x |
await 表达式 |
** |
乘方(指数) |
+x , -x , ~x |
正,负,按位非 NOT |
* , @ , / , // ,
% |
乘,矩阵乘,除,整除,取余 |
+ , - |
加和减 |
<< , >> |
移位 |
& |
按位与 AND |
^ |
按位异或 XOR |
| |
按位或 OR |
in , not in , is ,
is not , < , <= ,
> , >= , != ,
== |
比较运算,包括成员检测和标识号检测 |
not x |
逻辑非 NOT |
and |
逻辑与 AND |
or |
逻辑或 OR |
if -- else |
条件表达式 |
lambda |
lambda 表达式 |
:= |
赋值表达式 |
下实例演示了Python所有运算符优先级的操作:
#!/usr/bin/python3
= 20
a = 10
b = 15
c = 5
d = 0
e
= (a + b) * c / d #( 30 * 15 ) / 5
e print ("(a + b) * c / d 运算结果为:", e)
= ((a + b) * c) / d # (30 * 15 ) / 5
e print ("((a + b) * c) / d 运算结果为:", e)
= (a + b) * (c / d) # (30) * (15/5)
e print ("(a + b) * (c / d) 运算结果为:", e)
= a + (b * c) / d # 20 + (150/5)
e print ("a + (b * c) / d 运算结果为:", e)
以上实例输出结果:
+ b) * c / d 运算结果为: 90.0
(a + b) * c) / d 运算结果为: 90.0
((a + b) * (c / d) 运算结果为: 90.0
(a + (b * c) / d 运算结果为: 50.0 a
and拥有更高优先级:
= True
x = False
y = False
z
print("情况1:默认优先级(先算and)")
if x or y and z: # 等同于 x or (y and z)
print("yes") # 会输出
else:
print("no")
print("\n情况2:强制改变优先级(先算or)")
if (x or y) and z: # 人为添加括号改变顺序
print("yes") # 不会输出
else:
print("no") # 会输出
以上实例先计算 y and z
并返回 False,然后
x ot False
返回 True,输出结果:
1:默认优先级(先算and)
情况
yes
2:强制改变优先级(先算or)
情况 no
Python数字数据类型用于存储数值。数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间。
以下实例在变量赋值时 Number 对象将被创建:
= 1
var1 = 10 var2
您也可以使用del语句删除一些数字对象的引用:
del语句的语法是:
del var1[,var2[,var3[....,varN]]]
您可以通过使用del语句删除单个或多个对象的引用,例如:
del var
del var_a, var_b
Python 支持三种不同的数值类型:
我们可以使用十六进制和八进制来代表整数:
>>> number = 0xA0F # 十六进制
>>> number
2575
>>> number=0o37 # 八进制
>>> number
31
int | float | complex |
---|---|---|
10 |
0.0 |
3.14j |
100 |
15.20 |
45.j |
-786 |
-21.9 |
9.322e-36j |
080 |
32.3e+18 |
.876j |
-0490 |
-90. |
-.6545+0J |
-0x260 |
-32.54e100 |
3e+26J |
0x69 |
70.2E-12 |
4.53e-7j |
有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。
以下示例将浮点数变量 a 转换为整数:
>>> a = 1.0
>>> int(a)
1
Python解释器可以作为一个简单的计算器,您可以在解释器里输入一个表达式,它将输出表达式的值。
表达式的语法很直白,+, -, * 和 /, 和其它语言(如Pascal或C)里一样。例如:
>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # 总是返回一个浮点数
1.6
注意:在不同的机器上浮点运算的结果可能不太一样。
在整数除法中,除法 /
总是返回一个浮点数,如果只想得到整数的结果,丢弃可能的分数部分,可以使用运算符
//
:
>>> 17 / 3 # 整数除法返回浮点型
5.666666666666667
>>>
>>> 17 // 3 # 整数除法返回向下取整后的结果
5
>>> 17 % 3 # %操作符返回除法的余数
2
>>> 5 * 3 + 2
17
注意:// 得到的并不一定是整数类型的数,它与分母分子的数据类型有关系。
>>> 7//2
3
>>> 7.0//2
3.0
>>> 7//2.0
3.0
>>>
等号 = 用于给变量赋值。赋值之后,除了下一个提示符,解释器不会显示任何结果。
>>> width = 20
>>> height = 5*9
>>> width * height
900
Python可以使用 **
操作来进行幂运算:
>>> 5 ** 2 # 5 的平方
25
>>> 2 ** 7 # 2的7次方
128
变量在使用前必须先 “定义”(即赋予变量一个值),否则会出现错误:
>>> n # 尝试访问一个未定义的变量
Traceback (most recent call last):"<stdin>", line 1, in <module>
File NameError: name 'n' is not defined
不同类型的数混合运算时会将整数转换为浮点数:
>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5
在交互模式中,最后被输出的表达式结果被赋值给变量 _,例如
>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06
函数 | 返回值 ( 描述 ) |
---|---|
abs(x) |
返回数字的绝对值,如 abs(-10) 返回 10 |
ceil(x) |
返回数字的上入整数,如 math.ceil(4.1) 返回 5 |
cmp(x, y) |
如果 x < y 返回 -1, 如果 x == y 返回 0,
如果 x > y 返回 1。Python 3 已废弃,使用
(x>y)-(x<y) 替换。 |
exp(x) |
返回 e 的 x 次幂 (e^x),如 math.exp(1) 返回
2.718281828459045 |
fabs(x) |
以浮点数形式返回数字的绝对值,如 math.fabs(-10) 返回
10.0 |
floor(x) |
返回数字的下舍整数,如 math.floor(4.9) 返回 4 |
log(x) |
如 math.log(math.e) 返回
1.0,math.log(100,10) 返回 2.0 |
log10(x) |
返回以 10 为基数的 x 的对数,如 math.log10(100) 返回
2.0 |
max(x1, x2,...) |
返回给定参数的最大值,参数可以为序列。 |
min(x1, x2,...) |
返回给定参数的最小值,参数可以为序列。 |
modf(x) |
返回 x 的整数部分与小数部分,两部分的数值符号与 x 相同,整数部分以浮点型表示。 |
pow(x, y) |
x**y 运算后的值。 |
round(x [,n]) |
返回浮点数 x 的四舍五入值,如给出 n 值,则代表舍入到小数点后的位数。其实准确的说是保留值将保留到离上一位更近的一端。 |
sqrt(x) |
返回数字 x 的平方根。 |
随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。
Python包含以下常用随机数函数:
函数 | 描述 |
---|---|
choice(seq) |
从序列的元素中随机挑选一个元素,比如
random.choice(range(10)) ,从 0 到 9
中随机挑选一个整数。 |
randrange([start,] stop [,step]) |
从指定范围内,按指定基数递增的集合中获取一个随机数,基数默认值为 1。 |
random() |
随机生成下一个实数,它在 [0,1) 范围内。 |
seed([x]) |
改变随机数生成器的种子 seed。如果你不了解其原理,你不必特别去设定 seed,Python 会帮你选择 seed。 |
shuffle(lst) |
将序列的所有元素随机排序。 |
uniform(x, y) |
随机生成下一个实数,它在 [x,y] 范围内。 |
Python包括以下三角函数:
函数 | 描述 |
---|---|
acos(x) |
返回 x 的反余弦弧度值。 |
asin(x) |
返回 x 的反正弦弧度值。 |
atan(x) |
返回 x 的反正切弧度值。 |
atan2(y, x) |
返回给定的 X 及 Y 坐标值的反正切值。 |
cos(x) |
返回 x 的弧度的余弦值。 |
hypot(x, y) |
返回欧几里德范数 sqrt(x*x + y*y) 。 |
sin(x) |
返回 x 弧度的正弦值。 |
tan(x) |
返回 x 弧度的正切值。 |
degrees(x) |
将弧度转换为角度,如 degrees(math.pi/2) ,返回
90.0。 |
radians(x) |
将角度转换为弧度。 |
常量 | 描述 |
---|---|
pi 数学常量 | pi(圆周率,一般以π来表示) |
e 数学常量 | e,e即自然常数(自然常数)。 |
字符串是 Python 中最常用的数据类型。我们可以使用引号( ’ 或 ” )来创建字符串。
创建字符串很简单,只要为变量分配一个值即可。例如:
= 'Hello World!'
var1 = "Runoob" var2
Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。
Python 访问子字符串,可以使用方括号 [] 来截取字符串,字符串的截取的语法格式如下:
变量[头下标:尾下标]
如下实例:
#!/usr/bin/python3
= 'Hello World!'
var1 = "Runoob"
var2
print ("var1[0]: ", var1[0])
print ("var2[1:5]: ", var2[1:5])
以上实例执行结果:
0]: H
var1[1:5]: unoo var2[
你可以截取字符串的一部分并与其他字段拼接,如下实例:
#!/usr/bin/python3
= 'Hello World!'
var1
print ("已更新字符串 : ", var1[:6] + 'Runoob!')
以上实例执行结果:
! 已更新字符串 : Hello Runoob
在需要在字符中使用特殊字符时,python 用反斜杠 转义字符。如下表:
\(在行尾时) 续行符 >>> print("line1 \
... line2 \
... line3")
line1 line2 line3>>>
\\ 反斜杠符号 >>> print("\\")
\
' 单引号
\>>> print('\'')
'
\" 双引号
>>> print("\"")
"
\a 响铃
>>> print("\a")
执行后电脑有响声。
\b 退格(Backspace) >>> print("Hello \b World!")
!
Hello World
000 空
\>>> print("\000")
>>>
\n 换行 >>> print("\n")
>>>
\v 纵向制表符 >>> print("Hello \v World!")
Hello !
World>>>
\t 横向制表符 >>> print("Hello \t World!")
!
Hello World>>>
\r 回车,将 \r 后面的内容移到字符串开头,并逐一替换开头部分的字符,直至将 \r 后面的内容完全替换完成。 >>> print("Hello\rWorld!")
!
World>>> print('google runoob taobao\r123456')
123456 runoob taobao
\f 换页 >>> print("Hello \f World!")
Hello !
World>>>
0~7 的字符,例如:\012 代表换行。
\yyy 八进制数,y 代表 >>> print("\110\145\154\154\157\40\127\157\162\154\144\41")
!
Hello World
\xyy 十六进制数,以 \x 开头,y 代表的字符,例如:\x0a 代表换行 >>> print("\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21")
!
Hello World
\other 其它的字符以普通格式输出
使用 现百分比进度
import time
for i in range(101): # 添加进度条图形和百分比
= '[' + '=' * (i // 2) + ' ' * (50 - i // 2) + ']'
bar print(f"\r{bar} {i:3}%", end='', flush=True)
0.05)
time.sleep(print()
以下实例,我们使用了不同的转义字符来演示单引号、换行符、制表符、退格符、换页符、ASCII、二进制、八进制数和十六进制数的效果:
print('\'Hello, world!\'') # 输出:'Hello, world!'
print("Hello, world!\nHow are you?") # 输出:Hello, world!
# How are you?
print("Hello, world!\tHow are you?") # 输出:Hello, world! How are you?
print("Hello,\b world!") # 输出:Hello world!
print("Hello,\f world!") # 输出:
# Hello,
# world!
print("A 对应的 ASCII 值为:", ord('A')) # 输出:A 对应的 ASCII 值为: 65
print("\x41 为 A 的 ASCII 代码") # 输出:A 为 A 的 ASCII 代码
= 42
decimal_number = bin(decimal_number) # 十进制转换为二进制
binary_number print('转换为二进制:', binary_number) # 转换为二进制: 0b101010
= oct(decimal_number) # 十进制转换为八进制
octal_number print('转换为八进制:', octal_number) # 转换为八进制: 0o52
= hex(decimal_number) # 十进制转换为十六进制
hexadecimal_number print('转换为十六进制:', hexadecimal_number) # 转换为十六进制: 0x2a
下表实例变量 a 值为字符串 “Hello”,b 变量值为 “Python”:
操作符 | 描述 | 实例 |
---|---|---|
+ |
字符串连接 | a + b 输出结果: HelloPython |
* |
重复输出字符串 | a*2 输出结果: HelloHello |
[] |
通过索引获取字符串中字符 | a[1] 输出结果: e |
[:] |
截取字符串中的一部分,遵循左闭右开原则,str[0:2]
是不包含第 3 个字符的。 |
a[1:4] 输出结果: ell |
in |
成员运算符 - 如果字符串中包含给定的字符返回 True |
'H' in a 输出结果: True |
not in |
成员运算符 - 如果字符串中不包含给定的字符返回 True |
'M' not in a 输出结果: True |
r/R |
原始字符串 -
原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。原始字符串除在字符串的第一个引号前加上字母
r (可以大小写)以外,与普通字符串有着几乎完全相同的语法。 |
print(r'\n')# 输出: \n print(R'\n') # 输出: \n |
% |
格式字符串 | 请看下一节内容。 |
#!/usr/bin/python3
= "Hello"
a = "Python"
b
print("a + b 输出结果:", a + b)
print("a * 2 输出结果:", a * 2)
print("a[1] 输出结果:", a[1])
print("a[1:4] 输出结果:", a[1:4])
if( "H" in a) :
print("H 在变量 a 中")
else :
print("H 不在变量 a 中")
if( "M" not in a) :
print("M 不在变量 a 中")
else :
print("M 在变量 a 中")
print (r'\n')
print (R'\n')
以上实例输出结果为
+ b 输出结果: HelloPython
a * 2 输出结果: HelloHello
a 1] 输出结果: e
a[1:4] 输出结果: ell
a[
H 在变量 a 中
M 不在变量 a 中
\n \n
Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。
在 Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法。
#!/usr/bin/python3
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
# 我叫 小明 今年 10 岁!
python字符串格式化符号:
符号 | 描述 |
---|---|
%c |
格式化字符及其 ASCII 码 |
%s |
格式化字符串 |
%d |
格式化整数 |
%u |
格式化无符号整型 |
%o |
格式化无符号八进制数 |
%x |
格式化无符号十六进制数 |
%X |
格式化无符号十六进制数(大写) |
%f |
格式化浮点数字,可指定小数点后的精度 |
%e |
用科学计数法格式化浮点数 |
%E |
作用同 %e ,用科学计数法格式化浮点数 |
%g |
%f 和 %e 的简写 |
%G |
%f 和 %E 的简写 |
%p |
用十六进制数格式化变量的地址 |
格式化操作符辅助指令:
符号 | 功能 |
---|---|
* |
定义宽度或者小数点精度 |
- |
用做左对齐 |
+ |
在正数前面显示加号 (+ ) |
<sp> |
在正数前面显示空格 |
# |
在八进制数前面显示零 ('0' ),在十六进制前面显示
'0x' 或者 '0X' (取决于用的是 'x'
还是 'X' ) |
0 |
显示的数字前面填充 '0' 而不是默认的空格 |
% |
'%%' 输出一个单一的 '%' |
(var) |
映射变量 (字典参数) |
m.n. |
m 是显示的最小总宽度,n 是小数点后的位数
(如果可用的话) |
Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。
python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。实例如下
#!/usr/bin/python3
= """这是一个多行字符串的实例
para_str 多行字符串可以使用制表符
TAB ( \t )。
也可以使用换行符 [ \n ]。
"""
print (para_str)
以上实例执行结果为:
这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( )。
也可以使用换行符 [ ]。
f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。
之前我们习惯用百分号 (%):
>>> name = 'Runoob'
>>> 'Hello %s' % name
'Hello Runoob'
f-string 格式化字符串以 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'
用了这种方式明显更简单了,不用再去判断使用 %s,还是 %d。
在 Python 3.8 的版本中可以使用 = 符号来拼接运算表达式与结果:
>>> x = 1
>>> print(f'{x+1}') # Python 3.6
2
>>> x = 1
>>> print(f'{x+1=}') # Python 3.8
+1=2 x
在Python3中,所有的字符串都是Unicode字符串。
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")
bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。
Python3 中没有 decode 方法,但我们可以使用
5. encode(encoding='UTF-8',errors='strict')
'ignore'或者'replace'
以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是
6. endswith(suffix, beg=0, end=len(string))
True,否则返回 False。
检查字符串是否以 suffix 结束,如果 beg 或者 end 指定则检查指定的范围内是否以 suffix 结束,如果是,返回
7. expandtabs(tabsize=8)
8 。
把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是
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()
False
如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回
14. isnumeric()
False
如果字符串中只包含数字字符,则返回 True,否则返回
15. isspace()
False.
如果字符串中只包含空白,则返回 True,否则返回
16. istitle()
False
如果字符串是标题化的(见 title())则返回 True,否则返回
17. isupper()
False
如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回
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])
max 指定,则替换不超过 max 次。
把 将字符串中的 old 替换成 new,如果
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="")
256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中
根据 table 给出的表(包含
38. upper()
转换字符串中的小写字母为大写
39. zfill (width)
0
返回长度为 width 的字符串,原字符串右对齐,前面填充
40. isdecimal()
检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。
序列是 Python 中最基本的数据结构。
序列中的每个值都有对应的位置值,称之为索引,第一个索引是 0,第二个索引是 1,依此类推。
Python 有 6 个序列的内置类型,但最常见的是列表和元组。
列表都可以进行的操作包括索引,切片,加,乘,检查成员。
此外,Python 已经内置确定序列的长度以及确定最大和最小的元素的方法。
列表是最常用的 Python 数据类型,它可以作为一个方括号内的逗号分隔值出现。
列表的数据项不需要具有相同的类型
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:
= ['Google', 'Runoob', 1997, 2000]
list1 = [1, 2, 3, 4, 5 ]
list2 = ["a", "b", "c", "d"]
list3 = ['red', 'green', 'blue', 'yellow', 'white', 'black'] list4
与字符串的索引一样,列表索引从 0 开始,第二个索引是 1,依此类推。
通过索引列表可以进行截取、组合等操作。
#!/usr/bin/python3
list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print( list[0] )
print( list[1] )
print( list[2] )
以上实例输出结果
red
green blue
索引也可以从尾部开始,最后一个元素的索引为 -1,往前一位为 -2,以此类推。
#!/usr/bin/python3
list = ['red', 'green', 'blue', 'yellow', 'white', 'black']
print( list[-1] )
print( list[-2] )
print( list[-3] )
以上实例输出结果:
black
white yellow
使用下标索引来访问列表中的值,同样你也可以使用方括号 []
的形式截取字符,如下所示:
#!/usr/bin/python3
= [10, 20, 30, 40, 50, 60, 70, 80, 90]
nums print(nums[0:4])
以上实例输出结果:
10, 20, 30, 40] [
使用负数索引值截取
#!/usr/bin/python3
list = ['Google', 'Runoob', "Zhihu", "Taobao", "Wiki"]
# 读取第二位
print ("list[1]: ", list[1])
# 从第二位开始(包含)截取到倒数第二位(不包含)
print ("list[1:-2]: ", list[1:-2])
以上实例输出结果:
list[1]: Runoob
list[1:-2]: ['Runoob', 'Zhihu']
你可以对列表的数据项进行修改或更新,你也可以使用
append()
方法来添加列表项,如下所示:
#!/usr/bin/python3
list = ['Google', 'Runoob', 1997, 2000]
print ("第三个元素为 : ", list[2])
list[2] = 2001
print ("更新后的第三个元素为 : ", list[2])
= ['Google', 'Runoob', 'Taobao']
list1 'Baidu')
list1.append(print ("更新后的列表 : ", list1)
# 第三个元素为 : 1997
# 更新后的第三个元素为 : 2001
# 更新后的列表 : ['Google', 'Runoob', 'Taobao', 'Baidu']
可以使用 del 语句来删除列表中的元素,如下实例:
#!/usr/bin/python3
list = ['Google', 'Runoob', 1997, 2000]
print ("原始列表 : ", list)
del list[2]
print ("删除第三个元素 : ", list)
以上实例输出结果
'Google', 'Runoob', 1997, 2000]
原始列表 : ['Google', 'Runoob', 2000] 删除第三个元素 : [
列表对 +
和 *
的操作符与字符串相似。+
号用于组合列表,*
号用于重复列表。
如下所示:
Python 表达式 | 结果 | 描述 |
---|---|---|
len([1, 2, 3]) | 3 | 长度 |
[1, 2, 3] + [4, 5, 6] | [1, 2, 3, 4, 5, 6] | 组合 |
[‘Hi!’] * 4 | [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] | 重复 |
3 in [1, 2, 3] | True | 元素是否存在于列表中 |
for x in [1, 2, 3]: print(x, end=” “) | 1 2 3 | 迭代 |
Python 的列表截取与字符串操作类似,如下所示:
=['Google', 'Runoob', 'Taobao']
L
# Python 表达式 结果 描述
# L[2] 'Taobao' 读取第三个元素
# L[-2] 'Runoob' 从右侧开始读取倒数第二个元素: count from the right
# L[1:] ['Runoob', 'Taobao'] 输出从第二个元素开始后的所有元素
>>> L=['Google', 'Runoob', 'Taobao']
>>> L[2]
'Taobao'
>>> L[-2]
'Runoob'
>>> L[1:]
'Runoob', 'Taobao']
[>>>
列表还支持拼接操作:
>>> squares = [1, 4, 9, 16, 25]
>>> squares += [36, 49, 64, 81, 100]
>>> squares
1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[>>>
使用嵌套列表即在列表里创建其它列表,例如:
>>> 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'
列表比较需要引入 operator 模块的 eq 方法(详见:Python operator 模块):
# 导入 operator 模块
import operator
= [1, 2]
a = [2, 3]
b = [2, 3]
c print("operator.eq(a,b): ", operator.eq(a,b))
print("operator.eq(c,b): ", operator.eq(c,b))
以上代码输出结果为
False
operator.eq(a,b): True operator.eq(c,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()
复制列表
Python 的元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号 ( )
,列表使用方括号
[ ]
。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
>>> tup1 = ('Google', 'Runoob', 1997, 2000)
>>> tup2 = (1, 2, 3, 4, 5 )
>>> tup3 = "a", "b", "c", "d" # 不需要括号也可以
>>> type(tup3)
<class 'tuple'>
创建空元组
= () tup1
元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当做运算符使用
>>> tup1 = (50)
>>> type(tup1) # 不加逗号,类型为整型
<class 'int'>
>>> tup1 = (50,)
>>> type(tup1) # 加上逗号,类型为元组
<class 'tuple'>
元组与字符串类似,下标索引从 0 开始,可以进行截取,组合等。
元组可以使用下标索引来访问元组中的值,如下实例:
#!/usr/bin/python3
= ('Google', 'Runoob', 1997, 2000)
tup1 = (1, 2, 3, 4, 5, 6, 7 )
tup2
print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])
以上实例输出结果:
0]: Google
tup1[1:5]: (2, 3, 4, 5) tup2[
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:
#!/usr/bin/python3
= (12, 34.56)
tup1 = ('abc', 'xyz')
tup2
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
= tup1 + tup2
tup3 print (tup3)
以上实例输出结果:
12, 34.56, 'abc', 'xyz') (
元组中的元素是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:
#!/usr/bin/python3
= ('Google', 'Runoob', 1997, 2000)
tup
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)
以上实例元组被删除后,输出变量会有异常信息,输出如下所示:
删除后的元组 tup :
Traceback (most recent call last):"test.py", line 8, in <module>
File print (tup)
NameError: name 'tup' is not defined
与字符串一样,元组之间可以使用 +
、+=
和
*
号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。
len((1, 2, 3))
3
计算元素个数
>>> a = (1, 2, 3)
>>> b = (4, 5, 6)
>>> c = a+b
>>> c
1, 2, 3, 4, 5, 6)
( 连接,c 就是一个新的元组,它包含了 a 和 b 中的所有元素。
>>> a = (1, 2, 3)
>>> b = (4, 5, 6)
>>> a += b
>>> a
1, 2, 3, 4, 5, 6)
( 连接,a 就变成了一个新的元组,它包含了 a 和 b 中的所有元素。
'Hi!',) * 4
('Hi!', 'Hi!', 'Hi!', 'Hi!')
( 复制
3 in (1, 2, 3)
True
元组是否存在
for x in (1, 2, 3):
print (x, end=" ")
1 2 3
迭代
因为元组也是一个序列,所以我们可以访问元组中的指定位置的元素,也可以截取索引中的一段元素,如下所示:
元组
= ('Google', 'Runoob', 'Taobao', 'Wiki', 'Weibo','Weixin') tup
Python 表达式 | 结果 | 描述 |
---|---|---|
tup[1] |
'Runoob' |
读取第二个元素 |
tup[-2] |
'Weibo' |
反向读取,读取倒数第二个元素 |
tup[1:] |
('Runoob', 'Taobao', 'Wiki', 'Weibo', 'Weixin') |
截取元素,从第二个开始后的所有元素 |
tup[1:4] |
('Runoob', 'Taobao', 'Wiki') |
截取元素,从第二个开始到第四个元素(索引为 3) |
运行实例如下:
>>> tup = ('Google', 'Runoob', 'Taobao', 'Wiki', 'Weibo','Weixin')
>>> tup[1]
'Runoob'
>>> tup[-2]
'Weibo'
>>> tup[1:]
'Runoob', 'Taobao', 'Wiki', 'Weibo', 'Weixin')
(>>> tup[1:4]
'Runoob', 'Taobao', 'Wiki')
(>>>
Python元组包含了以下内置函数
>>> tuple1 = ('Google', 'Runoob', 'Taobao')
>>> len(tuple1)
3
>>>
# len(tuple)
# 计算元组元素个数。
>>> tuple2 = ('5', '4', '8')
>>> max(tuple2)
'8'
>>>
# max(tuple)
# 返回元组中元素最大值。
>>> tuple2 = ('5', '4', '8')
>>> min(tuple2)
'4'
>>>
# min(tuple)
# 返回元组中元素最小值。
>>> list1= ['Google', 'Taobao', 'Runoob', 'Baidu']
>>> tuple1=tuple(list1)
>>> tuple1
'Google', 'Taobao', 'Runoob', 'Baidu')
(# tuple(iterable)
# 将可迭代系列转换为元组。
所谓元组的不可变指的是元组所指向的内存中的内容不可变。
>>> tup = ('r', 'u', 'n', 'o', 'o', 'b')
>>> tup[0] = 'g' # 不支持修改元素
Traceback (most recent call last):"<stdin>", line 1, in <module>
File TypeError: 'tuple' object does not support item assignment
>>> id(tup) # 查看内存地址
4440687904
>>> tup = (1,2,3)
>>> id(tup)
4441088800 # 内存地址不一样了
从以上实例可以看出,重新赋值的元组 tup,绑定到新的对象了,不是修改了原来的对象。
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value
对用冒号 :
分割,每个对之间用逗号(,)
分割,整个字典包括在花括号
{}
中 ,格式如下所示:
= {key1 : value1, key2 : value2, key3 : value3 } d
注意:dict 作为 Python 的关键字和内置函数,变量名不建议命名为 dict。
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
一个简单的字典实例:
= {'name': 'runoob', 'likes': 123, 'url': 'www.runoob.com'} tinydict
也可如此创建字典
= { 'abc': 456 }
tinydict1 = { 'abc': 123, 98.6: 37 } tinydict2
使用大括号 { }
创建空字典:
# 使用大括号 {} 来创建空字典
= {}
emptyDict
# 打印字典
print(emptyDict)
# 查看字典的数量
print("Length:", len(emptyDict))
# 查看类型
print(type(emptyDict))
以上实例输出结果:
{}0
Length: <class 'dict'>
使用内建函数 dict() 创建字典:
= dict()
emptyDict
# 打印字典
print(emptyDict)
# 查看字典的数量
print("Length:",len(emptyDict))
# 查看类型
print(type(emptyDict))
以上实例输出结果:
{}0
Length: <class 'dict'>
把相应的键放入到方括号中,如下实例:
#!/usr/bin/python3
= {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
tinydict
print ("tinydict['Name']: ", tinydict['Name'])
print ("tinydict['Age']: ", tinydict['Age'])
以上实例输出结果:
'Name']: Runoob
tinydict['Age']: 7 tinydict[
如果用字典里没有的键访问数据,会输出错误如下:
Traceback (most recent call last):"test.py", line 5, in <module>
File print ("tinydict['Alice']: ", tinydict['Alice'])
KeyError: 'Alice'
向字典添加新内容的方法是增加新的键/值对,修改或删除已有键/值对如下实例:
#!/usr/bin/python3
= {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
tinydict
'Age'] = 8 # 更新 Age
tinydict['School'] = "菜鸟教程" # 添加信息
tinydict[
print ("tinydict['Age']: ", tinydict['Age'])
print ("tinydict['School']: ", tinydict['School'])
以上实例输出结果:
'Age']: 8
tinydict['School']: 菜鸟教程 tinydict[
能删单一的元素也能清空字典,清空只需一项操作。
显式删除一个字典用del命令,如下实例:
#!/usr/bin/python3
= {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
tinydict
del tinydict['Name'] # 删除键 'Name'
# 清空字典
tinydict.clear() del tinydict # 删除字典
print ("tinydict['Age']: ", tinydict['Age'])
print ("tinydict['School']: ", tinydict['School'])
但这回引发一个异常,因为用执行del操作后字典不再存在:
Traceback (most recent call last):"/runoob-test/test.py", line 9, in <module>
File print ("tinydict['Age']: ", tinydict['Age'])
NameError: name 'tinydict' is not defined
注:del() 方法后面也会讨论
字典值可以是任何的 python 对象,既可以是标准的对象,也可以是用户定义的,但键不行。
两个重要的点需要记住:
#!/usr/bin/python3
= {'Name': 'Runoob', 'Age': 7, 'Name': '小菜鸟'}
tinydict
print ("tinydict['Name']: ", tinydict['Name'])
以上实例输出结果:
'Name']: 小菜鸟 tinydict[
#!/usr/bin/python3
= {['Name']: 'Runoob', 'Age': 7}
tinydict
print ("tinydict['Name']: ", tinydict['Name'])
以上实例输出结果:
Traceback (most recent call last):"test.py", line 3, in <module>
File = {['Name']: 'Runoob', 'Age': 7}
tinydict TypeError: unhashable type: 'list'
Python字典包含了以下内置函数:
1. len(dict)
计算字典元素个数,即键的总数。 >>> tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
>>> len(tinydict)
3
2. str(dict)
输出字典,可以打印的字符串表示。 >>> tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
>>> str(tinydict)
"{'Name': 'Runoob', 'Class': 'First', 'Age': 7}"
3. type(variable)
返回输入的变量类型,如果变量是字典就返回字典类型。 >>> tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
>>> type(tinydict)
<class 'dict'>
Python字典包含了以下内置方法
1. dict.clear()
删除字典内所有元素
2. dict.copy()
返回一个字典的浅复制
3. dict.fromkeys()
创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
4. dict.get(key, default=None)
返回指定键的值,如果键不在字典中返回 default 设置的默认值
5. key in dict
如果键在字典dict里返回true,否则返回false
6. dict.items()
以列表返回一个视图对象
7. dict.keys()
返回一个视图对象
8. dict.setdefault(key, default=None)
和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
9. dict.update(dict2)
/值对更新到dict里
把字典dict2的键
10. dict.values()
返回一个视图对象
11. dict.pop(key[,default])
删除字典 key(键)所对应的值,返回被删除的值。
12. dict.popitem()
返回并删除字典中的最后一对键和值。
集合(set)是一个无序的不重复元素序列。
集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。
可以使用大括号 { } 创建集合,元素之间用逗号 , 分隔, 或者也可以使用 set() 函数创建集合。
= {value01,value02,...}
parame
或者set(value)
以下是一个简单实例
= {1, 2, 3, 4} # 直接使用大括号创建集合
set1 = set([4, 5, 6, 7]) # 使用 set() 函数从列表创建集合 set2
注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # 这里演示的是去重功能
'orange', 'banana', 'pear', 'apple'}
{>>> 'orange' in basket # 快速判断元素是否在集合内
True
>>> 'crabgrass' in basket
False
>>> # 下面展示两个集合间的运算.
...>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a
'a', 'r', 'b', 'c', 'd'}
{>>> a - b # 集合a中包含而集合b中不包含的元素
'r', 'd', 'b'}
{>>> a | b # 集合a或b中包含的所有元素
'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
{>>> a & b # 集合a和b中都包含了的元素
'a', 'c'}
{>>> a ^ b # 不同时包含于a和b的元素
'r', 'd', 'b', 'm', 'z', 'l'} {
类似列表推导式,同样集合支持集合推导式(Set comprehension)
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
'r', 'd'} {
s.add(x)
将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作。
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.add("Facebook")
>>> print(thisset)
'Taobao', 'Facebook', 'Google', 'Runoob'} {
还有一个方法,也可以添加元素,且参数可以是列表,元组,字典等,语法格式如下:
s.update(x)
x可以有多个,用逗号分开
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.update({1,3})
>>> print(thisset)
1, 3, 'Google', 'Taobao', 'Runoob'}
{>>> thisset.update([1,4],[5,6])
>>> print(thisset)
1, 3, 4, 5, 6, 'Google', 'Taobao', 'Runoob'}
{>>>
s.remove(x)
将元素x从集合s中移除,如果元素不存在,则会发生错误
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.remove("Taobao")
>>> print(thisset)
'Google', 'Runoob'}
{>>> thisset.remove("Facebook") # 不存在会发生错误
Traceback (most recent call last):"<stdin>", line 1, in <module>
File KeyError: 'Facebook'
>>>
此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:
s.discard( x )
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.discard("Facebook") # 不存在不会发生错误
>>> print(thisset)
'Taobao', 'Google', 'Runoob'} {
我们也可以设置随机删除集合中的一个元素,语法格式如下:
s.pop()
多次执行测试结果都不一样。
set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。
= set(("Google", "Runoob", "Taobao", "Facebook"))
thisset = thisset.pop()
x
print(x)
# Runoob
len(s)
计算集合s元素个数
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> len(thisset)
3
s.clear()
清空集合s
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> thisset.clear()
>>> print(thisset)
set()
in s x
判断元素x是否在集合s中,存在返回True,不存在返回False。
>>> thisset = set(("Google", "Runoob", "Taobao"))
>>> "Runoob" in thisset
True
>>> "Facebook" in thisset
False
>>>
方法 | 描述 |
---|---|
add() | 为集合添加元素 |
clear() | 移除集合中的所有元素 |
copy() | 拷贝一个集合 |
difference() | 返回多个集合的差集 |
difference_update() | 移除集合中的元素,该元素在指定的集合也存在。 |
discard() | 删除集合中指定的元素 |
intersection() | 返回集合的交集 |
intersection_update() | 返回集合的交集。 |
isdisjoint() | 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。 |
issubset() | 判断指定集合是否为该方法参数集合的子集。 |
issuperset() | 判断该方法的参数集合是否为指定集合的子集 |
pop() | 随机移除元素 |
remove() | 移除指定元素 |
symmetric_difference() | 返回两个集合中不重复的元素集合。 |
symmetric_difference_update() | 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。 |
union() | 返回两个集合的并集 |
update() | 给集合添加元素 |
len() | 计算集合元素个数 |
Python条件语句是通过一条或多条语句的执行结果 True或者False 来决定执行的代码块。
if condition_1:
statement_block_1elif condition_2:
statement_block_2else:
statement_block_3
Python中使用elif代替了else if,所以if语句的关键字为:if-elif-else。
注意:
:
,表示接下来是满足条件后要执行的语句块。switch...case
语句,但在
Python3.10
版本添加了
match...case
,功能也类似,详见下文。#!/usr/bin/python3
= 100
var1 if var1:
print ("1 - if 表达式条件为 true")
print (var1)
= 0
var2 if var2:
print ("2 - if 表达式条件为 true")
print (var2)
print ("Good bye!")
执行以上代码,输出结果为:
1 - if 表达式条件为 true
100
! Good bye
从结果可以看到由于变量var2为0,所以对应的if内的语句没有执行。
以下实例演示了狗的年龄计算判断:
#!/usr/bin/python3
= int(input("请输入你家狗狗的年龄: "))
age print("")
if age <= 0:
print("你是在逗我吧!")
elif age == 1:
print("相当于 14 岁的人。")
elif age == 2:
print("相当于 22 岁的人。")
elif age > 2:
= 22 + (age -2)*5
human print("对应人类年龄: ", human)
### 退出提示
input("点击 enter 键退出")
将以上脚本保存在dog.py文件中,并执行该脚本:
$ python3 dog.py 1
请输入你家狗狗的年龄:
14 岁的人。
相当于 点击 enter 键退出
以下为if中常用的操作运算符
操作符 描述< 小于
<= 小于或等于
> 大于
>= 大于或等于
== 等于,比较两个值是否相等
!= 不等于
#!/usr/bin/python3
# 程序演示了 == 操作符
# 使用数字
print(5 == 6) # False
# 使用变量
= 5
x = 8
y print(x == y) # False
在嵌套if语句中,可以把 if elif else结构放在另外一个 if elif else结构中
if 表达式1:
语句if 表达式2:
语句elif 表达式3:
语句else:
语句elif 表达式4:
语句else:
语句
实例
# !/usr/bin/python3
=int(input("输入一个数字:"))
numif num%2==0:
if num%3==0:
print ("你输入的数字可以整除 2 和 3")
else:
print ("你输入的数字可以整除 2,但不能整除 3")
else:
if num%3==0:
print ("你输入的数字可以整除 3,但不能整除 2")
else:
print ("你输入的数字不能整除 2 和 3")
Python 3.10 增加了 match...case
的条件判断,不需要再使用一连串的 if-else
来判断了。
match 后的对象会依次与 case
后的内容进行匹配,如果匹配成功,则执行匹配到的表达式,否则直接跳过,_
可以匹配一切。
语法格式如下:
match subject:
<pattern_1>:
case <action_1>
<pattern_2>:
case <action_2>
<pattern_3>:
case <action_3>
case _:
<action_wildcard>
case _
: 类似于C中的default
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
=400
mystatusprint(http_error(400))
一个 case 也可以设置多个匹配条件,条件使用 | 隔开,例如:
...case 401|403|404:
return "Not allowed"
Python中的循环语句有for和while。
Python 中 while 语句的一般形式:
while 判断条件(condition):
执行语句(statements)……
同样需要注意冒号和缩进。另外,在Python中没有do while循环。
#!/usr/bin/env python3
= 100
n
sum = 0
= 1
counter while counter <= n:
sum = sum + counter
+= 1
counter
print("1 到 %d 之和为: %d" % (n,sum))
# 1 到 100 之和为: 5050
如果 while 后面的条件语句为 false 时,则执行 else 的语句块。
语法格式如下:
while <expr>:
<statement(s)>
else:
<additional_statement(s)>
expr条件语句为true则执行 statement(s) 语句块,如果为 false,则执行 additional_statement(s)。
循环输出数字,并判断大小:
#!/usr/bin/python3
= 0
count while count < 5:
print (count, " 小于 5")
= count + 1
count else:
print (count, " 大于或等于 5")
以上脚本,输出结果如下:
0 小于 5
1 小于 5
2 小于 5
3 小于 5
4 小于 5
5 大于或等于 5
类似 if 语句的语法,如果你的 while 循环体中只有一条语句,你可以将该语句与 while 写在同一行中, 如下所示:
#!/usr/bin/python
= 1
flag
while (flag): print ('欢迎访问菜鸟教程!')
print ("Good bye!")
Python for 循环可以遍历任何可迭代对象,如一个列表或者一个字符串。
for循环的一般格式如下:
for <variable> in <sequence>:
<statements>
else:
<statements>
Python for 循环实例:
#!/usr/bin/python3
= ["Baidu", "Google","Runoob","Taobao"]
sites for site in sites:
print(site)
以上代码执行输出结果为:
Baidu
Google
Runoob Taobao
也可用于打印字符串中的每个字符
#!/usr/bin/python3
= 'runoob'
word
for letter in word:
print(letter)
以上代码执行输出结果为
r
u
n
o
o b
整数范围可以配和range()函数使用
#!/usr/bin/python3
# 1 到 5 的所有数字:
for number in range(1, 6):
print(number)
# 1
# 2
# 3
# 4
# 5
在 Python 中,for…else 语句用于在循环结束后执行一段代码。
语法格式如下:
for item in iterable:
# 循环主体
else:
# 循环结束后执行的代码
当循环执行完毕(即遍历完 iterable 中的所有元素)后,会执行 else 子句中的代码,如果在循环过程中遇到了 break 语句,则会中断循环,此时不会执行 else 子句。
for x in range(6):
print(x)
else:
print("Finally finished!")
执行脚本后,输出结果为:
0
1
2
3
4
5
! Finally finished
以下for实例中使用了break语句,break语句用于跳出当前循环体,不会执行else子句。
#!/usr/bin/python3
= ["Baidu", "Google","Runoob","Taobao"]
sites for site in sites:
if site == "Runoob":
print("菜鸟教程!")
break
print("循环数据 " + site)
else:
print("没有循环数据!")
print("完成循环!")
执行脚本后,在循环到 Runoob时会跳出循环体
循环数据 Baidu
循环数据 Google!
菜鸟教程! 完成循环
如果你需要遍历数字序列,可以使用内置 range() 函数。它会生成数列,例如:
>>>for i in range(5):
print(i)
...
...0
1
2
3
4
你也可以使用range()指定区间的值
>>>for i in range(5,9) :
print(i)
5
6
7
8
>>>
也可以使 range() 以指定数字开始并指定不同的增量(甚至可以是负数,有时这也叫做’步长’):
>>>for i in range(0, 10, 3) :
print(i)
0
3
6
9
>>>
负数:
>>>for i in range(-10, -100, -30) :
print(i)
-10
-40
-70
>>>
您可以结合 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
>>>
还可以使用 range() 函数来创建一个列表:
>>>list(range(5))
0, 1, 2, 3, 4]
[>>>
break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
实例
while中使用break:
= 5
n while n > 0:
-= 1
n if n == 2:
break
print(n)
print('循环结束。')
输出结果为:
4
3
循环结束。
while中使用continue:
= 5
n while n > 0:
-= 1
n if n == 2:
continue
print(n)
print('循环结束。')
输出结果为:
4
3
1
0
循环结束。
更多实例如下:
#!/usr/bin/python3
for letter in 'Runoob': # 第一个实例
if letter == 'b':
break
print ('当前字母为 :', letter)
= 10 # 第二个实例
var while var > 0:
print ('当前变量值为 :', var)
= var -1
var if var == 5:
break
print ("Good bye!")
以上脚本输出结果为:
当前字母为 : R
当前字母为 : u
当前字母为 : n
当前字母为 : o
当前字母为 : o10
当前变量值为 : 9
当前变量值为 : 8
当前变量值为 : 7
当前变量值为 : 6
当前变量值为 : ! Good bye
以下实例循环字符串Runoob,碰到字母o跳过输出
#!/usr/bin/python3
for letter in 'Runoob': # 第一个实例
if letter == 'o': # 字母为 o 时跳过输出
continue
print ('当前字母 :', letter)
= 10 # 第二个实例
var while var > 0:
= var -1
var if var == 5: # 变量为 5 时跳过输出
continue
print ('当前变量值 :', var)
print ("Good bye!")
以上脚本输出结果为
当前字母 : R
当前字母 : u
当前字母 : n
当前字母 : b9
当前变量值 : 8
当前变量值 : 7
当前变量值 : 6
当前变量值 : 4
当前变量值 : 3
当前变量值 : 2
当前变量值 : 1
当前变量值 : 0
当前变量值 : ! Good bye
循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被 break 终止时不执行。
如下实例用于查询质数的循环例子:
#!/usr/bin/python3
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, '等于', x, '*', n//x)
break
else:
# 循环中没有找到元素
print(n, ' 是质数')
执行以上脚本输出结果为:
2 是质数
3 是质数
4 等于 2 * 2
5 是质数
6 等于 2 * 3
7 是质数
8 等于 2 * 4
9 等于 3 * 3
Python pass是空语句,是为了保持程序结构的完整性。
pass 不做任何事情,一般用做占位语句,如下实例
>>>while True:
pass # 等待键盘中断 (Ctrl+C) ...
最小的类
>>>class MyEmptyClass:
pass ...
以下实例在字母为o时,执行pass语句块
#!/usr/bin/python3
for letter in 'Runoob':
if letter == 'o':
pass
print ('执行 pass 块')
print ('当前字母 :', letter)
print ("Good bye!")
输出结果为
当前字母 : R
当前字母 : u
当前字母 : npass 块
执行
当前字母 : opass 块
执行
当前字母 : o
当前字母 : b! Good bye
关键字end可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符,实例如下:
#!/usr/bin/python3
# Fibonacci series: 斐波纳契数列
# 两个元素的总和确定了下一个数
= 0, 1
a, b while b < 1000:
print(b, end=',')
= b, a+b a, b
输出结果为
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。
Python 推导式是一种强大且简洁的语法,适用于生成列表、字典、集合和生成器。
在使用推导式时,需要注意可读性,尽量保持表达式简洁,以免影响代码的可读性和可维护性。
Python 支持各种数据结构的推导式:
列表推导式格式为
for 变量 in 列表]
[表达式 for out_exp in input_list]
[out_exp_res
或者
for 变量 in 列表 if 条件]
[表达式 for out_exp in input_list if condition] [out_exp_res
过滤掉长度小于或等于3的字符串列表,并将剩下的转换成大写字母
>>> names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
>>> new_names = [name.upper()for name in names if len(name)>3]
>>> print(new_names)
'ALICE', 'JERRY', 'WENDY', 'SMITH'] [
计算30以内可以被3整除的整数
>>> multiples = [i for i in range(30) if i % 3 == 0]
>>> print(multiples)
0, 3, 6, 9, 12, 15, 18, 21, 24, 27] [
字典推导基本格式
for value in collection }
{ key_expr: value_expr
或
for value in collection if condition } { key_expr: value_expr
使用字符串及其长度创建字典
= ['Google','Runoob', 'Taobao']
listdemo # 将列表中各字符串值为键,各字符串的长度为值,组成键值对
>>> newdict = {key:len(key) for key in listdemo}
>>> newdict
'Google': 6, 'Runoob': 6, 'Taobao': 6} {
提供三个数字,以三个数字为键,三个数字的平方为值来创建字典:
>>> dic = {x: x**2 for x in (2, 4, 6)}
>>> dic
2: 4, 4: 16, 6: 36}
{>>> type(dic)
<class 'dict'>
集合推导式基本格式:
for item in Sequence }
{ expression
或for item in Sequence if conditional } { expression
计算数字1,2,3的平方数
>>> setnew = {i**2 for i in (1,2,3)}
>>> setnew
1, 4, 9} {
判断不是abc字母并输出
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
'd', 'r'}
{>>> type(a)
<class 'set'>
元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。
元组推导式基本格式:
for item in Sequence )
(expression
或for item in Sequence if conditional ) (expression
元组推导式和列表推导式的用法也完全相同,只是元组推导式是用
()
圆括号将各部分括起来,而列表推导式用的是中括号
[]
,另外元组推导式返回的结果是一个生成器对象。
例如,我们可以使用下面的代码生成一个包含数字1~9的元组:
>>> a = (x for x in range(1,10))
>>> a
<generator object <genexpr> at 0x7faf6ee20a50> # 返回的是生成器对象
>>> tuple(a) # 使用 tuple() 函数,可以直接将生成器对象转换成元组
1, 2, 3, 4, 5, 6, 7, 8, 9) (
迭代是 Python 最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>
迭代器对象可以使用常规for语句进行遍历
#!/usr/bin/python3
list=[1,2,3,4]
= iter(list) # 创建迭代器对象
it for x in it:
print (x, end=" ")
执行以上程序,输出结果如下:
1 2 3 4
也可以使用next()函数
#!/usr/bin/python3
import sys # 引入 sys 模块
list=[1,2,3,4]
= iter(list) # 创建迭代器对象
it
while True:
try:
print (next(it))
except StopIteration:
sys.exit()
执行以上程序,输出结果如下
1
2
3
4
把一个类作为一个迭代器使用需要在类中实现两个方法
__iter__()
与 __next__()
。
如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 init(), 它会在对象初始化的时候执行。
__iter__()
方法返回一个特殊的迭代器对象,
这个迭代器对象实现了 __next__()
方法并通过 StopIteration
异常标识迭代的完成。
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
= self.a
x self.a += 1
return x
= MyNumbers()
myclass = iter(myclass)
myiter
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
执行输出结果为:
1
2
3
4
5
StopIteration异常用于标识迭代的完成,防止出现无限循环的情况,在
__next__()
方法中我们可以设置在完成指定循环此输后触发
StopIteration 异常来结束迭代。
在20次迭代后停止执行:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
= self.a
x self.a += 1
return x
else:
raise StopIteration
= MyNumbers()
myclass = iter(myclass)
myiter
for x in myiter:
print(x)
执行输出结果为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。
然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。
调用一个生成器函数,返回的是一个迭代器对象。
下面是一个简单的示例,展示了生成器函数的使用:
def countdown(n):
while n > 0:
yield n
-= 1
n
# 创建生成器对象
= countdown(5)
generator
# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3
# 使用 for 循环迭代生成器
for value in generator:
print(value) # 输出: 2 1
以上实例中,countdown 函数是一个生成器函数。它使用 yield 语句逐步产生从 n 到 1 的倒数数字。在每次调用 yield 语句时,函数会返回当前的倒数值,并在下一次调用时从上次暂停的地方继续执行。
通过创建生成器对象并使用 next() 函数或 for 循环迭代生成器,我们可以逐步获取生成器函数产生的值。在这个例子中,我们首先使用 next() 函数获取前三个倒数值,然后通过 for 循环获取剩下的两个倒数值。
生成器函数的优势是它们可以按需生成值,避免一次性生成大量数据并占用大量内存。此外,生成器还可以与其他迭代工具(如for循环)无缝配合使用,提供简洁和高效的迭代方式。
执行以上程序,输出结果如下:
5
4
3
2
1
以下实例使用yield实现斐波那契数列:
#!/usr/bin/python3
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
= 0, 1, 0
a, b, counter while True:
if (counter > n):
return
yield a
= b, a + b
a, b += 1
counter = fibonacci(10) # f 是一个迭代器,由生成器返回生成
f
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
执行以上程序,输出结果如下:
0 1 1 2 3 5 8 13 21 34 55
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
你可以定义一个由自己想要功能的函数,以下是简单的规则:
return [表达式]
结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回
None。语法
Python定义函数使用def关键字,一般格式如下:
def 函数名(参数列表):
函数体
默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。
实例:
#!/usr/bin/python3
def hello() :
print("Hello World!")
hello()
更复杂点的应用,函数中带上参数变量:
#!/usr/bin/python3
# 比较两个数,并返回较大的数:
def max(a, b):
if a > b:
return a
else:
return b
= 4
a = 5
b print(max(a, b))
# 5
计算面积函数:
#!/usr/bin/python3
# 计算面积函数
def area(width, height):
return width * height
def print_welcome(name):
print("Welcome", name)
"Runoob")
print_welcome(= 4
w = 5
h print("width =", w, " height =", h, " area =", area(w, h))
定义一个函数:给了函数一个名称,指定了函数里包含的参数,和代码块结构。
这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从 Python 命令提示符执行。
如下实例调用了 printme() 函数:
#!/usr/bin/python3
# 定义函数
def printme( str ):
# 打印任何传入的字符串
print (str)
return
# 调用函数
"我要调用用户自定义函数!")
printme("再次调用同一函数") printme(
以上实例输出结果
!
我要调用用户自定义函数 再次调用同一函数
在 python 中,类型属于对象,对象有不同类型的区分,变量是没有类型的:
=[1,2,3]
a
="Runoob" a
以上代码中,[1,2,3]
是 List 类型,“Runoob” 是 String
类型,而变量 a
是没有类型,它仅仅是一个对象的引用(一个指针),可以是指向 List
类型对象,也可以是指向 String 类型对象。
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
la=[1,2,3,4]
后再赋值 la[2]=5 则是将
list la
的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。python 函数的参数传递:
Python中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
通过 id() 函数来查看内存地址变化:
def change(a):
print(id(a)) # 指向的是同一个对象
=10
aprint(id(a)) # 一个新对象
=1
aprint(id(a))
change(a)
以上实例输出结果为:
4379369136
4379369136
4379369424
可以看见在调用函数前后,形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的 id。
可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:
#!/usr/bin/python3
# 可写函数说明
def changeme( mylist ):
"修改传入的列表"
1,2,3,4])
mylist.append([print ("函数内取值: ", mylist)
return
# 调用changeme函数
= [10,20,30]
mylist
changeme( mylist )print ("函数外取值: ", mylist)
传入函数的和在末尾加新内容的对象用的是同一个引用,输出的结果如下:
10, 20, 30, [1, 2, 3, 4]]
函数内取值: [10, 20, 30, [1, 2, 3, 4]] 函数外取值: [
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用 printme() 函数,你必须传入一个参数,不然会出现语法错误:
#!/usr/bin/python3
#可写函数说明
def printme( str ):
"打印任何传入的字符串"
print (str)
return
# 调用 printme 函数,不加参数会报错
printme()
以上实例输出结果:
Traceback (most recent call last):"test.py", line 10, in <module>
File
printme()TypeError: printme() missing 1 required positional argument: 'str'
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 printme() 调用时使用参数名:
#!/usr/bin/python3
#可写函数说明
def printme( str ):
"打印任何传入的字符串"
print (str)
return
#调用printme函数
str = "菜鸟教程") printme(
以下实例中演示了函数参数的使用不需要使用指定顺序:
#!/usr/bin/python3
#可写函数说明
def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
=50, name="runoob" ) printinfo( age
以上实例输出结果:
名字: runoob50 年龄:
调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:
#!/usr/bin/python3
#可写函数说明
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
=50, name="runoob" )
printinfo( ageprint ("------------------------")
="runoob" ) printinfo( name
以上实例输出结果:
名字: runoob50
年龄: ------------------------
名字: runoob35 年龄:
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下:
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suitereturn [expression]
加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
#!/usr/bin/python3
# 可写函数说明
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vartuple)
# 调用printinfo 函数
70, 60, 50 ) printinfo(
以上实例输出结果:
输出:
70
60, 50) (
如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例:
#!/usr/bin/python3
# 可写函数说明
def printinfo( arg1, *vartuple ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
for var in vartuple:
print (var)
return
# 调用printinfo 函数
10 )
printinfo( 70, 60, 50 ) printinfo(
以上实例输出结果:
输出:10
输出:70
60
50
还有一种就是参数带两个星号 **
基本语法如下:
def functionname([formal_args,] **var_args_dict ):
"函数_文档字符串"
function_suitereturn [expression]
#!/usr/bin/python3
# 可写函数说明
def printinfo( arg1, **vardict ):
"打印任何传入的参数"
print ("输出: ")
print (arg1)
print (vardict)
# 调用printinfo 函数
1, a=2,b=3) printinfo(
以上实例输出结果:
输出: 1
'a': 2, 'b': 3} {
声明函数时,参数中星号 *
可以单独出现,例如:
def f(a,b,*,c):
return a+b+c
如果单独出现星号 *
,则星号 *
后的参数必须用关键字传入
>>> def f(a,b,*,c):
return a+b+c
...
... >>> f(1,2,3) # 报错
Traceback (most recent call last):"<stdin>", line 1, in <module>
File TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
>>>
Python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
语法
lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
设置参数a加上10:
= lambda a : a + 10
x print(x(5))
以上实例输出结果:
15
以下实例匿名函数设置两个参数:
#!/usr/bin/python3
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
# 相加后的值为 : 30
print ("相加后的值为 : ", sum( 20, 20 ))
# 相加后的值为 : 40
def myfunc(n):
return lambda a : a * n
= myfunc(2)
mydoubler = myfunc(3)
mytripler
print(mydoubler(11))
# 22
print(mytripler(11))
# 33
return [表达式]
语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return
语句返回 None。之前的例子都没有示范如何返回数值,以下实例演示了 return
语句的用法:
#!/usr/bin/python3
# 可写函数说明
def sum( arg1, arg2 ):
# 返回2个参数的和."
= arg1 + arg2
total print ("函数内 : ", total)
return total
# 调用sum函数
= sum( 10, 20 )
total print ("函数外 : ", total)
以上实例输出结果:
30
函数内 : 30 函数外 :
Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。
在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
以下使用方法是正确的
10, 20, 30, d=40, e=50, f=60) f(
以下使用方法会发生错误
10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式 f(
Python 使用 lambda 来创建匿名函数。
lambda 函数是一种小型、匿名的、内联函数,它可以具有任意数量的参数,但只能有一个表达式。
匿名函数不需要使用 def 关键字定义完整函数。
lambda
函数通常用于编写简单的、单行的函数,通常在需要函数作为参数传递的情况下使用,例如在
map()
、filter()
、reduce()
等函数中。
lambda语法格式:
lambda arguments: expression
以下的lambda函数没有参数:
= lambda: "Hello, world!"
f print(f()) # 输出: Hello, world!
以下实例使用lambda创建匿名函数,设置一个函数参数a,函数计算参数a加10,并返回结果。
= lambda a : a + 10
x print(x(5)) # 15
lambda函数也可以设置多个参数,参数使用逗号,隔开:
以下示例使用lambda创建匿名函数,函数参数a与b相乘,并返回结果。
= lambda a, b : a * b
x print(x(5, 6)) # 30
以下实例使用 lambda 创建匿名函数,函数参数 a、b 与 c 相加,并返回结果:
= lambda a, b, c : a + b + c
x print(x(5, 6, 2)) # 13
lambda 函数通常与内置函数如 map()
、filter()
和 reduce()
一起使用,以便在集合上执行操作。例如:
= [1, 2, 3, 4, 5]
numbers = list(map(lambda x: x**2, numbers))
squared print(squared) # 输出: [1, 4, 9, 16, 25]
使用lambda函数与filter() 一起,筛选偶数
= [1, 2, 3, 4, 5, 6, 7, 8]
numbers = list(filter(lambda x: x % 2 == 0, numbers))
even_numbers print(even_numbers) # 输出:[2, 4, 6, 8]
下面是一个使用reduce()和lambda表达式演示如何计算一个序列的累积乘积:
from functools import reduce
= [1, 2, 3, 4, 5]
numbers
# 使用 reduce() 和 lambda 函数计算乘积
= reduce(lambda x, y: x * y, numbers)
product
print(product) # 输出:120
在上面的实例中,reduce() 函数通过遍历
numbers列表,并使用lambda函数将累积的结果不断更新,最终得到了
1*2*3*4*5=120
的结果。
装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为。
装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数。
->装饰器函数->新函数 原函数
装饰器的语法使用 @decorator_name
来应用在函数或方法上。
Python 还提供了一些内置的装饰器,比如 @staticmethod
和
@classmethod
,用于定义静态方法和类方法。
装饰器的应用场景:
Python 装饰允许在不修改原有函数代码的基础上,动态地增加或修改函数的功能,装饰器本质上是一个接收函数作为输入并返回一个新的包装过后的函数的对象。
def decorator_function(original_function):
def wrapper(*args, **kwargs):
# 这里是在调用原始函数前添加的新功能
before_call_code()
= original_function(*args, **kwargs)
result
# 这里是在调用原始函数后添加的新功能
after_call_code()
return result
return wrapper
# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
pass # 原始函数的实现
解析:decorator 是一个装饰器函数,它接受一个函数 func 作为参数,并返回一个内部函数 wrapper,在 wrapper 函数内部,你可以执行一些额外的操作,然后调用原始函数 func,并返回其结果。
装饰器通过 @
符号应用在函数定义之前,例如:
@time_logger
def target_function():
pass
等同于:
def target_function():
pass
= time_logger(target_function) target_function
这会将 target_function 函数传递给 decorator 装饰器,并将返回的函数重新赋值给 target_function。从而,每次调用 target_function 时,实际上是调用了经过装饰器处理后的函数。
通过装饰器,开发者可以在保持代码整洁的同时,灵活且高效地扩展程序的功能。
以下是一个简单的装饰器示例,它会在函数执行前后打印日志:
def my_decorator(func):
def wrapper():
print("在原函数之前执行")
func()print("在原函数之后执行")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# 输出
# 在原函数之前执行
# Hello!
# 在原函数之后执行
如果原函数需要参数,可以在装饰器的wrapper函数中传递参数:
def my_decorator(func):
def wrapper(*args, **kwargs):
print("在原函数之前执行")
*args, **kwargs)
func(print("在原函数之后执行")
return wrapper
@my_decorator
def greet(name):
print(f"Hello, {name}!")
"Alice")
greet(
# 输出:
# 在原函数之前执行
# Hello, Alice!
# 在原函数之后执行
以上代码代码定义了一个装饰器 my_decorator,它会在被装饰的函数执行前后分别打印一条消息。装饰器通过 wrapper 函数包裹原函数,并在调用原函数前后添加额外操作。
装饰器本身也可以接受参数,此时需要额外定义一个外层函数:
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
*args, **kwargs)
func(return wrapper
return decorator
@repeat(3)
def say_hello():
print("Hello!")
say_hello()
# Hello!
# Hello!
# Hello!
repeat 函数是一个装饰器工厂,它接受一个参数 num_times,返回一个装饰器
decorator。decorator 接受一个函数 func,并返回一个 wrapper 函数。wrapper
函数会调用 func 函数 num_times 次。使用 @repeat(3)
装饰s
ay_hell 函数后,调用 say_hello 会打印 “Hello!” 三次。
除了函数装饰器,Python 还支持类装饰器。类装饰器是包含
__call__
方法的类,它接受一个函数作为参数,并返回一个新的函数。
def my_decorator(cls):
class Wrapper:
def __init__(self, *args, **kwargs):
self.wrapped = cls(*args, **kwargs)
def display(self):
print("在类方法之前执行")
self.wrapped.display()
print("在类方法之后执行")
return Wrapper
@my_decorator
class MyClass:
def display(self):
print("这是 MyClass 的 display 方法")
= MyClass()
obj
obj.display()
# 在类方法之前执行
# 这是 MyClass 的 display 方法
# 在类方法之后执行
Python 提供了一些内置的装饰器,例如:
@staticmethod
:
将方法定义为静态方法,不需要实例化类即可调用。@classmethod
:
将方法定义为类方法,第一个参数是类本身(通常命名为 cls)。@property
:
将方法转换为属性,使其可以像属性一样访问。class MyClass:
@staticmethod
def static_method():
print("This is a static method.")
@classmethod
def class_method(cls):
print(f"This is a class method of {cls.__name__}.")
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
# 使用
MyClass.static_method()
MyClass.class_method()
= MyClass()
obj = "Alice"
obj.name print(obj.name)
你可以将多个装饰器堆叠在一起,它们会按照从下到上的顺序依次应用。例如:
def decorator1(func):
def wrapper():
print("Decorator 1")
func()return wrapper
def decorator2(func):
def wrapper():
print("Decorator 2")
func()return wrapper
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
输出
1
Decorator 2
Decorator ! Hello
本章节我们主要结合前面所学的知识点来介绍Python数据结构。
Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能。
以下是 Python 中列表的方法:
方法 | 描述 |
---|---|
list.append(x) |
把一个元素添加到列表的结尾,相当于
a[len(a):] = [x] 。 |
list.extend(L) |
通过添加指定列表的所有元素来扩充列表,相当于
a[len(a):] = L 。 |
list.insert(i, x) |
在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如
a.insert(0, x) 会插入到整个列表之前,而
a.insert(len(a), x) 相当于 a.append(x) 。 |
list.remove(x) |
删除列表中值为 x
的第一个元素。如果没有这样的元素,就会返回一个错误。 |
list.pop([i]) |
从列表的指定位置移除元素,并将其返回。如果没有指定索引,a.pop()
返回最后一个元素。元素随即从列表中被移除。(方法中 i
两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在
Python 库参考手册中遇到这样的标记。) |
list.clear() |
移除列表中的所有项,等于 del a[:] 。 |
list.index(x) |
返回列表中第一个值为 x
的元素的索引。如果没有匹配的元素就会返回一个错误。 |
list.count(x) |
返回 x 在列表中出现的次数。 |
list.sort() |
对列表中的元素进行排序。 |
list.reverse() |
倒排列表中的元素。 |
list.copy() |
返回列表的浅复制,等于 a[:] 。 |
下面示例演示了列表的大部分方法:
>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print(a.count(333), a.count(66.25), a.count('x'))
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
66.25, 333, -1, 333, 1, 1234.5, 333]
[>>> a.index(333)
1
>>> a.remove(333)
>>> a
66.25, -1, 333, 1, 1234.5, 333]
[>>> a.reverse()
>>> a
333, 1234.5, 1, 333, -1, 66.25]
[>>> a.sort()
>>> a
-1, 1, 66.25, 333, 333, 1234.5] [
注意:类似 insert, remove 或 sort 等修改列表的方法没有返回值。
在 Python
中,可以使用列表(list)来实现栈的功能。栈是一种后进先出(LIFO,
Last-In-First-Out)数据结构,意味着最后添加的元素最先被移除。列表提供了一些方法,使其非常适合用于栈操作,特别是
append()
和 pop()
方法。
用 append()
方法可以把一个元素添加到栈顶,用不指定索引的
pop()
方法可以把一个元素从栈顶释放出来。
栈操作:
以下是如何在Python中使用列表实现这些操作的详细说明:
= [] stack
使用 append() 方法将元素添加到栈的顶端:
1)
stack.append(2)
stack.append(3)
stack.append(print(stack) # 输出: [1, 2, 3]
使用 pop() 方法移除并返回栈顶元素:
= stack.pop()
top_element print(top_element) # 输出: 3
print(stack) # 输出: [1, 2]
直接访问列表的最后一个元素(不移除):
= stack[-1]
top_element print(top_element) # 输出: 2
检查列表是否为空
= len(stack) == 0
is_empty print(is_empty) # 输出: False
使用 len() 函数获取栈中元素的数量:
= len(stack)
size print(size) # 输出: 2
以下是一个完整的实例,展示了如何使用上述操作来实现一个简单的栈:
class Stack:
def __init__(self):
self.stack = []
def push(self, item):
self.stack.append(item)
def pop(self):
if not self.is_empty():
return self.stack.pop()
else:
raise IndexError("pop from empty stack")
def peek(self):
if not self.is_empty():
return self.stack[-1]
else:
raise IndexError("peek from empty stack")
def is_empty(self):
return len(self.stack) == 0
def size(self):
return len(self.stack)
# 使用示例
= Stack()
stack 1)
stack.push(2)
stack.push(3)
stack.push(
print("栈顶元素:", stack.peek()) # 输出: 栈顶元素: 3
print("栈大小:", stack.size()) # 输出: 栈大小: 3
print("弹出元素:", stack.pop()) # 输出: 弹出元素: 3
print("栈是否为空:", stack.is_empty()) # 输出: 栈是否为空: False
print("栈大小:", stack.size()) # 输出: 栈大小: 2
以上代码中,我们定义了一个 Stack 类,封装了列表作为底层数据结构,并实现了栈的基本操作。
在 Python 中,列表(list)可以用作队列(queue),但由于列表的特点,直接使用列表来实现队列并不是最优的选择。
队列是一种先进先出(FIFO, First-In-First-Out)的数据结构,意味着最早添加的元素最先被移除。
使用列表时,如果频繁地在列表的开头插入或删除元素,性能会受到影响,因为这些操作的时间复杂度是 O(n)。为了解决这个问题,Python 提供了 collections.deque,它是双端队列,可以在两端高效地添加和删除元素。
collections.deque 是 Python 标准库的一部分,非常适合用于实现队列。
以下是使用 deque 实现队列的示例:
from collections import deque
# 创建一个空队列
= deque()
queue
# 向队尾添加元素
'a')
queue.append('b')
queue.append('c')
queue.append(
print("队列状态:", queue) # 输出: 队列状态: deque(['a', 'b', 'c'])
# 从队首移除元素
= queue.popleft()
first_element print("移除的元素:", first_element) # 输出: 移除的元素: a
print("队列状态:", queue) # 输出: 队列状态: deque(['b', 'c'])
# 查看队首元素(不移除)
= queue[0]
front_element print("队首元素:", front_element) # 输出: 队首元素: b
# 检查队列是否为空
= len(queue) == 0
is_empty print("队列是否为空:", is_empty) # 输出: 队列是否为空: False
# 获取队列大小
= len(queue)
size print("队列大小:", size) # 输出: 队列大小: 2
虽然 deque更高效,但如果坚持使用列表来实现队列,也可以这么做。以下是如何使用列表实现队列的示例:
# 1. 创建队列
= []
queue
# 2. 向队尾添加元素
# 使用 append() 方法将元素添加到队尾:
'a')
queue.append('b')
queue.append('c')
queue.append(print("队列状态:", queue) # 输出: 队列状态: ['a', 'b', 'c']
# 3. 从队首移除元素
# 使用 pop(0) 方法从队首移除元素:
= queue.pop(0)
first_element print("移除的元素:", first_element) # 输出: 移除的元素: a
print("队列状态:", queue) # 输出: 队列状态: ['b', 'c']
# 4. 查看队首元素(不移除)
# 直接访问列表的第一个元素:
= queue[0]
front_element print("队首元素:", front_element) # 输出: 队首元素: b
# 5. 检查队列是否为空
# 检查列表是否为空:
= len(queue) == 0
is_empty print("队列是否为空:", is_empty) # 输出: 队列是否为空: False
# 6. 获取队列大小
# 使用 len() 函数获取队列的大小:
= len(queue)
size print("队列大小:", size) # 输出: 队列大小: 2
实例(使用列表实现队列)
class Queue:
def __init__(self):
self.queue = []
def enqueue(self, item):
self.queue.append(item)
def dequeue(self):
if not self.is_empty():
return self.queue.pop(0)
else:
raise IndexError("dequeue from empty queue")
def peek(self):
if not self.is_empty():
return self.queue[0]
else:
raise IndexError("peek from empty queue")
def is_empty(self):
return len(self.queue) == 0
def size(self):
return len(self.queue)
# 使用示例
= Queue()
queue 'a')
queue.enqueue('b')
queue.enqueue('c')
queue.enqueue(
print("队首元素:", queue.peek()) # 输出: 队首元素: a
print("队列大小:", queue.size()) # 输出: 队列大小: 3
print("移除的元素:", queue.dequeue()) # 输出: 移除的元素: a
print("队列是否为空:", queue.is_empty()) # 输出: 队列是否为空: False
print("队列大小:", queue.size()) # 输出: 队列大小: 2
虽然可以使用列表来实现队列,但使用 collections.deque
会更高效和简洁。它提供了 O(1)
时间复杂度的添加和删除操作,非常适合队列这种数据结构。
列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。
每个列表推导式都在 for 之后跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。
这里我们将列表中每个数值乘三,获得一个新的列表:
>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
6, 12, 18] [
现在我们玩一点小花样:
>>> [[x, x**2] for x in vec]
2, 4], [4, 16], [6, 36]] [[
这里我们对序列里每一个元素逐个调用某方法:
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
'banana', 'loganberry', 'passion fruit'] [
我们可以用if子句作为过滤器:
>>> [3*x for x in vec if x > 3]
12, 18]
[>>> [3*x for x in vec if x < 2]
[]
以下是一些关于循环和其它技巧的演示:
>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
8, 6, -18, 16, 12, -36, 24, 18, -54]
[>>> [x+y for x in vec1 for y in vec2]
6, 5, -7, 8, 7, -5, 10, 9, -3]
[>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
8, 12, -54] [
列表推导式可以使用复杂表达式或嵌套函数:
>>> [str(round(355/113, i)) for i in range(1, 6)]
'3.1', '3.14', '3.142', '3.1416', '3.14159'] [
Python的列表还可以嵌套。
以下实例展示了3X4的矩阵列表:
>>> matrix = [
1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... [ ... ]
以下实例将3X4的矩阵列表转换为4X3列表:
>>> [[row[i] for row in matrix] for i in range(4)]
1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] [[
以上实例也可以使用以下方法来实现:
>>> transposed = []
>>> for i in range(4):
for row in matrix])
... transposed.append([row[i]
...>>> transposed
1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] [[
另外一种实现方法(说实话我更喜欢最原始的方式):
在工程中看似上面语法糖写时很简单,但是其他人看代码时需要思考的时间大大增加。
>>> transposed = []
>>> for i in range(4):
# the following 3 lines implement the nested listcomp
... = []
... transposed_row for row in matrix:
...
... transposed_row.append(row[i])
... transposed.append(transposed_row)
...>>> transposed
1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] [[
使用 del 语句可以从一个列表中根据索引来删除一个元素,而不是值来删除元素。这与使用 pop() 返回一个值不同。可以用 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
[]
也可以用del删除实体变量
>>> del a
元组由若干逗号分隔的值组成,例如:
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
12345, 54321, 'hello!')
(>>> # Tuples may be nested:
= t, (1, 2, 3, 4, 5)
... u >>> u
12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) ((
如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号, 不过括号通常是必须的(如果元组是更大的表达式的一部分)。
集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。
可以用大括号({})
创建集合。注意:如果要创建一个空集合,你必须用
set()
而不是 {}
;后者创建一个空的字典,下一节我们会介绍这个数据结构。
以下是一个简单的演示:
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # 删除重复的
'orange', 'banana', 'pear', 'apple'}
{>>> 'orange' in basket # 检测成员
True
>>> 'crabgrass' in basket
False
>>> # 以下演示了两个集合的操作
...>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # a 中唯一的字母
'a', 'r', 'b', 'c', 'd'}
{>>> a - b # 在 a 中的字母,但不在 b 中
'r', 'd', 'b'}
{>>> a | b # 在 a 或 b 中的字母
'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
{>>> a & b # 在 a 和 b 中都有的字母
'a', 'c'}
{>>> a ^ b # 在 a 或 b 中的字母,但不同时在 a 和 b 中
'r', 'd', 'b', 'm', 'z', 'l'} {
集合也支持推导式:
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
'r', 'd'} {
另一个非常有用的 Python 内建数据类型是字典。
序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。
理解字典的最佳方式是把它看做无序的键=>值对集合。在同一个字典之内,关键字必须是互不相同。
一对大括号创建一个空的字典:{}
。
这是一个字典运用的简单例子:
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
'sape': 4139, 'guido': 4127, 'jack': 4098}
{>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
'guido': 4127, 'irv': 4127, 'jack': 4098}
{>>> list(tel.keys())
'irv', 'guido', 'jack']
[>>> sorted(tel.keys())
'guido', 'irv', 'jack']
[>>> 'guido' in tel
True
>>> 'jack' not in tel
False
构造函数 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} {
如果关键字只是简单的字符串,使用关键字参数指定键值对有时候更方便:
>>> dict(sape=4139, guido=4127, jack=4098)
'sape': 4139, 'jack': 4098, 'guido': 4127} {
在字典中遍历时,关键字和对应的值可以使用 items()
方法同时解读出来:
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
print(k, v)
...
...
gallahad the pure robin the brave
在序列中遍历时,索引位置和对应值可以使用 enumerate()
函数同时得到:
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)
...
...0 tic
1 tac
2 toe
同时遍历两个或多个的序列,可以使用 zip()
组合:
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
print('What is your {0}? It is {1}.'.format(q, a))
...
...is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue. What
要反向遍历一个序列,首先指定这个序列,然后调用
reversed()
函数:
>>> for i in reversed(range(1, 10, 2)):
print(i)
...
...9
7
5
3
1
要按顺序遍历一个序列,使用 sorted()
函数返回一个已排序的序列,并不修改原值:
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
print(f)
...
...
apple
banana
orange pear
在前面的几个章节中我们基本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。
为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
Python 中的模块(Module)是一个包含 Python 定义和语句的文件,文件名就是模块名加上 .py 后缀。
模块可以包含函数、类、变量以及可执行的代码。通过模块,我们可以将代码组织成可重用的单元,便于管理和维护。
下面是一个使用python标准库中模块的例子:
#!/usr/bin/python3
# 文件名: using_sys.py
import sys
print('命令行参数如下:')
for i in sys.argv:
print(i)
print('\n\nPython 路径为:', sys.path, '\n')
想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下:
import module1[, module2[,... moduleN]
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
搜索路径时一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support,需要把命令放在脚本的顶端:
#!/usr/bin/python3
# Filename: support.py
def print_func( par ):
print ("Hello : ", par)
return
test.py 引入 support 模块:
#!/usr/bin/python3
# Filename: test.py
# 导入模块
import support
# 现在可以调用模块里包含的函数了
"Runoob") support.print_func(
以上实例输出结果:
$ python3 test.py
Hello : Runoob
一个模块只会被导入一次
,不管你执行了多少次
import。这样可以防止导入模块被一遍又一遍地执行。
当我们使用 import 语句的时候,Python 解释器是怎样找到对应的文件的呢?
这就涉及到 Python 的搜索路径,搜索路径是由一系列目录名组成的,Python 解释器就依次从这些目录中去寻找所引入的模块。
当导入一个模块时,Python会按照以下顺序查找模块:
.pth
文件中指定的目录。搜索路径是在 Python 编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在 sys 模块中的 path 变量,做一个简单的实验,在交互式解释器中,输入以下代码:
>>> import sys
>>> sys.path
'', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
[>>>
sys.path
输出是一个列表,其中第一项是空串
’’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行
python 解释器的目录(对于脚本的话就是运行的脚本所在的目录)。
因此若像我一样在当前目录下存在与要引入模块同名的文件,就会把要引入的模块屏蔽掉。
了解了搜索路径的概念,就可以在脚本中修改 sys.path
来引入一些不在搜索路径中的模块。
现在,在解释器的当前目录或者 sys.path
中的一个目录里面来创建一个 fibo.py
的文件,代码如下:
# 斐波那契(fibonacci)数列模块
def fib(n): # 定义到 n 的斐波那契数列
= 0, 1
a, b while b < n:
print(b, end=' ')
= b, a+b
a, b print()
def fib2(n): # 返回到 n 的斐波那契数列
= []
result = 0, 1
a, b while b < n:
result.append(b)= b, a+b
a, b return result
然后进入Python解释器,使用下面的命令导入这个模块:
>>> import fibo
这样做并没有把直接定义在fibo中的函数名称写入到当前符号表里,只是把模块fibo的名字写到了那里。
可以使用模块名称来访问函数:
>>>fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
[>>> fibo.__name__
'fibo'
如果你打算经常使用一个函数,你可以把它赋给一个本地的名称:
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块fibo的fib函数,使用如下语句:
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
这个声明不会把整个fibo模块导入当前的命名空间,它只会将fibo里的fib函数引入进来。
使用 as 关键字为模块或函数起别名:
import numpy as np # 将 numpy 模块别名设置为 np
from math import sqrt as square_root # 将 sqrt 函数别名设置为 square_root
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
from modname import *
这提供了一个简单的方法来导入一个模块中的所有项目。
不推荐,容易引起命名冲突
模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。
每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。
所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞混。
从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。
模块是可以导入其他模块的。在一个模块(或者脚本,或者其他地方)的最前面使用 import 来导入一个模块,当然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。
还有一种导入的方法,可以使用 import 直接把模块内(函数,变量的)名称导入到当前操作模块。比如:
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
这种导入的方法不会把被导入的模块的名称放在当前的字符表中(所以在这个例子里面,fibo 这个名称是没有定义的)。
这还有一种方法,可以一次性的把模块中的所有(函数,变量)名称都导入到当前模块的字符表:
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
这将把所有的名字都导入进来,但是那些由单一下划线(_)
开头的名字不在此例。大多数情况,
Python程序员不使用这种方法,因为引入的其它来源的命名,很可能覆盖了已有的定义。
__name__
属性一个模块被另一个程序第一次引入时,其主程序将运行。
如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用
__name__
属性来使该程序块仅在该模块自身运行时执行。
#!/usr/bin/python3
# Filename: using_name.py
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')
运行输出如下:
$ python using_name.py 程序自身在运行
$ python>>> import using_name
我来自另一模块>>>
说明:每个模块都有一个 __name__
属性。
__name__
的值为
__main__
。__name__
的值为模块名。内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:
>>> import fibo, sys
>>> dir(fibo)
'__name__', 'fib', 'fib2']
[>>> dir(sys)
'__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
['__package__', '__stderr__', '__stdin__', '__stdout__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
'_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
'call_tracing', 'callstats', 'copyright', 'displayhook',
'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
'thread_info', 'version', 'version_info', 'warnoptions']
如果没有给定参数,那么dir()
函数会罗列出当前定义的所有名称。
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 得到一个当前模块中定义的属性列表
'__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
[>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
'__builtins__', '__doc__', '__name__', 'a', 'sys']
[>>>
>>> del a # 删除变量名a
>>>
>>> dir()
'__builtins__', '__doc__', '__name__', 'sys']
[>>>
Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的”库参考文档”)。
模块名 | 功能描述 |
---|---|
math |
数学运算(如平方根、三角函数等) |
os |
操作系统相关功能(如文件、目录操作) |
sys |
系统相关的参数和函数 |
random |
生成随机数 |
datetime |
处理日期和时间 |
json |
处理 JSON 数据 |
re |
正则表达式操作 |
collections |
提供额外的数据结构(如 defaultdict、deque) |
itertools |
提供迭代器工具 |
functools |
高阶函数工具(如 reduce、lru_cache) |
有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。
这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。
应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
> print('Runoob!')
C!
Runoob> C
包是一种管理 Python 模块命名空间的形式,采用”点模块名称”。
比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。
就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。
这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。
不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个”包”)。
现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。
并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。
这里给出了一种可能的包结构(在分层的文件系统中):
/ 顶层包
sound__init__.py 初始化 sound 包
/ 文件格式转换子包
formats__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
.../ 声音效果子包
effects__init__.py
echo.py
surround.py
reverse.py
.../ filters 子包
filters__init__.py
equalizer.py
vocoder.py
karaoke.py ...
在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。
目录只有包含一个叫做 __init__.py
的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做
string)不小心的影响搜索路径中的有效模块。
最简单的情况,放一个空的 :file:__init__.py
就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的)
__all__
变量赋值。
用户可以每次只导入一个包里面的特定模块,比如:
import sound.effects.echo
这将会导入子模块:sound.effects.echo。 他必须使用全名去访问:
input, output, delay=0.7, atten=4) sound.effects.echo.echofilter(
还有一种导入子模块的方法是:
from sound.effects import echo
这同样会导入子模块: echo,并且他不需要那些冗长的前缀,所以他可以这样使用:
input, output, delay=0.7, atten=4) echo.echofilter(
还有一种变化就是直接导入一个函数或者变量:
from sound.effects.echo import echofilter
同样的,这种方法会导入子模块:echo,并且可以直接使用他的 echofilter() 函数:
input, output, delay=0.7, atten=4) echofilter(
注意当使用 from package import item
这种形式的时候,对应的 item
既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
import 语法会首先把 item
当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,抛出一个
:exc:ImportError
异常。
反之,如果使用形如 import item.subitem.subsubitem
这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。
*
如果我们使用 from sound.effects import *
会发生什么呢?
Python 会进入文件系统,找到这个包里面所有的子模块,然后一个一个的把它们都导入进来。
但这个方法在 Windows 平台上工作的就不是非常好,因为 Windows 是一个不区分大小写的系统。
在 Windows 平台上,我们无法确定一个叫做 ECHO.py 的文件导入为模块是 echo 还是 Echo,或者是 ECHO。
为了解决这个问题,我们只需要提供一个精确包的索引。
导入语句遵循如下规则:如果包定义文件 __init__.py
存在一个叫做 __all__
的列表变量,那么在使用
from package import *
的时候就把这个列表中的所有名字作为包内容导入。
作为包的作者,可别忘了在更新包之后保证 __all__
也更新了啊。
以下实例在 file:sounds/effects/__init__.py
中包含如下代码:
= ["echo", "surround", "reverse"] __all__
这表示当你使用from sound.effects import *
这种用法时,你只会导入包里面这三个子模块。
如果 __all__
真的没有定义,那么使用from sound.effects import *
这种语法的时候,就不会导入包sound.effects
里的任何子模块。他只是把包sound.effects
和它里面定义的所有内容导入进来(可能运行__init__.py
里定义的初始化代码)。
这会把 __init__.py
里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块。看下这部分代码:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
这个例子中,在执行 from...import
前,包 sound.effects
中的 echo 和 surround 模块都被导入到当前的命名空间中了。(当然如果定义了
__all__
就更没问题了)
通常我们并不主张使用 *
这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫,而且一些模块都设计成了只能通过特定的方法导入。
记住,使用 from Package import specific_submodule
这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。
如果在结构中包是一个子包(比如这个例子中对于包sound来说),而你又想导入兄弟包(同级别的包)你就得使用导入绝对的路径来导入。比如,如果模块sound.filters.vocoder 要使用包 sound.effects 中的模块 echo,你就要写成 from sound.effects import echo。
from . import echo
from .. import formats
from ..filters import equalizer
无论是隐式的还是显式的相对导入都是从当前模块开始的。主模块的名字永远是__main__
,一个Python应用程序的主模块,应当总是使用绝对路径引用。
包还提供一个额外的属性__path__
。这是一个目录列表,里面每一个包含的目录都有为这个包服务的__init__.py
,你得在其他__init__.py
被执行前定义哦。可以修改这个变量,用来影响包含在包里面的模块和子包。
这个功能并不常用,一般用来扩展包里面的模块。
__name__
平时我们经常会看到这样的 Python 代码:
if __name__ == "__main__":
main()
在 Python 中,__name__
和 __main__
是两个与模块和脚本执行相关的特殊变量。
__name__
和 __main__
通常用于控制代码的执行方式,尤其是在模块既可以作为独立脚本运行,也可以被其他模块导入时。
__name__
变量__name__
是一个内置变量,用于表示当前模块的名称。
__name__
的值取决于模块是如何被使用的:
当模块作为主程序运行时:__name__
的值被设置为
"__main__"
。
当模块被导入时:__name__
的值被设置为模块的文件名(不包括 .py 扩展名)。
假设有一个module.py文件:
print(f"模块的 __name__ 值: {__name__}")
输出
__name__ 值: __main__ 模块的
__main__
的含义__main__
是一个特殊的字符串,用于表示当前模块是作为主程序运行的。
__main__
通常与 __name__
变量一起使用,以确定模块是被导入还是作为独立脚本运行。
if __name__ == "__main__"
: 的常见模式在 Python 中,常见的做法是在模块的末尾添加以下代码块:
if __name__ == "__main__":
# 这里的代码只有在模块作为主程序运行时才会执行
main()
这种模式允许模块在被导入时不会执行某些代码,而只有在作为独立脚本运行时才会执行这些代码。
在前面几个章节中,我们其实已经接触了 Python 的输入输出的功能。本章节我们将具体介绍 Python 的输入输出。
Python两种输出值的方式: 表达式语句和 print() 函数。
第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用。
如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。
如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。
str(): 函数返回一个用户易读的表达形式。 repr(): 产生一个解释器易读的表达形式。
>>> s = 'Hello, Runoob'
>>> str(s)
'Hello, Runoob'
>>> repr(s)
"'Hello, Runoob'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x 的值为: ' + repr(x) + ', y 的值为:' + repr(y) + '...'
>>> print(s)
32.5, y 的值为:40000...
x 的值为: >>> # repr() 函数可以转义字符串中的特殊字符
= 'hello, runoob\n'
... hello >>> hellos = repr(hello)
>>> print(hellos)
'hello, runoob\n'
>>> # repr() 的参数可以是 Python 的任何对象
repr((x, y, ('Google', 'Runoob')))
... "(32.5, 40000, ('Google', 'Runoob'))"
这里有两种方式输出一个平方与立方的表:
>>> for x in range(1, 11):
print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
... # 注意前一行 '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 100 1000
>>> 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() 添加。
这个例子展示了字符串对象的 rjust() 方法, 它可以将字符串靠右, 并在左边填充空格。
还有类似的方法, 如 ljust() 和 center()。 这些方法并不会写任何东西, 它们仅仅返回新的字符串。
另一个方法 zfill(), 它会在数字的左边填充 0,如下所示:
>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'
str.format() 的基本使用如下:
>>> print('{}网址: "{}!"'.format('菜鸟教程', 'www.runoob.com'))
"www.runoob.com!" 菜鸟教程网址:
括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。
在括号中的数字用于指向传入对象在 format() 中的位置,如下所示:
>>> print('{0} 和 {1}'.format('Google', 'Runoob'))
Google 和 Runoob>>> print('{1} 和 {0}'.format('Google', 'Runoob'))
Runoob 和 Google
如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。
>>> print('{name}网址: {site}'.format(name='菜鸟教程', site='www.runoob.com'))
菜鸟教程网址: www.runoob.com
位置及关键字参数可以任意的结合:
>>> print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao'))
站点列表 Google, Runoob, 和 Taobao。
!a
(使用 ascii()), !s
(使用 str()) 和
!r
(使用 repr())
可以用于在格式化某个值之前对其进行转化:
>>> import math
>>> print('常量 PI 的值近似为: {}。'.format(math.pi))
3.141592653589793。
常量 PI 的值近似为: >>> print('常量 PI 的值近似为: {!r}。'.format(math.pi))
3.141592653589793。 常量 PI 的值近似为:
可选项 : 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位:
>>> import math
>>> print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
3.142。 常量 PI 的值近似为
在 : 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
print('{0:10} ==> {1:10d}'.format(name, number))
...
... ==> 1
Google ==> 2
Runoob ==> 3 Taobao
如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。
最简单的就是传入一个字典, 然后使用方括号 []
来访问键值
:
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
2; Google: 1; Taobao: 3 Runoob:
也可以通过在 table 变量前使用 **
来实现相同的功能:
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
2; Google: 1; Taobao: 3 Runoob:
%
操作符也可以实现字符串格式化。 它将左边的参数作为类似
sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串.
例如:
>>> import math
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
3.142。 常量 PI 的值近似为:
因为 str.format() 是比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().
Python 提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘。
#!/usr/bin/python3
str = input("请输入:");
print ("你输入的内容是: ", str)
这会产生如下的对应着输入的结果:
请输入:菜鸟教程 你输入的内容是: 菜鸟教程
open() 将会返回一个 file 对象,基本语法格式如下:
open(filename, mode)
不同模式打开文件的完全列表:
模式 | 描述 |
---|---|
r |
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb |
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。 |
r+ |
打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ |
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w |
打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb |
以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ |
打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ |
以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a |
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ |
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ |
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
以下实例将字符串写入到文件 foo.txt 中:
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo.txt", "w")
f
"Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
f.write(
# 关闭打开的文件
f.close()
此时打开文件 foo.txt 显示如下:
/tmp/foo.txt
$ cat
Python 是一个非常好的语言。!! 是的,的确非常好
本节中剩下的例子假设已经创建了一个称为 f 的文件对象。
f.read()
为了读取一个文件的内容,调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。
size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。
以下实例假定文件 foo.txt 已存在(上面实例中已创建):
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo.txt", "r")
f
str = f.read()
print(str)
# 关闭打开的文件
f.close()
# Python 是一个非常好的语言。
# 是的,的确非常好!!
f.readline()
f.readline() 会从文件中读取单独的一行。换行符为 ‘’。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo.txt", "r")
f
str = f.readline()
print(str)
# 关闭打开的文件
f.close()
f.readlines()
f.readlines() 将返回该文件中包含的所有行。
如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo.txt", "r")
f
str = f.readlines()
print(str)
# 关闭打开的文件
f.close()# ['Python 是一个非常好的语言。\n', '是的,的确非常好!!\n']
另一种方式是迭代一个文件对象然后读取每行:
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo.txt", "r")
f
for line in f:
print(line, end='')
# 关闭打开的文件
f.close()
f.write()
f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo.txt", "w")
f
= f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
num print(num)
# 关闭打开的文件
f.close()
如果要写入一些不是字符串的东西, 那么将需要先进行转换:
#!/usr/bin/python3
# 打开一个文件
= open("/tmp/foo1.txt", "w")
f
= ('www.runoob.com', 14)
value = str(value)
s
f.write(s)
# 关闭打开的文件
f.close()
f.tell()
f.tell() 用于返回文件当前的读/写位置(即文件指针的位置)。文件指针表示从文件开头开始的字节数偏移量。f.tell() 返回一个整数,表示文件指针的当前位置。
f.seek()
如果要改变文件指针当前的位置, 可以使用 f.seek(offset, from_what) 函数。
f.seek(offset, whence) 用于移动文件指针到指定位置。
offset 表示相对于 whence 参数的偏移量,from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:
from_what 值为默认为0,即文件开头。下面给出一个完整的例子:
>>> f = open('/tmp/foo.txt', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5) # 移动到文件的第六个字节
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # 移动到文件的倒数第三字节
13
>>> f.read(1)
b'd'
f.close()
在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。
当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常。
>>> f.close()
>>> f.read()
Traceback (most recent call last):"<stdin>", line 1, in ?
File ValueError: I/O operation on closed file
当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:
>>> with open('/tmp/foo.txt', 'r') as f:
= f.read()
... read_data >>> f.closed
True
文件对象还有其他方法, 如 isatty() 和 trucate(), 但这些通常比较少用。
python的pickle模块实现了基本的数据序列和反序列化。
通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
基本接口:
file, [,protocol]) pickle.dump(obj,
有了pickle这个对象, 就能对 file 以读取的形式打开:
= pickle.load(file) x
注解:从 file 中读取一个字符串,并将它重构为原来的python对象。
file: 类文件对象,有read()和readline()接口。
#!/usr/bin/python3
import pickle
# 使用pickle模块将数据对象保存到文件
= {'a': [1, 2.0, 3, 4+6j],
data1 'b': ('string', u'Unicode string'),
'c': None}
= [1, 2, 3]
selfref_list
selfref_list.append(selfref_list)
= open('data.pkl', 'wb')
output
# Pickle dictionary using protocol 0.
pickle.dump(data1, output)
# Pickle the list using the highest protocol available.
-1)
pickle.dump(selfref_list, output,
output.close()
#!/usr/bin/python3
import pprint, pickle
#使用pickle模块从文件中重构python对象
= open('data.pkl', 'rb')
pkl_file
= pickle.load(pkl_file)
data1
pprint.pprint(data1)
= pickle.load(pkl_file)
data2
pprint.pprint(data2)
pkl_file.close()
Python open()
方法用于打开一个文件,并返回文件对象。
在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
注意:使用 open()
方法一定要保证关闭文件对象,即调用
close()
方法。
open()
函数常用形式是接收两个参数:文件名(file)和模式(mode)。
open(file, mode='r')
完整的语法格式为:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数说明:
mode参数有:
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(Python 3 不支持)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
默认为文本模式,如果要以二进制模式打开,加上 b 。
file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:
序号 | 方法及描述 |
---|---|
1 | file.close() 关闭文件。关闭后文件不能再进行读写操作。 |
2 | file.flush() 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件,而不是被动的等待输出缓冲区写入。 |
3 | file.fileno() 返回一个整型的文件描述符(file descriptor FD 整型),可以用在如os模块的read方法等一些底层操作上。 |
4 | file.isatty() 如果文件连接到一个终端设备返回 True,否则返回 False。 |
5 | file.next() Python 3 中的 File 对象不支持 next() 方法。 返回文件下一行。 |
6 | file.read([size]) 从文件读取指定的字节数,如果未给定或为负则读取所有。 |
7 | file.readline([size]) 读取整行,包括 “” 字符。 |
8 | file.readlines([sizeint]) 读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行,实际读取值可能比 sizeint 较大,因为需要填充缓冲区。 |
9 | file.seek(offset[, whence]) 移动文件读取指针到指定位置。 |
10 | file.tell() 返回文件当前位置。 |
11 | file.truncate([size]) 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 windows 系统下的换行代表2个字符大小。 |
12 | file.write(str) 将字符串写入文件,返回的是写入的字符长度。 |
13 | file.writelines(sequence) 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 |
os 模块是 Python 标准库中的一个重要模块,它提供了与操作系统交互的功能。
通过 os 模块,你可以执行文件操作、目录操作、环境变量管理、进程管理等任务。
os 模块是跨平台的,这意味着你可以在不同的操作系统(如 Windows、Linux、macOS)上使用相同的代码。
在使用 os 模块之前,你需要先导入它。导入 os 模块的代码如下:
import os
os.getcwd() 函数用于获取当前工作目录的路径。当前工作目录是 Python 脚本执行时所在的目录。
= os.getcwd()
current_directory print("当前工作目录:", current_directory)
os.chdir(path) 函数用于改变当前工作目录。path 是你想要切换到的目录路径。
"/path/to/new/directory")
os.chdir(print("新的工作目录:", os.getcwd())
os.listdir(path) 函数用于列出指定目录中的所有文件和子目录。如果不提供 path 参数,则默认列出当前工作目录的内容。
= os.listdir()
files_and_dirs print("目录内容:", files_and_dirs)
os.mkdir(path) 函数用于创建一个新的目录。如果目录已经存在,会抛出 FileExistsError 异常。
"new_directory") os.mkdir(
os.rmdir(path) 函数用于删除一个空目录。如果目录不为空,会抛出 OSError 异常。
"new_directory") os.rmdir(
os.remove(path) 函数用于删除一个文件。如果文件不存在,会抛出 FileNotFoundError 异常。
"file_to_delete.txt") os.remove(
os.rename(src, dst) 函数用于重命名文件或目录。src 是原始路径,dst 是新的路径。
"old_name.txt", "new_name.txt") os.rename(
os.getenv(key) 函数用于获取指定环境变量的值。如果环境变量不存在,返回 None。
= os.getenv("HOME")
home_directory print("HOME 目录:", home_directory)
os.system(command) 函数用于在操作系统的 shell 中执行命令。命令执行后,返回命令的退出状态。
"ls -l") os.system(
os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:
序号 | 方法及描述 |
---|---|
1 | os.access(path, mode) 检验权限模式 |
2 | os.chdir(path) 改变当前工作目录 |
3 | os.chflags(path, flags) 设置路径的标记为数字标记。 |
4 | os.chmod(path, mode) 更改权限 |
5 | os.chown(path, uid, gid) 更改文件所有者 |
6 | os.chroot(path) 改变当前进程的根目录 |
7 | os.close(fd) 关闭文件描述符 fd |
8 | os.closerange(fd_low, fd_high) 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 |
9 | os.dup(fd) 复制文件描述符 fd |
10 | os.dup2(fd, fd2) 将一个文件描述符 fd 复制到另一个 fd2 |
11 | os.fchdir(fd) 通过文件描述符改变当前工作目录 |
12 | os.fchmod(fd,
mode) 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 |
13 | os.fchown(fd, uid,
gid) 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 |
14 | os.fdatasync(fd) 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 |
15 | os.fdopen(fd[, mode[, bufsize]]) 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
16 | os.fpathconf(fd,
name) 返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 |
17 | os.fstat(fd) 返回文件描述符fd的状态,像stat()。 |
18 | os.fstatvfs(fd) 返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。 |
19 | os.fsync(fd) 强制将文件描述符为fd的文件写入硬盘。 |
20 | os.ftruncate(fd, length) 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 |
21 | os.getcwd() 返回当前工作目录 |
22 | os.getcwdb() 返回一个当前工作目录的Unicode对象 |
23 | os.isatty(fd) 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 |
24 | os.lchflags(path, flags) 设置路径的标记为数字标记,类似 chflags(),但是没有软链接 |
25 | os.lchmod(path, mode) 修改连接文件权限 |
26 | os.lchown(path, uid, gid) 更改文件所有者,类似 chown,但是不追踪链接。 |
27 | os.link(src, dst) 创建硬链接,名为参数 dst,指向参数 src |
28 | os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
29 | os.lseek(fd, pos, how) 设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 |
30 | os.lstat(path) 像stat(),但是没有软链接 |
31 | os.major(device) 从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 |
32 | os.makedev(major,
minor) 以major和minor设备号组成一个原始设备号 |
33 | os.makedirs(path[, mode]) 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 |
34 | os.minor(device) 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 |
35 | os.mkdir(path[,
mode]) 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 |
36 | os.mkfifo(path[, mode]) 创建命名管道,mode 为数字,默认为 0666 (八进制) |
37 | os.mknod(filename[, mode=0600,
device]) 创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。 |
38 | os.open(file, flags[,
mode]) 打开一个文件,并且设置需要的打开选项,mode参数是可选的 |
39 | os.openpty() 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 |
40 | os.pathconf(path, name) 返回相关文件的系统配置信息。 |
41 | os.pipe() 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 |
42 | os.popen(command[, mode[, bufsize]]) 从一个 command 打开一个管道 |
43 | os.read(fd, n) 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 |
44 | os.readlink(path) 返回软链接所指向的文件 |
45 | os.remove(path) 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 |
46 | os.removedirs(path) 递归删除目录。 |
47 | os.rename(src, dst) 重命名文件或目录,从 src 到 dst |
48 | os.renames(old,
new) 递归地对目录进行更名,也可以对文件进行更名。 |
49 | os.rmdir(path) 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 |
50 | os.stat(path) 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 |
51 | os.stat_float_times([newvalue]) 决定stat_result是否以float对象显示时间戳 |
52 | os.statvfs(path) 获取指定路径的文件系统统计信息 |
53 | os.symlink(src, dst) 创建一个软链接 |
54 | os.tcgetpgrp(fd) 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 |
55 | os.tcsetpgrp(fd,
pg) 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 |
56 | os.tempnam([dir[, prefix]]) Python3 中已删除。返回唯一的路径名用于创建临时文件。 |
57 | os.tmpfile() Python3 中已删除。返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。 |
58 | os.tmpnam() Python3 中已删除。为创建一个临时文件返回一个唯一的路径 |
59 | os.ttyname(fd) 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 |
60 | os.unlink(path) 删除文件路径 |
61 | os.utime(path, times) 返回指定的path文件的访问和修改的时间。 |
62 | os.walk(top[, topdown=True[, onerror=None[,
followlinks=False]]]) 输出在文件夹中的文件名通过在树中游走,向上或者向下。 |
63 | os.write(fd, str) 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |
64 | os.path 模块 获取文件的属性信息。 |
65 | os.pardir() 获取当前目录的父目录,以字符串形式显示目录名。 |
66 | os.replace() 重命名文件或目录。 |
67 | os.startfile() 用于在 Windows 上打开一个文件或文件夹。 |
作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。
Python 有两种错误很容易辨认:语法错误和异常。
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例
>>> while True print('Hello world')
"<stdin>", line 1, in ?
File while True print('Hello world')
^
SyntaxError: invalid syntax
这个例子中,函数 print() 被检查到有错误,是它前面缺少了一个冒号 : 。
语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。
即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:
>>> 10 * (1/0) # 0 不能作为除数,触发异常
Traceback (most recent call last):"<stdin>", line 1, in ?
File ZeroDivisionError: division by zero
>>> 4 + spam*3 # spam 未定义,触发异常
Traceback (most recent call last):"<stdin>", line 1, in ?
File NameError: name 'spam' is not defined
>>> '2' + 2 # int 不能与 str 相加,触发异常
Traceback (most recent call last):"<stdin>", line 1, in <module>
File TypeError: can only concatenate str (not "int") to str
异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。
错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。
try/except
异常捕捉可以使用 try/except 语句。
以下例子中,让用户输入一个合法的整数,但是允许用户中断这个程序(使用 Control-C 或者操作系统提供的方法)。用户中断的信息会引发一个 KeyboardInterrupt 异常。
while True:
try:
= int(input("请输入一个数字: "))
x break
except ValueError:
print("您输入的不是数字,请再次尝试输入!")
try 语句按照如下方式工作;
一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
except (RuntimeError, TypeError, NameError):
pass
最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
import sys
try:
= open('myfile.txt')
f = f.readline()
s = int(s.strip())
i except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
try/except...else
try/except
语句还有一个可选的 else
子句,如果使用这个子句,那么必须放在所有的 except 子句之后。
else 子句将在 try 子句没有发生任何异常的时候执行。
以下实例在 try 语句中判断文件是否可以打开,如果打开文件时正常的没有发生异常则执行 else 部分的语句,读取文件内容:
for arg in sys.argv[1:]:
try:
= open(arg, 'r')
f except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到,而 except 又无法捕获的异常。
异常处理并不仅仅处理那些直接发生在 try 子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。例如:
>>> def this_fails():
= 1/0
x
>>> try:
this_fails()except ZeroDivisionError as err:
print('Handling run-time error:', err)
-time error: int division or modulo by zero Handling run
try-finally
语句
try-finally 语句无论是否发生异常都将执行最后的代码。
以下实例中 finally 语句无论异常是否发生都会执行:
try:
runoob()except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
= file.read()
read_data except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('这句话,无论异常是否发生都会执行。')
Python 使用 raise 语句抛出一个指定的异常。
raise语法格式如下:
raise [Exception [, args [, traceback]]]
以下实例如果x大于5就触发异常
= 10
x if x > 5:
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
执行以上代码会触发异常:
Traceback (most recent call last):"test.py", line 3, in <module>
File raise Exception('x 不能大于 5。x 的值为: {}'.format(x))
Exception: x 不能大于 5。x 的值为: 10
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
>>> try:
raise NameError('HiThere') # 模拟一个异常。
except NameError:
print('An exception flew by!')
raise
!
An exception flew by
Traceback (most recent call last):"<stdin>", line 2, in ?
File NameError: HiThere
你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 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)
4
My exception occurred, value: >>> raise MyError('oops!')
Traceback (most recent call last):"<stdin>", line 1, in ?
File 'oops!' __main__.MyError:
在这个例子中,类 Exception 默认的 __init__()
被覆盖。
当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
大多数的异常的名字都以”Error”结尾,就跟标准的异常命名一样。
try 语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。 例如:
>>> try:
raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
... !
Goodbye, world
Traceback (most recent call last):"<stdin>", line 2, in <module>
File KeyboardInterrupt
以上例子不管 try 子句里面有没有发生异常,finally 子句都会执行。
如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后被抛出。
下面是一个更加复杂的例子(在同一个 try 语句里包含 except 和 finally 子句):
>>> def divide(x, y):
try:
= x / y
result except ZeroDivisionError:
print("division by zero!")
else:
print("result is", result)
finally:
print("executing finally clause")
>>> divide(2, 1)
is 2.0
result finally clause
executing >>> divide(2, 0)
!
division by zerofinally clause
executing >>> divide("2", "1")
finally clause
executing
Traceback (most recent call last):"<stdin>", line 1, in ?
File "<stdin>", line 3, in divide
File TypeError: unsupported operand type(s) for /: 'str' and 'str'
一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。
下面这个例子展示了尝试打开一个文件,然后把内容打印到屏幕上:
for line in open("myfile.txt"):
print(line, end="")
以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并没有被关闭。
关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:
with open("myfile.txt") as f:
for line in f:
print(line, end="")
以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件。
assert expression
# 等价于
if not expression:
raise AssertionError
assert 后面也可以紧跟参数:
assert expression [, arguments]
# 等价于:
if not expression:
raise AssertionError(arguments)
以下为 assert 使用实例:
>>> assert True # 条件为 true 正常执行
>>> assert False # 条件为 false 触发异常
Traceback (most recent call last):"<stdin>", line 1, in <module>
File AssertionError
>>> assert 1==1 # 条件为 true 正常执行
>>> assert 1==2 # 条件为 false 触发异常
Traceback (most recent call last):"<stdin>", line 1, in <module>
File AssertionError
>>> assert 1==2, '1 不等于 2'
Traceback (most recent call last):"<stdin>", line 1, in <module>
File AssertionError: 1 不等于 2
>>>
以下实例判断当前系统是否为 Linux,如果不满足条件则直接触发异常,不必执行接下来的代码:
import sys
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
# 接下来要执行的代码
Python 中的 with 语句用于异常处理,封装了
try…except…finally
编码范式,提高了易用性。
with 语句使代码更清晰、更具可读性, 它简化了文件流等公共资源的管理。
在处理文件对象时使用 with 关键字是一种很好的做法。
我们可以看下以下几种代码实例: 不使用 with,也不使用
try…except…finally
file = open('./test_runoob.txt', 'w')
file.write('hello world !')
file.close()
以上代码如果在调用 write 的过程中,出现了异常,则 close 方法将无法被执行,因此资源就会一直被该程序占用而无法被释放。
接下来我们呢可以使用 try…except…finally
来改进代码:
file = open('./test_runoob.txt', 'w')
try:
file.write('hello world')
finally:
file.close()
以上代码我们对可能发生异常的代码处进行 try 捕获,发生异常时执行 except 代码块,finally 代码块是无论什么情况都会执行,所以文件会被关闭,不会因为执行异常而占用资源。
使用 with 关键字:
with open('./test_runoob.txt', 'w') as file:
file.write('hello world !')
使用 with 关键字系统会自动调用 f.close() 方法, with 的作用等效于 try/finally 语句是一样的。
我们可以在执行 with 关键字后检验文件是否关闭:
>>> with open('./test_runoob.txt') as f:
= f.read()
... read_data
>>> # 查看文件是否关闭
>>> f.closed
True
with 语句实现原理建立在上下文管理器之上。
上下文管理器是一个实现 __enter__
和
__exit__
方法的类。
使用 with 语句确保在嵌套块的末尾调用 __exit__
方法。
这个概念类似于 try...finally
块的使用。
with open('./test_runoob.txt', 'w') as my_file:
'hello world!') my_file.write(
在文件对象中定义了 __enter__
和 __exit__
方法,即文件对象也实现了上下文管理器,首先调用 __enter__
方法,然后执行 with 语句中的代码,最后调用 __exit__
方法。
即使出现错误,也会调用 __exit__
方法,也就是会关闭文件流。
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。
如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。
接下来我们先来简单的了解下面向对象的一些基本特征。
和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。
Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。
语法格式如下:
class ClassName:
<statement-1>
.
.
.<statement-N>
类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性。
类对象支持两种操作:属性引用和实例化。
属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name。
类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:
#!/usr/bin/python3
class MyClass:
"""一个简单的类实例"""
= 12345
i def f(self):
return 'hello world'
# 实例化类
= MyClass()
x
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())
以上创建了一个新的类实例并将该对象赋给局部变量x,x为空的对象。
执行以上程序输出结果为:
12345
MyClass 类的属性 i 为: MyClass 类的方法 f 输出为: hello world
类定义了 __init__()
方法,类的实例化操作会自动调用
__init__()
方法。如下实例化类 MyClass,对应的
__init__()
方法就会被调用:
= MyClass() x
当然, __init__()
方法可以有参数,参数通过
__init__()
传递到类的实例化操作上。例如:
#!/usr/bin/python3
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
= Complex(3.0, -4.5)
x print(x.r, x.i) # 输出结果:3.0 -4.5
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
class Test:
def prt(self):
print(self)
print(self.__class__)
= Test()
t t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x100771878>
__main__.Test
从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。
self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的:
class Test:
def prt(runoob):
print(runoob)
print(runoob.__class__)
= Test()
t t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x100771878>
__main__.Test
在 Python中,self 是一个惯用的名称,用于表示类的实例(对象)自身。它是一个指向实例的引用,使得类的方法能够访问和操作实例的属性。
当你定义一个类,并在类中定义方法时,第一个参数通常被命名为 self,尽管你可以使用其他名称,但强烈建议使用 self,以保持代码的一致性和可读性。
class MyClass:
def __init__(self, value):
self.value = value
def display_value(self):
print(self.value)
# 创建一个类的实例
= MyClass(42)
obj
# 调用实例的方法
# 输出 42 obj.display_value()
在上面的例子中,self 是一个指向类实例的引用,它在
__init__
构造函数中用于初始化实例的属性,也在 display_value
方法中用于访问实例的属性。通过使用
self,你可以在类的方法中访问和操作实例的属性,从而实现类的行为。
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
#!/usr/bin/python3
#类定义
class people:
#定义基本属性
= ''
name = 0
age #定义私有属性,私有属性在类外部无法直接进行访问
= 0
__weight #定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
# 实例化类
= people('runoob',10,30)
p p.speak()
执行以上程序输出结果为:
10 岁。 runoob 说: 我
派生类的定义如下所示:
class DerivedClassName(BaseClassName):
<statement-1>
.
.
.<statement-N>
子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。
BaseClassName(实例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:
class DerivedClassName(modname.BaseClassName):
#!/usr/bin/python3
#类定义
class people:
#定义基本属性
= ''
name = 0
age #定义私有属性,私有属性在类外部无法直接进行访问
= 0
__weight #定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
= ''
grade def __init__(self,n,a,w,g):
#调用父类的构函
__init__(self,n,a,w)
people.self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
= student('ken',10,60,3)
s s.speak()
执行以上程序输出结果为:
10 岁了,我在读 3 年级 ken 说: 我
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.<statement-N>
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
#!/usr/bin/python3
#类定义
class people:
#定义基本属性
= ''
name = 0
age #定义私有属性,私有属性在类外部无法直接进行访问
= 0
__weight #定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
= ''
grade def __init__(self,n,a,w,g):
#调用父类的构函
__init__(self,n,a,w)
people.self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
#另一个类,多继承之前的准备
class speaker():
= ''
topic = ''
name def __init__(self,n,t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
#多继承
class sample(speaker,student):
=''
a def __init__(self,n,a,w,g,t):
__init__(self,n,a,w,g)
student.__init__(self,n,t)
speaker.
= sample("Tim",25,80,4,"Python")
test #方法名同,默认调用的是在括号中参数位置排前父类的方法 test.speak()
执行以上程序输出结果为:
我叫 Tim,我是一个演说家,我演讲的主题是 Python
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法,实例如下:
#!/usr/bin/python3
class Parent: # 定义父类
def myMethod(self):
print ('调用父类方法')
class Child(Parent): # 定义子类
def myMethod(self):
print ('调用子类方法')
= Child() # 子类实例
c # 子类调用重写方法
c.myMethod() super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
super() 函数是用于调用父类(超类)的一个方法。
执行以上程序输出结果为:
调用子类方法 调用父类方法
如果在子类中需要父类的构造方法就需要显式地调用父类的构造方法,或者不重写父类的构造方法。
子类不重写 __init__
,实例化子类时,会自动调用父类定义的
__init__
。
class Father(object):
def __init__(self, name):
self.name=name
print ( "name: %s" %( self.name) )
def getName(self):
return 'Father ' + self.name
class Son(Father):
def getName(self):
return 'Son '+self.name
if __name__=='__main__':
=Son('runoob')
sonprint ( son.getName() )
输出结果为:
name: runoob Son runoob
如果重写了__init__
时,实例化子类,就不会调用父类已经定义的
__init__
,语法格式如下:
class Father(object):
def __init__(self, name):
self.name=name
print ( "name: %s" %( self.name) )
def getName(self):
return 'Father ' + self.name
class Son(Father):
def __init__(self, name):
print ( "hi" )
self.name = name
def getName(self):
return 'Son '+self.name
if __name__=='__main__':
=Son('runoob')
sonprint ( son.getName() )
输出结果为:
hi Son runoob
如果重写了__init__
时,要继承父类的构造方法,可以使用
super 关键字:
super(子类,self).__init__(参数1,参数2,....)
还有一种经典写法:
__init__(self,参数1,参数2,...) 父类名称.
class Father(object):
def __init__(self, name):
self.name=name
print ( "name: %s" %( self.name))
def getName(self):
return 'Father ' + self.name
class Son(Father):
def __init__(self, name):
super(Son, self).__init__(name)
print ("hi")
self.name = name
def getName(self):
return 'Son '+self.name
if __name__=='__main__':
=Son('runoob')
sonprint ( son.getName() )
输出结果为:
name: runoob
hi Son runoob
类的私有属性
__private_attrs
:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时
self.__private_attrs
。
类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定使用 self
类的私有方法
__private_method
:两个下划线开头,声明该方法为私有方法,只能在类的内部调用
,不能在类的外部调用。self.__private_methods
。
类的私有属性实例如下:
#!/usr/bin/python3
class JustCounter:
= 0 # 私有变量
__secretCount = 0 # 公开变量
publicCount
def count(self):
self.__secretCount += 1
self.publicCount += 1
print (self.__secretCount)
= JustCounter()
counter
counter.count()
counter.count()print (counter.publicCount)
print (counter.__secretCount) # 报错,实例不能访问私有变量
执行以上程序输出结果为:
1
2
2
Traceback (most recent call last):"test.py", line 16, in <module>
File print (counter.__secretCount) # 报错,实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'
类的私有方法实例如下:
#!/usr/bin/python3
class Site:
def __init__(self, name, url):
self.name = name # public
self.__url = url # private
def who(self):
print('name : ', self.name)
print('url : ', self.__url)
def __foo(self): # 私有方法
print('这是私有方法')
def foo(self): # 公共方法
print('这是公共方法')
self.__foo()
= Site('菜鸟教程', 'www.runoob.com')
x # 正常输出
x.who() # 正常输出
x.foo() # 报错 x.__foo()
类的专有方法:
__init__
: 构造函数,在生成对象时调用__del__
: 析构函数,释放对象时使用__repr__
: 打印,转换__setitem__
: 按照索引赋值__getitem__
: 按照索引获取值__len__
: 获得长度__cmp__
: 比较运算__call__
: 函数调用__add__
: 加运算__sub__
: 减运算__mul__
: 乘运算__truediv__
: 除运算__mod__
: 求余运算__pow__
: 乘方Python同样支持运算符重载,我们可以对类的专有方法进行重载,实例如下:
#!/usr/bin/python3
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
= Vector(2,10)
v1 = Vector(5,-2)
v2 print (v1 + v2)
# Vector(7,8)
先看看官方文档的一段话:
is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries。 A namespace
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。
命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。
我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
一般有三种命名空间:
命名空间查找顺序:
假设我们要使用变量 runoob,则 Python 的查找顺序为:局部的命名空间 -> 全局命名空间 -> 内置命名空间。
如果找不到变量 runoob,它将放弃查找并引发一个 NameError 异常:
NameError: name 'runoob' is not defined。
命名空间的生命周期:
命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。
因此,我们无法从外部命名空间访问内部命名空间的对象。
# var1 是全局名称
= 5
var1 def some_func():
# var2 是局部名称
= 6
var2 def some_inner_func():
# var3 是内嵌的局部名称
= 7 var3
is a textual region of a Python program where a namespace is directly accessible. "Directly accessible" here means that an unqualified reference to a name attempts to find the name in the namespace. A scope
作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
Python 的作用域一共有 4 种,分别是:
有四种作用域:
LEGB 规则(Local, Enclosing, Global, Built-in):Python 查找变量时的顺序是: L –> E –> G –> B。
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
->闭包函数外的函数Enclosing->全局作用域Global->内建作用域Built-in 局部作用域Local
= 0 # 全局作用域
g_count def outer():
= 1 # 闭包函数外的函数中
o_count def inner():
= 2 # 局部作用域 i_count
内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:
>>> import builtins
>>> dir(builtins)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:
>>> if True:
= 'I am from Runoob'
... msg
... >>> msg
'I am from Runoob'
>>>
实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。
如果将 msg 定义在函数中,则它就是局部变量,外部不能访问:
>>> def test():
= 'I am from Runoob'
... msg_inner
... >>> msg_inner
Traceback (most recent call last):"<stdin>", line 1, in <module>
File NameError: name 'msg_inner' is not defined
>>>
从报错的信息上看,说明了 msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
在函数内部声明的变量只在函数内部的作用域中有效,调用函数时,这些内部变量会被加入到函数内部的作用域中,并且不会影响到函数外部的同名变量,如下实例:
#!/usr/bin/python3
= 0 # 这是一个全局变量
total # 可写函数说明
def sum( arg1, arg2 ):
#返回2个参数的和."
= arg1 + arg2 # total在这里是局部变量.
total print ("函数内是局部变量 : ", total)
return total
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)
# 函数内是局部变量 : 30
# 函数外是全局变量 : 0
1、全局变量:在函数外部定义的变量,可以在整个文件中被访问。在函数外部定义的变量对所有函数都是可见的,除非函数内部定义了同名的局部变量。`
= 10 # 全局变量
x
def my_function():
print(x) # 可以访问全局变量 x
# 输出 10 my_function()
2、局部变量:在函数内部定义的变量,仅在函数内有效,函数外无法访问。局部变量优先级高于全局变量,因此如果局部变量和全局变量同名,函数内部会使用局部变量。
def my_function():
= 5 # 局部变量
x print(x) # 访问局部变量 x
# 输出 5
my_function() print(x) # 报错: NameError: name 'x' is not defined
当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal 关键字了。
以下实例修改全局变量 num:
#!/usr/bin/python3
= 1
num def fun1():
global num # 需要使用 global 关键字声明
print(num)
= 123
num print(num)
fun1()print(num)
以上实例输出结果:
1
123
123
如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
#!/usr/bin/python3
def outer():
= 10
num def inner():
nonlocal num # nonlocal关键字声明
= 100
num print(num)
inner()print(num)
outer()
以上实例输出结果:
100
100
另外有一种特殊情况,假设下面这段代码被运行:
#!/usr/bin/python3
= 10
a def test():
= a + 1
a print(a)
test()
# Traceback (most recent call last):
# File "test.py", line 7, in <module>
# test()
# File "test.py", line 5, in test
# a = a + 1
# UnboundLocalError: local variable 'a' referenced before assignment
错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。
修改 a 为全局变量:
#!/usr/bin/python3
= 10
a def test():
global a
= a + 1
a print(a)
test()# 11
也可以通过函数参数传递
#!/usr/bin/python3
= 10
a def test(a):
= a + 1
a print(a)
test(a)# 11
Python 标准库非常庞大,所提供的组件涉及范围十分广泛,使用标准库我们可以让您轻松地完成各种任务。
以下是一些 Python3 标准库中的模块:
os 模块提供了不少与操作系统相关联的函数,例如文件和目录的操作。
import os
# 获取当前工作目录
= os.getcwd()
current_dir print("当前工作目录:", current_dir)
# 列出目录下的文件
= os.listdir(current_dir)
files print("目录下的文件:", files)
建议使用 import os 风格而非
from os import *
,这样可以保证随操作系统不同而有所变化的
os.open() 不会覆盖内置函数 open()。
在使用 os 这样的大型模块时内置的 dir() 和 help() 函数非常有用:
>>> import os
>>> dir(os)
<returns a list of all module functions>
>>> help(os)
<returns an extensive manual page created from the module's docstrings>
针对日常的文件和目录管理任务,:mod:shutil
模块提供了一个易于使用的高级接口:
>>> import shutil
>>> shutil.copyfile('data.db', 'archive.db')
>>> shutil.move('/build/executables', 'installdir')
glob 模块提供了一个函数用于从目录通配符搜索中生成文件列表:
实例
>>> import glob
>>> glob.glob('*.py')
'primes.py', 'random.py', 'quote.py'] [
通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于 sys 模块的 argv 变量。例如在命令行中执行 “python demo.py one two three” 后可以得到以下输出结果:
>>> import sys
>>> print(sys.argv)
'demo.py', 'one', 'two', 'three'] [
sys 还有 stdin,stdout 和 stderr 属性,即使在 stdout 被重定向时,后者也可以用于显示警告和错误信息。
实例
>>> sys.stderr.write('Warning, log file not found starting a new one\n')
Warning, log file not found starting a new one
大多脚本的定向终止都使用 sys.exit()。
re 模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案:
实例
>>> import re
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
'foot', 'fell', 'fastest']
[>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
如果只需要简单的功能,应该首先考虑字符串方法,因为它们非常简单,易于阅读和调试:
>>> 'tea for too'.replace('too', 'two')
'tea for two'
math 模块为浮点运算提供了对底层 C 函数库的访问:
>>> import math
>>> math.cos(math.pi / 4)
0.70710678118654757
>>> math.log(1024, 2)
10.0
random 提供了生成随机数的工具。
>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'apple'
>>> random.sample(range(100), 10) # sampling without replacement
30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
[>>> random.random() # random float
0.17970987693706186
>>> random.randrange(6) # random integer chosen from range(6)
4
有几个模块用于访问互联网以及处理网络通信协议。其中最简单的两个是用于处理从 urls 接收的数据的 urllib.request 以及用于发送电子邮件的 smtplib:
>>> from urllib.request import urlopen
>>> for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
= line.decode('utf-8') # Decoding the binary data to text.
... line if 'EST' in line or 'EDT' in line: # look for Eastern Time
... print(line)
...
<BR>Nov. 25, 09:43:32 PM EST
>>> import smtplib
>>> server = smtplib.SMTP('localhost')
>>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
"""To: jcaesar@example.org
... ... From: soothsayer@example.org
...
... Beware the Ides of March.
... """)
>>> server.quit()
注意第二个例子需要本地有一个在运行的邮件服务器。
atetime 模块为日期和时间处理同时提供了简单和复杂的方法。
支持日期和时间算法的同时,实现的重点放在更有效的处理和格式化输出。
import datetime
#获取当前日期和时间
= datetime.datetime.now()
current_datetime print(current_datetime)
# 获取当前日期
= datetime.date.today()
current_date print(current_date)
# 格式化日期
= current_datetime.strftime("%Y-%m-%d %H:%M:%S")
formatted_datetime print(formatted_datetime) # 输出:2023-07-17 15:30:45
输出结果为:
2023-07-17 18:37:56.036914
2023-07-17
2023-07-17 18:37:56
该模块还支持时区处理:
>>> # 导入了 datetime 模块中的 date 类
>>> from datetime import date
>>> now = date.today() # 当前日期
>>> now
2023, 7, 17)
datetime.date(>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'07-17-23. 17 Jul 2023 is a Monday on the 17 day of July.'
>>> # 创建了一个表示生日的日期对象
>>> birthday = date(1964, 7, 31)
>>> age = now - birthday # 计算两个日期之间的时间差
>>> age.days # 变量age的days属性,表示时间差的天数
21535
以下模块直接支持通用的数据打包和压缩格式:zlib,gzip,bz2,zipfile,以及 tarfile。
>>> import zlib
>>> s = b'witch which has which witches wrist watch'
>>> len(s)
41
>>> t = zlib.compress(s)
>>> len(t)
37
>>> zlib.decompress(t)
b'witch which has which witches wrist watch'
>>> zlib.crc32(s)
226805979
有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣。Python 提供了一个度量工具,为这些问题提供了直接答案。
例如,使用元组封装和拆封来交换元素看起来要比使用传统的方法要诱人的多,timeit 证明了现代的方法更快一些。
>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791
相对于 timeit 的细粒度,:mod:profile
和 pstats
模块提供了针对更大代码块的时间度量工具。
开发高质量软件的方法之一是为每一个函数开发测试代码,并且在开发过程中经常进行测试
doctest模块提供了一个工具,扫描模块并根据程序中内嵌的文档字符串执行测试。
测试构造如同简单的将它的输出结果剪切并粘贴到文档字符串中。
通过用户提供的例子,它强化了文档,允许 doctest 模块确认代码的结果是否与文档一致:
def average(values):
"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0
"""
return sum(values) / len(values)
import doctest
# 自动验证嵌入测试 doctest.testmod()
unittest模块不像 doctest模块那么容易使用,不过它可以在一个独立的文件里提供一个更全面的测试集:
import unittest
class TestStatisticalFunctions(unittest.TestCase):
def test_average(self):
self.assertEqual(average([20, 30, 70]), 40.0)
self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
self.assertRaises(ZeroDivisionError, average, [])
self.assertRaises(TypeError, average, 20, 30, 70)
# Calling from the command line invokes all tests unittest.main()
以上我们看到的只是 Python3 标准库中的一部分模块,还有很多其他模块可以在官方文档中查看完整的标准库文档:https://docs.python.org/zh-cn/3/library/index.html
以下内容直接略过,用到时直接问GPT好了
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
在 Python 中,使用 re 模块来处理正则表达式。
re 模块提供了一组函数,允许你在字符串中进行模式匹配、搜索和替换操作。
re 模块使 Python 语言拥有完整的正则表达式功能。
CGI 目前由NCSA维护,NCSA定义CGI如下:
CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如:HTTP服务器,提供同客户端HTML页面的接口。
MySQL 是最流行的关系型数据库管理系统,如果你不熟悉 MySQL,可以阅读我们的 MySQL 教程。
本章节我们为大家介绍使用 mysql-connector 来连接使用 MySQL, mysql-connector 是 MySQL 官方提供的驱动器。
我们可以使用 pip 命令来安装 mysql-connector:
-m pip install mysql-connector python
PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2 中则使用 mysqldb。
PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。
Python 提供了两个级别访问的网络服务。:
低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。
python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。
Python创建 SMTP 对象语法如下:
import smtplib
= smtplib.SMTP( [host [, port [, local_hostname]]] ) smtpObj
Python3 线程中常用的两个模块为:
thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用”thread” 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。
Python 对 XML 的解析 常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,当然使用场合也不同。
Python 有三种方法解析 XML:ElementTree、SAX 以及 DOM。
xml.etree.ElementTree 是 Python 标准库中用于处理 XML 的模块,它提供了简单而高效的 API,用于解析和生成 XML 文档。
Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。
import json
import time # 引入time模块
abs() dict() help() min() setattr()
all() dir() hex() next() slice()
any() divmod() id() object() sorted()
ascii() enumerate() input() oct() staticmethod()
bin() eval() int() open() str()
bool() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round() reload()
delattr() hash() memoryview() set()
-m pip3 install pymongo python3
Python urllib 库用于操作网页 URL,并对网页的内容进行抓取处理。
pip 是 Python 包管理工具,该工具提供了对 Python 包的查找、下载、安装、卸载的功能。
pip install numpy
pip uinstall numpylist pip
Python3 operator 模块
Python 3.X 的版本中已经没有 cmp() 函数,如果你需要实现比较功能,需要引入 operator 模块,适合任何对象,包含的方法有:
operator.lt(a, b)
operator.le(a, b)
operator.eq(a, b)
operator.ne(a, b)
operator.ge(a, b)
operator.gt(a, b)__lt__(a, b)
operator.__le__(a, b)
operator.__eq__(a, b)
operator.__ne__(a, b)
operator.__ge__(a, b)
operator.__gt__(a, b) operator.
Python math 模块提供了许多对浮点数的数学运算函数。
math 模块下的函数,返回值均为浮点数,除非另有明确说明。
如果你需要计算复数,请使用 cmath 模块中的同名函数。
要使用 math 函数必须先导入:
>>> import math
>>> dir(math)
'__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp'] [
Python requests 是一个常用的 HTTP 请求库,可以方便地向网站发送 HTTP 请求,并获取响应结果。
requests 模块比 urllib 模块更简洁。
使用 requests 发送 HTTP 请求需要先导入 requests 模块:
import requests
Python random 模块主要用于生成随机数。
random 模块实现了各种分布的伪随机数生成器。
要使用 random 函数必须先导入:
>>> import random
>>> dir(random)
'BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_Sequence', '_Set', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_accumulate', '_acos', '_bisect', '_ceil', '_cos', '_e', '_exp', '_floor', '_inst', '_log', '_os', '_pi', '_random', '_repeat', '_sha512', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'choices', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'lognormvariate', 'normalvariate', 'paretovariate', 'randbytes', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate'] [
在数据分析和科学计算中,统计学是一个非常重要的工具。
Python 提供了一个内置的 statistics 模块,专门用于处理基本的统计计算。本文将详细介绍 statistics 模块的功能和使用方法,帮助初学者快速掌握如何使用这个模块进行基本的统计分析。
statistics 模块提供了许多常用的统计函数,如均值、中位数、方差、标准差等。
要使用 statistics 函数必须先导入:
>>> import statistics
>>> dir(statistics)
'Counter', 'Decimal', 'Fraction', 'NormalDist', 'StatisticsError', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_coerce', '_convert', '_exact_ratio', '_fail_neg', '_find_lteq', '_find_rteq', '_isfinite', '_normal_dist_inv_cdf', '_ss', '_sum', 'bisect_left', 'bisect_right', 'erf', 'exp', 'fabs', 'fmean', 'fsum', 'geometric_mean', 'groupby', 'harmonic_mean', 'hypot', 'itemgetter', 'log', 'math', 'mean', 'median', 'median_grouped', 'median_high', 'median_low', 'mode', 'multimode', 'numbers', 'pstdev', 'pvariance', 'quantiles', 'random', 'sqrt', 'stdev', 'tau', 'variance'] [
Python hashlib 模块主要用于进行哈希(hash)操作。
哈希(Hash)是一种将任意长度的输入数据映射为固定长度输出数据的算法。
哈希通常用于验证数据的完整性、安全存储密码等场景。
哈希函数的输出通常是一串看似随机的字母和数字。
hashlib 模块提供了常见的哈希算法的实现,如 MD5、SHA-1、SHA-256 等。
要使用 hashlib 函数必须先导入:
>>> import hashlib
>>> dir(hashlib)
'__all__', '__block_openssl_constructor', '__builtin_constructor_cache', '__builtins__', '__cached__', '__doc__', '__file__', '__get_builtin_constructor', '__loader__', '__name__', '__package__', '__spec__', '_hashlib', 'algorithms_available', 'algorithms_guaranteed', 'blake2b', 'blake2s', 'md5', 'new', 'pbkdf2_hmac', 'scrypt', 'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512', 'shake_128', 'shake_256'] [
Python 量化是指利用 Python 编程语言以及相关的库和工具来进行金融市场数据分析、策略开发和交易执行的过程。
Python 由于其简洁、易学、强大的生态系统和丰富的金融库而成为量化交易的首选编程语言之一。
量化交易在金融领域得到广泛应用,它允许交易者通过系统性的方法来制定和执行交易策略,提高交易效率和决策的科学性。
量化主要是通过数学和统计学的方法,利用计算机技术对金融市场进行量化分析,从而制定和执行交易策略。
pyecharts 是一个基于 ECharts 的 Python 数据可视化库,它允许用户使用 Python 语言生成各种类型的交互式图表和数据可视化。
ECharts 是一个使用 JavaScript 实现的开源可视化库,而 Pyecharts 则是 ECharts 的 Python 封装,使得在 Python 中使用 ECharts 变得更加方便。
pyecharts 提供了一组简单而灵活的 API,使用户能够轻松地创建各种图表,包括但不限于折线图、柱状图、散点图、饼图、地图等。
通过 pyecharts,用户可以使用 Python 语言处理和准备数据,然后使用简洁的代码生成交互式的图表,这些图表可以嵌入到 Web 应用程序中或保存为静态文件。
pip install pyecharts
Selenium 是一个用于自动化 Web 浏览器操作的强大工具,广泛应用于 Web 应用程序测试、网页数据抓取和任务自动化等场景。
Selenium 为各种编程语言提供了 API,用作测试。 目前的官方 API 文档有 C#、JavaScript、Java、Python、Ruby。
Python 爬虫(Web Scraping)是指通过编写 Python 程序从互联网上自动提取信息的过程。
爬虫的基本流程通常包括发送 HTTP 请求获取网页内容、解析网页并提取数据,然后存储数据。
Python 的丰富生态使其成为开发爬虫的热门语言,特别是由于其强大的库支持。
一般来说,爬虫的流程可以分为以下几个步骤:
发送 HTTP 请求:爬虫通过 HTTP 请求从目标网站获取 HTML
页面,常用的库包括 requests。
解析 HTML 内容:获取 HTML 页面后,爬虫需要解析内容并提取数据,常用的库有
BeautifulSoup、lxml、Scrapy 等。
提取数据:通过定位 HTML
元素(如标签、属性、类名等)来提取所需的数据。
存储数据:将提取的数据存储到数据库、CSV 文件、JSON
文件等格式中,以便后续使用或分析。
pip install beautifulsoup4# 推荐使用 lxml 作为解析器(速度更快) pip install lxml
Scrapy 是一个功能强大的 Python 爬虫框架,专门用于抓取网页数据并提取信息。
Scrapy常被用于数据挖掘、信息处理或存储历史数据等应用。
Scrapy 内置了许多有用的功能,如处理请求、跟踪状态、处理错误、处理请求频率限制等,非常适合进行高效、分布式的网页爬取。
与简单的爬虫库(如 requests 和 BeautifulSoup)不同,Scrapy 是一个全功能的爬虫框架,具有高度的可扩展性和灵活性,适用于复杂和大规模的网页抓取任务。
Scrapy 官网:https://scrapy.org/。
Scrapy 特点与介绍:https://www.runoob.com/w3cnote/scrapy-detail.html。
Markdown 是一种轻量级的标记语言,它允许你使用易读易写的纯文本格式来编写文档,然后将其转换为结构化的 HTML 文档。
Markdown 的语法简单直观,常用于编写博客、文档、README 文件等。
Python 可以使用 markdown 模块将 Markdown 文本转换为 HTML。
将 Markdown 转换为 HTML 的步骤
pip install markdown
import markdown
# 定义 Markdown 文本
= """
md_text # 这是标题
这是 **加粗** 的文本。
这是 *斜体* 的文本。
- 列表项 1
- 列表项 2
[点击这里](https://www.runoob.com) 访问网站。
"""
# 转换为 HTML
= markdown.markdown(md_text)
html_output
# 输出 HTML
print(html_output)
输出结果为:
<h1>这是标题</h1>
<p>这是 <strong>加粗</strong> 的文本。
<em>斜体</em> 的文本。</p>
这是 <ul>
<li>列表项 1</li>
<li>列表项 2</li>
</ul>
<p><a href="https://www.runoob.com">点击这里</a> 访问网站。</p>
sys 是 Python 标准库中的一个模块,提供了与 Python 解释器及其环境交互的功能。
通过 sys 库,你可以访问与 Python 解释器相关的变量和函数,例如命令行参数、标准输入输出、程序退出等。
import sys
# 列出 os 模块的所有属性和方法
print(dir(os))
Python 的 pickle 模块是一个用于序列化和反序列化 Python 对象的标准库模块。
序列化是指将 Python 对象转换为字节流的过程,而反序列化则是将字节流转换回 Python 对象的过程。
pickle 模块可以将几乎所有的 Python 对象(如列表、字典、类实例等)保存到文件中,或者通过网络传输,然后在需要时重新加载。
subprocess 是 Python 标准库中的一个模块,用于创建和管理子进程。
subprocess 允许你在 Python 程序中执行外部命令,并与这些命令进行交互。
通过 subprocess 模块,你可以执行系统命令、调用其他程序,并获取它们的输出或错误信息。
在 Python 中,queue 模块提供了一个线程安全的队列实现,用于在多线程编程中安全地传递数据。
队列是一种先进先出(FIFO)的数据结构,queue 模块提供了多种队列类型,包括 Queue、LifoQueue 和 PriorityQueue,以满足不同的需求。
import queue
在 Python 中,StringIO 模块是一个非常有用的工具,它允许我们在内存中处理字符串,就像处理文件一样。通常情况下,我们处理文件时需要打开、读取、写入和关闭文件,而 StringIO 模块则提供了一种更灵活的方式,让我们可以在内存中完成这些操作,而不需要实际创建文件。
为什么使用 StringIO 模块?
from io import StringIO
# 创建 StringIO 对象
= StringIO()
string_io
# 写入数据
"Python is awesome!\n")
string_io.write("StringIO is useful!")
string_io.write(
# 移动指针到开头
0)
string_io.seek(
# 读取数据
print(string_io.read())
# 关闭 StringIO 对象
string_io.close()
在编程中,日志记录(logging)是一种非常重要的工具,它可以帮助我们跟踪程序的运行状态、调试错误以及记录重要信息。
Python 提供了一个内置的 logging 模块,专门用于处理日志记录任务。与简单的 print 语句相比,logging 模块更加灵活和强大,能够满足不同场景下的日志需求。
日志系统
import logging
Python 的 datetime 模块是用于处理日期和时间的标准库模块。它提供了多种类和函数,可以帮助我们轻松地处理日期、时间、时间差等操作。无论是获取当前时间、格式化日期,还是计算时间差,datetime 模块都能胜任。
datetime 模块的核心类
datetime 模块中包含了以下几个核心类:
Python 的 re 模块是用于处理正则表达式的标准库模块。
正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的工具,用于匹配、搜索和操作文本。
通过 re 模块,你可以在 Python 中使用正则表达式来处理字符串。
为什么使用 re 模块?
在处理文本时,我们经常需要查找特定的模式或替换某些字符。例如,验证电子邮件地址、提取网页中的链接、或者格式化文本。手动编写代码来完成这些任务可能会非常繁琐,而正则表达式提供了一种简洁且高效的方式来解决这些问题。
import re
CSV(Comma-Separated Values)文件是一种常见的文件格式,用于存储表格数据。
CSV 文件由纯文本组成,每一行代表表格中的一行数据,而每一列则通过逗号(或其他分隔符)分隔。
CSV 文件通常用于数据交换,因为它简单且易于处理。
Python 提供了一个内置的 csv 模块,用于读取和写入 CSV 文件。这个模块简化了处理 CSV 文件的过程,使得开发者可以轻松地操作表格数据。
样例
import csv
# 打开 CSV 文件
with open('data.csv', mode='r', encoding='utf-8') as file:
# 创建 csv.reader 对象
= csv.reader(file)
csv_reader
# 逐行读取数据
for row in csv_reader:
print(row)
Python 的 threading 模块是用于实现多线程编程的标准库之一。多线程允许程序在同一时间内执行多个任务,从而提高程序的效率和响应速度。
threading 模块提供了创建和管理线程的工具,使得开发者可以轻松地编写并发程序。
asyncio 是 Python 标准库中的一个模块,用于编写异步 I/O 操作的代码。
asyncio 提供了一种高效的方式来处理并发任务,特别适用于 I/O 密集型操作,如网络请求、文件读写等。
通过使用 asyncio,你可以在单线程中同时处理多个任务,而无需使用多线程或多进程。
asyncio 的核心概念
import asyncio