一、基本语法
1.注释
单行注释:#
多行注释:’’’
或者”””
2.行与缩进
python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {} 。
缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。
3.多行语句
Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠() 来实现多行语句,例如
>>> t1=12
>>> t2=13
>>> t3=t1+\
t2
>>> t3
25
在 [], {}, 或 () 中的多行语句,不需要使用反斜杠(),例如
>>> t1=12
>>> t2=13
>>> t3 = [t1
+t2]
>>> t3
[25]
4.数字(Number)类型
python中数字有四种类型:整数、布尔型、浮点数和复数。
int (整数)
: 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
bool (布尔)
:如 True。
float (浮点数)
:如 1.23、3E-2
complex (复数)
:如 1 + 2j、 1.1 + 2.2j
5.字符串(String)
(1)python中单引号和双引号使用完全相同。
(2)使用三引号('''或""")
可以指定一个多行字符串。
(3)转义符 '\'
(4)反斜杠可以用来转义,使用r可以让反斜杠不发生转义。 如 r"this is a line with \n"
则\n
会显示,并不是换行。(这里的 r 指 raw,即 raw string。)
>>> print("this is a line with \n" )
this is a line with
>>> print(r"this is a line with \n" )
this is a line with \n
(4)按字面意义级联字符串,如"this " "is " "string"
会被自动转换为this is string
。
>>> print("this ""is ""string")
this is string
(5)字符串可以用 + 运算符连接在一起,用 * 运算符重复。
>>> print("ab"+"cd")
abcd
>>> print("ab"*5)
ababababab
(6)Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
(7)Python中的字符串不能改变。
(8)Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
(9)字符串的截取的语法格式如下:变量[头下标:尾下标:步长]
#!/usr/bin/python3
str='Runoob'
print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第五个的字符
print(str[2:]) # 输出从第三个开始后的所有字符
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串
print('------------------------------')
print('hello\nrunoob') # 使用反斜杠(\)+n转义特殊字符
print(r'hello\nrunoob') # 在字符串前面添加一个 r,表示原始字符串,不会发生转义
6.同一行显示多条语句
Python可以在同一行中使用多条语句,语句之间使用分号(;)分割
>>> print("hello ");print("world!")
hello
world!
7.多个语句构成代码组
缩进相同的一组语句构成一个代码块,我们称之代码组。
像if、while、def和class
这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。
我们将首行及后面的代码组称为一个子句(clause)。
if expression :
suite
elif expression :
suite
else :
suite
8.print输出
关键字end可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符
print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end="":
>>> print("hello");print("world!")
hello
world!
>>> print("hello",end=" ");print("world!")
hello world!
>>> print("hello",end="{}");print("world!")
hello{}world!
9.import 与 from…import
在 python 用 import
或者 from...import
来导入相应的模块。
将整个模块(somemodule)导入,格式为:
import somemodule
从某个模块中导入某个函数,格式为:
from somemodule import somefunction
从某个模块中导入多个函数,格式为:
from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为:
from somemodule import *
二.基本数据类型
Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。
等号(=)用来给变量赋值。
>>> a=100
>>> b=100.0
>>> c="string"
>>> print(a)
100
>>> print(b)
100.0
>>> print(c)
string
1.多个变量赋值
Python允许你同时为多个变量赋值
>>> a=b=c=100
>>> print(a,b,c)
100 100 100
以上实例,创建一个整型对象,值为 1,从后向前赋值,三个变量被赋予相同的数值。您也可以为多个对象指定多个变量。例如:
>>> a,b,c = 100,100.0,"python"
>>> print(a,b,c)
100 100.0 python
2.标准数据类型
Python3 中有六个标准的数据类型:
(一)Number(数字)(数学函数,随机数函数,三角函数,数学常量)
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=100
>>> isinstance(a,int)
True
用del可以删除一个或者多个对象
语法:del 对象一,对象二,...
>>> a=100
>>> a
100
>>> del a
>>> a
Traceback (most recent call last):
File "<pyshell#46>", line 1, in <module>
a
NameError: name 'a' is not defined
数学函数
随机数函数
随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。
Python包含以下常用随机数函数:
三角函数
数学常量
(二)String(字符串)(切片、转义字符、字符串运算符、字符串格式化打印、f-string格式化打印)
字符串截取方法语法格式:
变量名[头下标:尾下标]
索引值以0为开始值,-1为从末尾的开始位置
如果对截取下标不好理解,这里有一个小技巧,就是将截取的下标分配在两个数据之间
加号 + 是字符串的连接符, 星号 * 表示复制当前字符串,与之结合的数字为复制的次数。
>>> str = "Python"
>>> print(str) #输出字符串
Python
>>> print(str[0:-1]) #输出第一个字符到倒数第二个的所有字符
Pytho
>>> print(str[0]) #输出第一个字符
P
>>> print(str[2:5]) #输出第三个开始到第五个字符
tho
>>> print(str[2:]) #输出第三个开始的后的所有字符
thon
>>> print(str[:3]) #输出第三字符以及前面的所有字符
Pyt
>>> print(str * 2) #输出字符串两次
PythonPython
>>> print("I like "+str) #连接字符串
I like Python
Python 使用反斜杠 \ 转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:
>>> print("Py\nthon")
Py
thon
>>> print(r"Py\nthon")
Py\nthon
另外,反斜杠(\)可以作为续行符,表示下一行是上一行的延续。也可以使用 """..."""
或者 '''...'''
跨越多行。
注意:
1.Python字符串不能被改变
2.Python没有单独的字符类型,一个字符就是长度为1 的字符串
3.Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。
Python转义字符
Python字符串运算符
Python字符串格式化
>>> print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
我叫 小明 今年 10 岁!
f-string格式化
f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。
之前我们习惯用百分号 (%):
>>> name = 'Python'
>>> print('Hello %s' % name)
Hello Python
f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:
>>> name = 'python'
>>> print(f'Hello {name}') #替换变量
Hello python
>>> print(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}') #Pyhon 6
2
>>> x = 1
>>> print(f'{x+1=}') #python
x+1=2
(三)List(列表)(切片、列表函数&方法)
List(列表) 是 Python 中使用最频繁的数据类型。
列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。
列表截取语法格式:
变量[头下标:尾下标]
索引值以 0 为开始值,-1 为从末尾的开始位置。
>>> list = ['xiaobenjie',789,2.34,'Python',40.2]
>>> print(list) #输出完整列表
['xiaobenjie', 789, 2.34, 'Python', 40.2]
>>> print(list[1:4]) #输出第二个到第四个字符
[789, 2.34, 'Python']
>>> print(list[2:]) #输出输出第三个以及后面所有字符
[2.34, 'Python', 40.2]
>>> tin[123,"name"]
>>> tin = [123,"name"]
>>> print(tin*2) #输出两次列表
[123, 'name', 123, 'name']
>>> print(list + tin) #连接列表
['xiaobenjie', 789, 2.34, 'Python', 40.2, 123, 'name']
与Python字符串不一样的是,列表中的元素是可以改变的:
>>> a = [1,2,3,4,5]
>>> a[0] = 9
>>> a[2:5] = [13,14,15]
>>> a
[9, 2, 13, 14, 15]
>>> a[2:5] = [] #删除指定元素
>>> a
[9, 2]
Python 列表截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串:
列表函数&方法
列表函数:
列表方法:
(四)Tuple(元组)(切片、内置函数、运算符)
元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。
元组中的元素类型也可以不相同:
在这里插入代码片>>> tuple = ('python',123,3.14,"join")
>>> print(tuple) #输出完整元祖
('python', 123, 3.14, 'join')
>>> print("tuple[0]=",tuple[0]) #输出元祖第一个元素
tuple[0]= python
>>> print(tuple[1:3]) #输出第二个元素到第三个元素
(123, 3.14)
>>> print(tuple[-2]) #输出倒数第二个元素
3.14
>>> print(tuple * 2) #输出两次元祖
('python', 123, 3.14, 'join', 'python', 123, 3.14, 'join')
>>> tinytuple = (123,456)
>>> print(tuple + tinytuple) #连接两个元祖
('python', 123, 3.14, 'join', 123, 456)
>>> touple[0] = 10 #修改元祖,非法
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
touple[0] = 10 #修改元祖,非法
NameError: name 'touple' is not defined
构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:
tup1 = () # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号
可以将字符串看成是特殊的元祖
元祖的元素值是不允许修改的,但是我们可以使用del语句删除整个元组
>>> tup = ('Google','Runoob',1997,2000)
>>> print(tup)
('Google', 'Runoob', 1997, 2000)
>>> del tup
>>> print(tup)
Traceback (most recent call last):
File "<pyshell#163>", line 1, in <module>
print(tup)
元组运算符
元组内置函数
元组不可变指的是内存地址不可变
>>> tup = (1,2,3,4)
>>> tup[0] = 100 #不支持修改
Traceback (most recent call last):
File "<pyshell#167>", line 1, in <module>
tup[0] = 100 #不支持修改
TypeError: 'tuple' object does not support item assignment
>>> id(tup) #查看内存地址
5920040
>>> tup = (9,8,7) #新申请元组
>>> id(tup)
54544776 #地址不一样了
(五)Set(集合)(内置方法)
集合(set)是一个无序的不重复元素序列。
创建格式:
集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。
基本功能是进行成员关系测试和删除重复元素。
可以使用大括号 { } 或者 set() 函数创建集合
注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
创建格式:
parame = {value01,value02,...}
或者
set(value)
实例:
sites = {'Google','Taobao','Runoob','Taobao','Google'}
print(sites) #输出集合,重复的元素被自动去掉
#成员测试
if 'Google' in sites :
print("Google在集合中")
else :
print("Google不再集合中")
集合运算:
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> print(a - b) #a和b的差集
{'d', 'r', 'b'}
>>> print(a | b) #a和b的并集
{'m', 'r', 'c', 'z', 'l', 'b', 'a', 'd'}
>>> print(a & b) #a和b的交集
{'c', 'a'}
>>> print(a ^ b) #a和b不同时存在的元素
{'m', 'r', 'b', 'l', 'z', 'd'}
集合内置方法
(六)Dictionary(字典)(切片、内置函数、方法)
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }
列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。
键(key)必须使用不可变类型。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
在同一个字典中,键(key)必须是唯一的,但值不必。
>>> dict = {} #创建一个空的字典
>>> dict['肖本杰'] = "帅哥"
>>> dict[1] = 100;
>>> tinydict = {"name":'赵丽颖' , "code" : 1 ,'site' : 'www.jiejie.com'}
>>> print("dict['肖本杰'] = ",dict['肖本杰']) #打印键为“肖本杰”的值
dict['肖本杰'] = 帅哥
>>> print("dict[1] = ",dict[1]) #打印键为1的值
dict[1] = 100
>>> print(tinydict) #打印完整字典
{'name': '赵丽颖', 'code': 1, 'site': 'www.jiejie.com'}
>>> print(tinydict.keys()) #输出所有的键
dict_keys(['name', 'code', 'site'])
>>> print(tinydict.values()) #输出所有值
dict_values(['赵丽颖', 1, 'www.jiejie.com'])
>>> tinydict['name']= '王建林' #修改键值
>>> print("tinydict['name'] = ",tinydict['name'])
tinydict['name'] = 王建林
>>> tinydict.clear() #清空字典
>>> tinydict
{}
注意:键必须不可变,可以是数字,字符串,元组,但不可以是列表
内置函数
方法
(七)Python数据类型转换
有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。
以下几个内置的函数可以执行数据类型之间的转换。这些函数返回一个新的对象,表示转换的值。
三、运算符
(一)数值运算
>>> 5 + 4 # 加法
9
>>> 4.3 - 2 # 减法
2.3
>>> 3 * 7 # 乘法
21
>>> 2 / 4 # 除法,得到一个浮点数
0.5
>>> 2 // 4 # 除法,得到一个整数
0
>>> 17 % 3 # 取余
2
>>> 2 ** 5 # 乘方
32
注意:
1.数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。
2.在混合计算时,Python会把整型转换成为浮点数。
3.一个变量可以通过赋值指向不同类型的对象。
>>> 6/2
3.0
>>> 6//2
3
(二)位运算
(三)逻辑运算
(四)成员运算
list = [1,2,3,4,5]
a = 1
b = 10
if (a in list):
print("a在列表中")
else :
print("a不在列表中")
if(b not in list):
print("b不在列表中")
else :
print("b在列表中")
运算结果;
==================== RESTART: E:/study/Python/code/demo04.py ===================
a在列表中
b不在列表中
(五)身份运算符
a = 20
b = 20
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 的值
b = 30
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 有相同的标识")
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
1 - a 和 b 有相同的标识
2 - a 和 b 有相同的标识
3 - a 和 b 没有相同的标识
4 - a 和 b 没有相同的标识
(六)is 与 == 区别:
is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
>>>a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True
(七)运算符优先级
演示:
a = 20
b = 10
c = 15
d = 5
e = 0
e = (a + b) * c / d #( 30 * 15 ) / 5
print ("(a + b) * c / d 运算结果为:", e)
e = ((a + b) * c) / d # (30 * 15 ) / 5
print ("((a + b) * c) / d 运算结果为:", e)
e = (a + b) * (c / d); # (30) * (15/5)
print ("(a + b) * (c / d) 运算结果为:", e)
e = a + (b * c) / d; # 20 + (150/5)
print ("a + (b * c) / d 运算结果为:", e)
运算结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
(a + b) * c / d 运算结果为: 90.0
((a + b) * c) / d 运算结果为: 90.0
(a + b) * (c / d) 运算结果为: 90.0
a + (b * c) / d 运算结果为: 50.0
and拥有更高优先级
x = True
y = False
z = False
if x or y and z:
print("yes")
else:
print("no")
运行结果;
true
四、条件控制
Python 条件语句是通过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块。
if语句
if condition_1:
statement_block_1
elif condition_2:
statement_block_2
else:
statement_block_3
如果 "condition_1" 为 True 将执行 "statement_block_1" 块语句
如果 "condition_1" 为False,将判断 "condition_2"
如果"condition_2" 为 True 将执行 "statement_block_2" 块语句
如果 "condition_2" 为False,将执行"statement_block_3"块语句
Python 中用 elif 代替了 else if,所以if语句的关键字为:if – elif – else。
在Python中没有switch – case语句。
if嵌套
if 表达式1:
语句
if 表达式2:
语句
elif 表达式3:
语句
else:
语句
elif 表达式4:
语句
else:
语句
示例:
num = int(input("请输入一个数字:"))
if num % 2 :
print("您输入的不是偶数",end=',')
if(num%3) :
print("且不能被三整除")
else :
print("可以被三整除")
else :
print("您输入的是偶数",end=",")
if(num%3) :
print("且不能被三整除")
else :
print("可以被三整除")
五、循环语句
Python 中的循环语句有 for 和 while。
(一)while循环
Python 中 while 语句的一般形式:
while 判断条件(condition):
执行语句(statements)……
执行流程图:
同样需要注意冒号和缩进。另外,在 Python 中没有 do…while 循环。
无限循环可以用:CTRC+C 来退出当前无限循环,无限循环在服务器上客户端的实时请求非常有用。
while 循环使用 else 语句
在 while … else 在条件语句为 false 时执行 else 的语句块。
while <expr>:
<statement(s)>
else:
<additional_statement(s)>
简单语句组:类似if语句的语法,如果你的while循环体中只有一条语句,你可以将该语句与while写在同一行中
(二)for循环
Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串。
for循环的一般格式如下:
for <variable> in <sequence>:
<statements>
else:
<statements>
实例:
>>> list = ["C","C++","java","Python"]
>>> for x in list:
print(x)
C
C++
java
Python
使用bresk语句:
list = ["王健林","王思聪","赵丽颖","迪丽热巴"]
for x in list:
if(x == '赵丽颖'):
print("找的了赵丽颖")
break;
else:
print(f"现在是{x}还没有找到赵丽颖")
#print("现在是%s还没有找到赵丽颖" %(x))
print("任务结束")
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
现在是王健林还没有找到赵丽颖
现在是王思聪还没有找到赵丽颖
找的了赵丽颖
任务结束
>>>
range()函数
如果你需要遍历数字序列,可以使用内置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(5,20,3):
print(i)
5
8
11
14
17
负数:
>>> for i in range(-10,-100,-20):
print(i)
-10
-30
-50
-70
-90
>>> for i in range(-10,100,8):
print(i)
-10
-2
6
14
22
30
38
46
54
62
70
78
86
94
您可以结合range()和len()函数以遍历一个序列的索引,如下所示:
>>> list = ["王健林","王思聪","赵丽颖","迪丽热巴"]
>>> for i in range(len(list)):
print(i,list[i])
0 王健林
1 王思聪
2 赵丽颖
3 迪丽热巴
break和continue
break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
pass语句
Python pass是空语句,是为了保持程序结构的完整性。
pass 不做任何事情,一般用做占位语句,如下实例
>>> while True:
pass #等待键盘中断
六、迭代器与生成器
(一)迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter()
和 next()
。
字符串,列表或元组对象都可用于创建迭代器:
>>> list = [1,2,3,4,5]
>>> it = iter(list) #创建迭代器对象
>>> print(next(it)) #输出迭代器的下一个元素
1
>>> print(next(it)) #输出迭代器的下一个元素
2
迭代器对象可以使用常规for语句进行遍历:
>>> list = [1,2,3,4,5]
>>> it = iter(list)
>>> for i in it:
print(i,end=" ")
1 2 3 4 5
也可以使用 next() 函数:
import sys #引入 sys 模块
list = [1,2,3,4,5,6]
it = iter(list) #创建迭代器对象
while True:
try:
print(next(it))
except StopIteration:
sys.exit()
结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
1
2
3
4
5
6
创建一个迭代器
把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__()
与 __next__()
。
如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 __init__()
, 它会在对象初始化的时候执行。
__iter__()
方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__()
方法并通过 StopIteration
异常标识迭代的完成。
__next__()
方法(Python 2 里是 next())会返回下一个迭代器对象。
创建一个返回数字的迭代器,初始值为 1,逐步递增 1:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
1
2
3
4
5
StopIteration
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
在 20 次迭代后停止执行:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x)
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
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 的值, 并在下一次执行 next()
方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
以下实例使用 yield
实现斐波那契数列:
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
0 1 1 2 3 5 8 13 21 34 55
七、函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
语法
Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
函数体
默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。
实例:
>>> def hello(): #创建一个函数
print("Hello world!")
>>> hello() #调用函数
Hello world!
带参函数:
>>> def area(width,height): #计算没接函数
return width * height
>>> w = 4
>>> h = 3
>>> print(area(w,h))
12
参数传递
在 python 中,类型属于对象,变量是没有类型的:
-
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
-
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la
的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。 -
不可变类型:类似 C++ 的值传递,如 整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在
fun(a))内部修改 a 的值,则是新生成来一个 a。 -
可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la
也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
python 传不可变对象实例
通过id()函数来查找内存地址变化
def change(a):
print(id(a)) #指向的是同一个对象
a=10
print(id(a)) #一个新对象
a=1;
print(id(a))
change(a)
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
1623238576
1623238576
1623238720
可以看见在调用函数前后,形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的 id。
python 传可变对象实例
可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:
def changeme(mylist):
#修改传入的列表
mylist.append(100)
print("函数内取值:",mylist)
return
#调用change函数
mylist = [10,20,30]
print("列表初始值:",mylist)
changeme(mylist)
print("函数外取值:",mylist)
运行结果;
==================== RESTART: E:/study/Python/code/demo04.py ===================
列表初始值: [10, 20, 30]
函数内取值: [10, 20, 30, 100]
函数外取值: [10, 20, 30, 100]
参数:
(1)必须参数
必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
(2)关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
def fun(name,age):
print(f"我叫{name}今年{age}岁")
return
#使用关键字参数调用,顺序可以不一致
fun(age=18,name="王健林")
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
我叫王健林今年18
(3)默认参数
调用函数时,如果没有传递参数,则会使用默认参数。
def fun(name,age=18): #定义age是默认参数
print(f"我叫{name}今年{age}岁")
return
#使用关键字参数调用,顺序可以不一致
fun(name="王健林",age=100) #不使用默认参数
fun(name="王健林") #不传入年龄,使用默认参数
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
我叫王健林今年100岁
我叫王健林今年18岁
(4)不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法:
def functionname([formal_args,] *var_args_tuple ):
"函数_文档字符串"
function_suite
return [expression]
加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
def printof(arg1,*vartuple):
#打印任何传入的参数
print(arg1)
print(vartuple)
#调用
printof(30,40,50)
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
30
(40, 50)
如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例:
def printof(*arg):
for i in arg:
print(i,end=" ")
print()
return
printof(10) #传入一个元素
printof(12,34,"王健林",3.14) #传入多个元素
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
10
12 34 王健林 3.14
带两个*号会以字典的形式导入
def printof(arg1,**vardict):
print(arg1)
print(vardict)
return
#调用
printof(1,肖哥哥='帅哥',王健林='有钱人',王梓玉='女神')
运行结果:
1
{'肖哥哥': '帅哥', '王健林': '有钱人', '王梓玉': '女神'}
匿名函数
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法:
lambda [arg1 [,arg2,.....argn]]:expression
实例:
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
运行结果:
==================== RESTART: E:/study/Python/code/demo04.py ===================
相加后的值为 : 30
相加后的值为 : 40
八.数据结构
(一)列表
Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能。
方法:
示例:
list = [1,2,3]
>>> list.append(4)
>>> list
[1, 2, 3, 4]
>>> L = [6,5]
>>> list.extend(L)
>>> list
[1, 2, 3, 4, 6, 5]
>>> list.insert(0,9)
>>> list
[9, 1, 2, 3, 4, 6, 5]
>>> list.remove(3)
>>> list
[9, 1, 2, 4, 6, 5]
>>> list.pop(1)
1
>>> list
[9, 2, 4, 6, 5]
>>> list.index(4)
2
>>> list.count(2)
1
>>> list.sort()
>>> list
[2, 4, 5, 6, 9]
>>> list.reverse()
>>> L = list.copy()
>>> L
[9, 6, 5, 4, 2]
</font color=red>注意:类似 insert, remove 或 sort 等修改列表的方法没有返回值。
(二)将列表作为堆栈使用
列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 append()
方法可以把一个元素添加到堆栈顶。用不指定索引的 pop()
方法可以把一个元素从堆栈顶释放出来。
实例:
>>> stack = [3,4,5]
>>> stack = [3,4,5] #定义栈
>>> stack.append(6) #压入元素
>>> stack.append(7) #压入元素
>>> stack #查看栈元素
[3, 4, 5, 6, 7]
>>> stack.pop() #出栈
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
(三)将列表当做队列来使用
也可以把列表当做队列用,只是在队列里第一加入的元素,第一个取出来;但是拿列表用作这样的目的效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)。
>>> from collections import deque
>>> queue = deque(["王健林","迪丽热巴","古力娜扎"]) #初始队列
>>> queue.append("王思聪") #入队
>>> queue.append("华晨宇") #入队
>>> queue.popleft() #出队
'王健林'
>>> queue.popleft() #出队
'迪丽热巴'
>>> queue
deque(['古力娜扎', '王思聪', '华晨宇'])
(四)列表推导式
列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。
每个列表推导式都在 for 之前跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。
这里我们将列表中每个数值乘三,获得一个新的列表:
>>> vec = [2,4,6]
>>> [3*x for x in vec] #遍历列表,将每一个数乘以3组成一个新的列表
[6, 12, 18]
还可以这样:
>>> vec = [2,4,6]
>>> [[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子句作为过滤器:
>>> vec = [2,4,6]
>>> [x*2 for x in vec if x>3]
[8, 12]
>>> [x*3 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']
(五)嵌套列表解析
pythom的列表还可以嵌套
以下是3*4的矩阵列表:
>>> matrix = [
[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
]
>>> 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):
... transposed.append([row[i] for row in matrix])
...
>>> 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]]
(六)dell语句
使用 del 语句可以从一个列表中依索引而不是值来删除一个元素。这与使用 pop() 返回一个值不同。可以用 del 语句从列表中删除一个切割,或清空整个列表(我们以前介绍的方法是给该切割赋一个空列表)。例如:
>>> a = [1,2,3,4,5,6]
>>> del a[0]
>>> a
[2, 3, 4, 5, 6]
>>> del a[2:4]
>>> a
[2, 3, 6]
>>> del a[:]
>>> a
[]
也可以使用del 删除实体变量:
>>> b = 3
>>> del b
>>> b
Traceback (most recent call last):
File "<pyshell#97>", line 1, in <module>
b
NameError: name 'b' is not defined
(七)元祖和序列
元组由若干逗号分隔的值组成,例如:
>>> t = 123,3,14,'hello!'
>>> t[0]
123
>>> t
(123, 3, 14, 'hello!')
>>> u = t,('王健林','王思聪')
>>> u
((123, 3, 14, 'hello!'), ('王健林', '王思聪'))
如你所见,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号, 不过括号通常是必须的(如果元组是更大的表达式的一部分)。
(八)集合
集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。
可以用大括号({})创建集合。注意:如果要创建一个空集合,你必须用 set() 而不是 {} ;后者创建一个空的字典,下一节我们会介绍这个数据结构。
>>> basket = {'apple','orange','banana','pear','apple','banana'}
>>> print(basket)
{'apple', 'pear', 'banana', 'orange'}
>>> 'apple' in basket
True
>>> 'cucumber' in basket
False
>>> #以下演示集合操作
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a
{'c', 'r', 'b', 'd', 'a'}
>>> a - b # 在 a 中的字母,但不在 b 中
{'b', 'r', 'd'}
>>> a | b # 在 a 或 b 中的字母
{'c', 'l', 'm', 'z', 'r', 'b', 'd', 'a'}
>>> a & b # 在 a 和 b 中都有的字母
{'a', 'c'}
>>> a ^ b # 在 a 或 b 中的字母,但不同时在 a 和 b 中
{'b', 'l', 'd', 'm', 'z', 'r'}
集合也支持推导式:
>>> bb = {1,2,3,4,5}
>>> {x*2 for x in bb if x>3}
{8, 10}
>>> a = {x for x in 'aabbcdeeffgg' if x not in 'abc'}
>>> a
{'g', 'f', 'd', 'e'}
(九)字典
另一个非常有用的 Python 内建数据类型是字典。
序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。
理解字典的最佳方式是把它看做无序的键=>值对集合。在同一个字典之内,关键字必须是互不相同。
一对大括号创建一个空的字典:{}
。
这是一个字典运用的简单例子:
>>> fortune = {'王健林':100,'王思聪':2,'马云':10000}
>>> fortune['马云']
10000
>>> del fortune['王思聪']
>>> fortune['王健林']=50
>>> fortune
{'王健林': 50, '马云': 10000}
>>> fortune.keys()
dict_keys(['王健林', '马云'])
>>> fortune.values()
dict_values([50, 10000])
>>> '马云' in fortune
True
>>> '王思聪' in fortune
False
构造函数 dict() 直接从键值对元组列表中构建字典。如果有固定的模式,列表推导式指定特定的键值对:
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
此外,字典推导可以用来创建任意键和值的表达式词典:
>>> {x:x*2 for x in (2,4,6)}
{2: 4, 4: 8, 6: 12}
如果关键字只是简单的字符串,使用关键字参数指定键值对有时候更方便:
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
(十)遍历技巧
在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来:
>>> map = {'王健林':200,'马云':'1000'}
>>>> for x,y in map.items():
print(f"我叫{x}我有{y}钱")
我叫王健林我有200钱
我叫马云我有1000钱
在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:
>>> for i,v in enumerate(['马云','赵丽颖','王思聪']):
print(i,v)
0 马云
1 赵丽颖
2 王思聪
同时遍历两个或更多的序列,可以使用 zip() 组合:
>>> name = ['马云','王健林','王思聪']
>>> money = [120,345,567]
>>>> for n,m in zip(name,money):
print("我叫{0},我有{1}钱。".format(n,m))
我叫马云,我有120钱。
我叫王健林,我有345钱。
我叫王思聪,我有567钱。
要反向遍历一个序列,首先指定这个序列,然后调用 reversed() 函数:
>>> for i in reversed(range(1,10)):
print(i)
9
8
7
6
5
4
3
2
1
要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:
>>> list = [1,3,2,4,6,5,8]
>>> for i in sorted(set(list)):
print(i)
1
2
3
4
5
6
8
九、模块
在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。
为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。
使用python标准库模块的例子。
import sys
print("命令行参数:")
for i in sys.argv:
print(i)
print("\n\nPython 的路径为:",sys.path,'\n')
运行结果:
==================================================================================== RESTART: E:/study/Python/code/demo05.py ====================================================================================
命令行参数:
E:/study/Python/code/demo05.py
Python 的路径为: ['E:/study/Python/code', 'D:\\workspace\\pycharm\\Lib\\idlelib', 'D:\\workspace\\pycharm\\python38.zip', 'D:\\workspace\\pycharm\\DLLs', 'D:\\workspace\\pycharm\\lib', 'D:\\workspace\\pycharm', 'D:\\workspace\\pycharm\\lib\\site-packages']
1.import sys引入python标准库的sys.py模块;这是引入某一模块的方法
2.sys.argv是一个包含命令行参数的列表
3.sys.path 包含了一个Python解释器自动查找所需模块的路径列表
(一)import语句
想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下:
import module1[, module2[,... moduleN]
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support,需要把命令放在脚本的顶端:
support.py文件代码:
#!/usr/bin/python3
# Filename: support.py
def print_func( par ):
print ("Hello : ", par)
return
现在让我们引入模块:
>>> import support #导入模块
>>> support.print_func("熊泽宇") #调用模块方法
Hello : 熊泽宇
>>>
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
当我们使用import语句的时候,Python解释器是怎样找到对应的文件的呢?
这就涉及到Python的搜索路径,搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块。
这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。
搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量,做一个简单的实验,在交互式解释器中,输入以下代码:
>>> import sys
>>> sys.path
['D:/workspace/pycharm', 'D:\\workspace\\pycharm\\Lib\\idlelib', 'D:\\workspace\\pycharm\\python38.zip', 'D:\\workspace\\pycharm\\DLLs', 'D:\\workspace\\pycharm\\lib', 'D:\\workspace\\pycharm', 'D:\\workspace\\pycharm\\lib\\site-packages']
脚本形式:
import sys
print(sys.path)
输出:
['E:/study/Python/code', 'D:\\workspace\\pycharm\\Lib\\idlelib', 'D:\\workspace\\pycharm\\python38.zip', 'D:\\workspace\\pycharm\\DLLs', 'D:\\workspace\\pycharm\\lib', 'D:\\workspace\\pycharm', 'D:\\workspace\\pycharm\\lib\\site-packages']
sys.path 输出是一个列表,其中第一项是空串’’,代表当前目录(若是从一个脚本中打印出来的话,可以更清楚地看出是哪个目录),亦即我们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)。
因此若像我一样在当前目录下存在与要引入模块同名的文件,就会把要引入的模块屏蔽掉。
了解了搜索路径的概念,就可以在脚本中修改sys.path来引入一些不在搜索路径中的模块。
上述用法并没有把直接定义模块文件的函数名称写入当前符号列表中,只是把模块的名字写到了那里,所以只能用模块函数名称访问函数:
模块名.函数名(参数列表)
如果打算经常使用一个函数,可以把它赋给一个本地的名称:
>>> import support
>>> print_func = support.print_func
>>> print_func("帅哥")
Hello : 帅哥
>>>
(二)from … import语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下:
from modname import name1[, name2[, ... nameN]]
例如有以下模块:
def print_text1(name):
print(f"hello {name}")
return
def print_text2(name):
print(f"good by {name}")
return
例如要导入模块demo07中的print_text1函数
>>> from demo07 import print_text1 #导入模块demo07中的print_text1函数
>>> print_text1("王健林")
hello 王健林
这个声明不会把整个fibo模块导入到当前的命名空间中,它只会将fibo里的fib函数引入进来。
(三)from … import *语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
from modname import *
这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
(四)深入模块
模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。
每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。
所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞混。
从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。
模块是可以导入其他模块的。在一个模块(或者脚本,或者其他地方)的最前面使用 import 来导入一个模块,当然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。
还有一种导入的方法,可以使用 import 直接把模块内(函数,变量的)名称导入到当前操作模块。比如:
>>> from demo07 import print_text1,print_text2
>>> print_text1("马云")
hello 马云
>>> print_text2("王建林")
good by 王建林
这种导入的方法不会把被导入的模块的名称放在当前的字符表中(所以在这个例子里面,fibo 这个名称是没有定义的)。
这还有一种方法,可以一次性的把模块中的所有(函数,变量)名称都导入到当前模块的字符表:
>>> from demo07 import *
>>> print_text1("赵丽颖")
hello 赵丽颖
这将把所有的名字都导入进来,但是那些由单一下划线(_)开头的名字不在此例。大多数情况, Python程序员不使用这种方法,因为引入的其它来源的命名,很可能覆盖了已有的定义。
(五)__name__属性
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
if __name__ == '__main__':
print('程序自身运行')
else:
print('我来自另一模块')
运行输出:
==================== RESTART: E:/study/Python/code/demo08.py ===================
程序自身运行
>>> import demo08
我来自另一模块
说明: 每个模块都有一个__name__属性,当其值是’main’时,表明该模块自身在运行,否则是被引入。
说明:name 与 main 底下是双下划线, _ _ 是这样去掉中间的那个空格。
(六)dir()函数
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:
有以下模块:
#Filename:demo07.py
b=100
def print_text1(name):
print(f"hello {name}")
return
def print_text2(name):
print(f"good by {name}")
return
使用dir()函数:
>>> import demo07,sys
>>> dir(demo07)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'b', 'print_text1', 'print_text2']
>>> dir(sys)
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__', '_base_executable', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_enablelegacywindowsfsencoding', '_framework', '_getframe', '_git', '_home', '_xoptions', 'addaudithook', 'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix', 'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'pycache_prefix', 'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setcheckinterval', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info', 'warnoptions', 'winver']
如果没有给定参数,那么 dir() 函数会罗列出当前定义的所有名称:
>>> a = [1,2,3,4,5]
>>> import demo07
>>> print_text1 = demo07.print_text1
>>> dir() #得到一个当前模块中定义的属性列表
['__annotations__', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'demo07', 'print_text1', 'sys']
(七)标准模块
Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。
有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。
这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。
应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Runoob!')
Runoob!
C>
十、python输入,输出
(一)输出格式美化
Python两种输出值的方式: 表达式语句和 print() 函数。
第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用。
如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。
如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。
- str():函数返回一个用户易读的表达式
- repr():产生一个解释器易读的表达式形式
>>> s = 'hello world'
>>> str(s)
'hello world'
>>> repr(s)
"'hello world'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x 的值为:'+repr(x) + ',y的值为:'+repr(y)+'...'
>>> print(s)
x 的值为:32.5,y的值为:40000...
>>> hello = "hello world \n"
>>> print(hello)
hello world
>>> print(repr(hello))
'hello world \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("马云","王健林"))
我叫马云,我叫王健林
```python
>>> print('我叫{1},我叫{0}'.format("马云","王健林"))
我叫王健林,我叫马云
如果在 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))
常量 Pi 的近似值为:3.141592653589793。
>>> print('常量 Pi 的近似值为:{!r}。'.format(math.pi))
常量 Pi 的近似值为:3.141592653589793。
可选项 : 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位:
>>> import math
>>> print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
常量 PI 的值近似为 3.142。
在 : 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
print('{0:10} ==> {1:10d}'.format(name, number))
Google ==> 1
Runoob ==> 2
Taobao ==> 3
如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。
最简单的就是传入一个字典, 然后使用方括号 [] 来访问键值 :
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
Runoob: 2; Google: 1; Taobao: 3
也可以通过在 table 变量前使用 ** 来实现相同的功能:
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
Runoob: 2; Google: 1; Taobao: 3
(二)旧式字符串格式化
% 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串. 例如:
>>> import math
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
常量 PI 的值近似为:3.142。
因为 str.format() 是比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().
(三)读取键盘输入
Python提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘。
input 可以接收一个Python表达式作为输入,并将运算结果返回。
>>> str = input("请输入:");
请输入:14
>>> print('你输入的内容是:',str)
你输入的内容是: 14
(四)读和写文件
open() 将会返回一个 file 对象,基本语法格式如下:
open(filename, mode)
1.filename:包含了你要访问的文件名称的字符串值。
2.mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读®。
不同模式打开文件列表:
下图很好总结了这几种模式:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200917161534127.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG以下实例将字符串写入到文件foo.txt中:
#!/usr/bin/python3
# 打开一个文件
f = open("/tmp/foo.txt", "w")
f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
# 关闭打开的文件
f.close()
文件对象的方法
f.read()