1、python简介
1.0、python --version : 查看python版本
1.1、运行python脚本如下,如果是python2的话就是python hello.py;如果是python3的话就是python hello.py.
1.2、#!/usr/bin/python3:用来指定Python的解释器,并用只能应用于Linux、Mac等系统中,
1.3、#!/usr/bin/env python:防止当你写错或不写时报错或会不清楚解释器的具体全路径,或者说开发者的环境与最终使用者的安装路径不一样,它的作用是让env去查找python2的绝对路径替换作为解释器路径。
1.4、python和./执行效果一样,如果执行不成功,有可能是权限不够。
1.5、python的一个优点是可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"的能力。
1.6、Linux下安装以Python3.6.1 tar -zxvf Python-3.6.1.tgz cd Python-3.6.1 ./configure make && make install 检查 Python3 是否正常可用: python3 -V Python 3.6.1 1.7、环境变量配置 程序和可执行文件可以在许多目录,而这些路径很可能不在操作系统提供可执行文件的搜索路径中。 path(路径)存储在环境变量中,这是由操作系统维护的一个命名的字符串。这些变量包含可用的命令行解释器和其他程序的信息。 Unix 或 Windows 中路径变量为 PATH(UNIX 区分大小写,Windows 不区分大小写)。 echo
0
可
以
查
看
是
哪
个
s
h
e
l
l
在
b
a
s
h
s
h
e
l
l
(
L
i
n
u
x
)
输
入
:
e
x
p
o
r
t
P
A
T
H
=
"
0可以查看是哪个shell 在 bash shell (Linux) 输入 : export PATH="
0可以查看是哪个shell在bashshell(Linux)输入:exportPATH="PATH:/usr/local/bin/python" 注意: /usr/local/bin/python 是 Python 的安装目录。
1.8、运行python script.py # Unix/Linux
1.9、编码:默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码。
1.10、标识符 第一个字符必须是字母表中字母或下划线 _ 。 标识符的其他的部分由字母、数字和下划线组成。 标识符对大小写敏感。 在 Python 3 中,可以用中文作为变量名,非 ASCII 标识符也是允许的了。
1.11、python保留字 保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字: >>> import keyword >>> keyword.kwlist [‘False’, ‘None’, ‘True’, ‘and’, ‘as’, ‘assert’, ‘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’]
1.12、注释 Python中单行注释以 # 开头 多行注释可以用多个 # 号,还有 ‘’’ 和 “”":
1.13、行与缩进 python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {} 。缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。
1.14、Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \ 来实现多行语句,在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 \。
1.15、数字(Number)类型:python中数字有四种类型:整数、布尔型、浮点数和复数。
1.16字符串(String) Python 中单引号 ’ 和双引号 " 使用完全相同。 使用三引号(‘’’ 或 “”“)可以指定一个多行字符串。 转义符 \。 反斜杠可以用来转义,使用 r 可以让反斜杠不发生转义。 如 r"this is a line with \n” 则 \n 会显示,并不是换行。 按字面意义级联字符串,如 "this " "is " “string” 会被自动转换为 this is string。 字符串可以用 + 运算符连接在一起,用 * 运算符重复。 Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。 Python 中的字符串不能改变。 Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。 字符串的截取的语法格式如下:变量[头下标:尾下标:步长]
1.17、空行 函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。 空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。 记住:空行也是程序代码的一部分。 Python 可以在同一行中使用多条语句,语句之间使用分号 ; 分割,
1.18、print 输出 print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end=“”:
1.19、import 与 from…import 在 python 用 import 或者 from…import 来导入相应的模块。 将整个模块(somemodule)导入,格式为: import somemodule 从某个模块中导入某个函数,格式为: from somemodule import somefunction 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc 将某个模块中的全部函数导入,格式为: from somemodule import *
1.20、命令行参数 很多程序可以执行一些操作来查看一些基本信息,Python可以使用-h参数查看各参数帮助信息:
2、基本数据类型 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。 等号(=)用来给变量赋值。 等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。 Python允许你同时为多个变量赋值。 例如a = b = c = 1 a, b, c = 1, 2, “runoob”
2.1、Python3 的六个标准数据类型中: 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组); 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
2.2、Number(数字): 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。 内置的 type() 函数可以用来查询变量所指的对象类型。 isinstance 来判断是不是某个类型,ture/false isinstance 和 type 的区别在于: type()不会认为子类是一种父类类型。 isinstance()会认为子类是一种父类类型。 注意:Python3 中,bool 是 int 的子类,True 和 False 可以和数字相加, True1、False0 会返回 True,但可以通过 is 来判断类型。
2.3、数值运算 注意: 1、Python可以同时为多个变量赋值,如a, b = 1, 2。 2、一个变量可以通过赋值指向不同类型的对象。 3、数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数。 4、在混合计算时,Python会把整型转换成为浮点数。
2.4、String(字符串) 注意: 1、反斜杠可以用来转义,使用r可以让反斜杠不发生转义。 2、字符串可以用+运算符连接在一起,用*运算符重复。 3、Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。 4、Python中的字符串不能改变。 例如:str = ‘Runoob’
2.5、List(列表) List(列表) 是 Python 中使用最频繁的数据类型。 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。 索引值以 0 为开始值,-1 为从末尾的开始位置。 注意: 1、List写在方括号之间,元素用逗号隔开。 2、和字符串一样,list可以被索引和切片。 3、List可以使用+操作符进行拼接。 4、List中的元素是可以改变的。 例如:[‘abcd’, 786, 2.23, ‘runoob’, 70.2]
2.6、Tuple(元组) 元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。 string、list 和 tuple 都属于 sequence(序列)。 注意: 1、与字符串一样,元组的元素不能修改。 2、元组也可以被索引和切片,方法一样。 3、注意构造包含 0 或 1 个元素的元组的特殊语法规则。 4、元组也可以使用+操作符进行拼接。 例如:(‘abcd’, 786, 2.23, ‘runoob’, 70.2)
2.7、Set(集合) 集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。 基本功能是进行成员关系测试和删除重复元素。 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。 例如:sites = {‘Google’, ‘Taobao’, ‘Runoob’, ‘Facebook’, ‘Zhihu’, ‘Baidu’}
2.8、Dictionary(字典) 字典(dictionary)是Python中另一个非常有用的内置数据类型。 列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。 字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。 键(key)必须使用不可变类型。 在同一个字典中,键(key)必须是唯一的。 注意: 1、字典是一种映射类型,它的元素是键值对。 2、字典的关键字必须为不可变类型,且不能重复。 3、创建空字典使用 { }。 例如:tinydict = {‘name’: ‘runoob’,‘code’:1, ‘site’: ‘www.runoob.com’}
2.9、数据类型转换 有时候,我们需要对数据内置的类型进行转换,数据类型的转换,一般情况下你只需要将数据类型作为函数名即可。 Python 数据类型转换可以分为两种: 隐式类型转换 - 自动完成 显式类型转换 - 需要使用类型函数来转换 系统自带的类型转换: 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):将一个整数转换为一个八进制字符串
3.1、Python 推导式 Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。 Python 支持各种数据结构的推导式: 列表(list)推导式 举例:num_list=[i for i in range(0,10)] print(num_list) num_list=[i**2 for i in range(0,10) if i >6] print(num_list) 结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 结果:[7, 8, 9] 字典(dict)推导式 num_set={i for i in range(10)} print(num_set) num_set={i for i in range(10) if i>3} print(num_set) 结果:{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} {4, 5, 6, 7, 8, 9} 集合(set)推导式 num_dict={i:i for i in range(10)} print(num_dict) num_dict={i:i for i in range(10) if i>3} print(num_dict) 结果是:{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} {4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} 元组(tuple)推导式 data=(i for i in range(10)) print(data)# <generator object at 0x000000000213F190> print(type(data)) for i in data: print(i) 结果是:<generator object at 0x00000000039A4B40> <type ‘generator’>
3.2、Python3 运算符 Python 语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 运算符优先级 注意点:and 拥有更高优先级; 例如: if x or y and z: print(“yes”) else: print(“no”) 结果为yes
/home/xuweifeng/v90_wbx_2188_new/npti.src/npti_product/npt2700/build/buildmcp_eswp.sh 1>compile_err.log is 是判断两个标识符是不是引用自一个对象。 is not is not 是判断两个标识符是不是引用自不同对象。 例如: a = [1, 2, 3] b = a print (b is a) b = a[:] print (b is a) 结果: True False
3.3、Python3 数字(Number) Python 数字数据类型用于存储数值。 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间。 以下实例在变量赋值时 Number 对象将被创建: 举例:var1 = 1 del var
3.4、Python3 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号( ’ 或 " )来创建字符串。 创建字符串很简单,只要为变量分配一个值即可。 Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。 Python 访问子字符串,可以使用方括号 [] 来截取字符串,字符串的截取的语法格式如下: 变量[头下标:尾下标]
3.5、Python转义字符在菜鸟教程中。https://www.runoob.com/python3/python3-string.html
3.6、Python字符串运算符在菜鸟教程中。https://www.runoob.com/python3/python3-string.html
3.7、Python 字符串格式化在菜鸟教程中。举例:print (“我叫 %s 今年 %d 岁!” %(‘小明’, 10))
3.8、Python三引号:python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。 举例: para_str = “”“这是一个多行字符串的实例 多行字符串可以使用制表符 TAB ( \t )。 也可以使用换行符 [ \n ]。 “”” print (para_str) 以上实例执行结果为: 这是一个多行字符串的实例 多行字符串可以使用制表符 TAB ( )。 也可以使用换行符 [ ]。
3.9、Unicode 字符串 在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。 使用的语法是在字符串前面加上前缀 u。在Python3中,所有的字符串都是Unicode字符串。
3.10、Python 的字符串内建函数,在菜鸟教程中。
2、python列表
Python 有 6 个序列的内置类型,但最常见的是列表和元组。
列表的数据项不需要具有相同的类型,即元素可以不同。
列表都可以进行的操作包括索引,切片,加,乘,检查成员。
此外,Python 已经内置确定序列的长度以及确定最大和最小的元素的方法。
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:
list1 = [‘Google’, ‘Runoob’, 1997, 2000]
print (list[0]) 结果:Google
print(list[-1]) 结果:2000
print (list[0:2]) 结果:['Google', 'Runoob']
print ("list[0]:", list[0]) 结果:list[0]: Google
list.append('Baidu') 结果:['Google', 'Runoob', 1997, 2000, 'Baidu']
list.remove(2000) 结果:['Google', 'Runoob', 1997]
list1 = list.copy() 结果:['Google', 'Runoob', 1997, 2000]
list1 = list.clear() 结果:None
list.insert(1, '3000') 结果:['Google', '3000', 'Runoob', 1997, 2000]
3、python元组
①、python的元组与列表类似,不同之处在于元组的元素不能修改。元组中的数据不能够改变。
②、元组使用小括号( ),列表使用方括号[ ]。
③、元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
tup1 = ('Google', 'Runoob', 1997, 2000) 结果:('Google', 'Runoob', 1997, 2000)
tup1 = () 创建空元组 结果:()
type(tup1) 结果:<class 'tuple'>
print(tup1[0]) 结果:Google
tup2 = ('abc',) tup3 = tup1 + tup2 结果:('Google', 'Runoob', 1997, 2000, 'abc')
del tup3 结果:整个删除tup3,打印报错
list1= ['Google', 'Taobao', 'Runoob', 'Baidu'] 结果:['Google', 'Taobao', 'Runoob', 'Baidu']
tuple1=tuple(list1) 作用:将可迭代系列转换为元组。 结果:('Google', 'Taobao', 'Runoob', 'Baidu')
print(max(tuple1)) 结果是Taobao
4、Python 字典
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中。
注意①、键必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
②、tinydict2 = { ‘abc’: 123, 98.6: 37 }
③、元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
④、键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行。
emptyDict = {} 结果是{}
emptyDict = dict() 结果是{}
print(type(emptyDict)) 结果是<class 'dict'>
tinydict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
print(tinydict['Name']) 结果是Runoob
注意:如果用字典里的没有的键访问数据,会输出错误。
tinydict['Age'] = 8 结果是{'Name': 'Runoob', 'Age': 8, 'Class': 'First'} 注意:键值是唯一的。
tinydict.clear() 结果是{}
del tinydict 结果是整个删除,打印会报错
len(tinydict) 结果是3
print((tinydict.popitem())) 结果是('Class', 'First')
5、Python 集合
①、集合(set)是一个无序的不重复元素序列。
②、可以使用大括号{ }或者set()函数创建集合,注意:创建一个空集合必须用set()而不是{ },因为{ }是用来创建一个空字典。
a = set('abracadabra') 结果是{'a', 'r', 'b', 'c', 'd'}
b = set('a') 结果是{'d', 'c', 'b', 'r'}
注意:-是集合a中包含而集合b中不包含的元素; |是集合a或b中包含的所有元素; &是集合a和b中都包含了的元素;+是不能用于set与set相加。
a = {x for x in 'abracadabra' if x not in 'abc'} 结果是:{'d', 'r'}
thisset = set({'Coogle', 'Bunoob', 'Daobao'})
thisset.add('Aacebook') 结果是{'Aacebook', 'Daobao', 'Bunoob', 'Coogle'}
thisset.update({1, 2}) 结果是{1, 2, 'Bunoob', 'Daobao', 'Coogle'}
注意:update同样可以添加元素,并且参数可以是列表,元组,字典等。
thisset.remove(1) 结果是:{'Daobao', 2, 'Coogle', 'Bunoob'}
注意:将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。
thisset.discard(1) 结果是{'Coogle', 'Bunoob', 'Daobao'}
注意:此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。
thisset.pop() 结果是随机删除集合中的一个元素。
print(a , end)
print(b) 结果是a,b
注意:关键字end可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符。
- 1、每个条件后面要使用冒号 **:**,表示接下来是满足条件后要执行的语句块。
- 2、使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
- 3、在Python中没有switch – case语句。
a = 0
if 1 == a :
print('a = ', a)
elif 2 == a :
print('a = ', a)
else:
print('a = ', a)
a = 0
if 1 == a :
print('a = ', a)
if 2 == a :
print('a = ', a)
else:
print('a = ', a)
else:
print('a = ', a)
a = 1
while a < 10:
print('a = ', a)
a += 2
结果是
a = 1
a = 3
a = 5
a = 7
a = 9
注意:同样需要注意冒号和缩进。另外,在 Python 中没有 do..while 循环。
count = 0
while count < 5:
print (count, "小于 5")
count += 1
else:
print (count, " 大于或等于 5")
结果是
0 小于 5
1 小于 5
2 小于 5
3 小于 5
4 小于 5
5 大于或等于 5
languages = ['C', 'C++', "Perl", 'Python']
for x in languages:
print(x)
结果是:
C
C++
Perl
Python
注意;python for循环可以遍历任何可迭代对象,如一个列表或者一个字符串。
for i in range(5):
print(i)
结果:
0
1
2
3
4
注意:break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
n = 5
while n > 0:
n -= 1
if n == 2:
break
print(n)
print('循环结束。')
结果:
4
3
循环结束。
n = 5
while n > 0:
n -= 1
if n == 2:
continue
print(n)
print('循环结束。')
结果:
4
3
1
0
循环结束。
注意:循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被 break 终止时不执行。
for letter in 'Runoob':
if letter == 'o':
pass
print('执行 pass 块')
print('当前字母 :', letter)
print("Good bye")
结果:
当前字母 : R
当前字母 : u
当前字母 : n
执行 pass 块
当前字母 : o
执行 pass 块
当前字母 : o
当前字母 : b
Good bye
注意:Python pass是空语句,是为了保持程序结构的完整性。
pass不做任何事情,一般用来做占位语句。
6、Python 迭代器与生成器
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")
结果:1 2 3 4
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
while True:
try:
print(next(it))
except StopIteration:
sys.exit()
结果:
1
2
3
4
创建一个迭代器
把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。
如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 init(), 它会在对象初始化的时候执行。
更多内容查阅:Python3 面向对象
iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成。
next() 方法(Python 2 里是 next())会返回下一个迭代器对象。
创建一个返回数字的迭代器,初始值为 1,逐步递增 1:
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
结果:
1
2
3
4
5
注意:StopIteration
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
、生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
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()
结果:
0 1 1 2 3 5 8 13 21 34 55
7、python 函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
7.1、定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号 : 起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
def max(a, b):
if a > b:
return a
else:
return b
a = 4
b = 5
print(max(a, b))
结果:
5
a=5
print(id(a))
a=6
print(id(a))
结果:
1600492759472
1600492759504
def change(a):
print(id(a))
a = 10
print(id(a))
a=1
print(id(a))
change(a)
结果:
2793531468080
2793531468080
2793531468368
注意:可以看见在调用函数前后,形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的 id。
def changeme(mylist):
mylist.append([1,2,3,4])
print("函数内取值:", mylist)
return
#调用changeme函数
mylist = [10, 20,30]
changeme(mylist)
print("函数外取值:", mylist)
结果:
函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]
#可写函数说明
def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )
结果:
名字: runoob
年龄: 50
------------------------
名字: runoob
年龄: 35
类似于C++缺省参数
def printinfo(arg1, *vartuple):
print("输出:")
print(arg1)
print(vartuple)
printinfo(70, 60,50)
结果:
输出:
70
(60, 50)
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
- **不可变类型:**变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
- **可变类型:**变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- **不可变类型:**类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
- **可变类型:**类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
参数
以下是调用函数时可使用的正式参数类型:
-
必需参数:必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。例如 def printme(str) printme()错误 -
关键字参数:关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。 def printme(str) printme(str= “菜鸟教程”) 正确 -
默认参数:调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值。也即是C++中的缺省参数。 def printinfo( name, age = 35 ) printinfo( name=“runoob” ) -
强制位置参数:Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参: def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
正确写法:f(10, 20, 30, d=40, e=50, f=60)
错误写法1:f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
错误写法2:f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式
-
不定长参数:你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。def printinfo( arg1, *vartuple ) printinfo( 70, 60, 50 ) 结果:70 (60, 50) ①、加了星号 ***** 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。 ②、加了两个星号 ** 的参数会以字典的形式导入。
8、匿名函数
Python使用lambda来创建匿名函数,所谓匿名,意即不再使用def语句这样的标准形式定义一个函数。
①、lambda只是一个表达式,函数体比def简单很多。
②、lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
③、lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
④、虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
结果:
相加后的值为 : 30
相加后的值为 : 40
def myfunc(n):
return lambda a : a * n
mydoubler = myfunc(2)
mytripler = myfunc(3)
print(mydoubler(11))
print(mytripler(11))
结果:
22
33
def sum(arg1, arg2):
total = arg1 + arg2
print("函数内:", total)
return total
total = sum(10, 20)
print("函数外:", total)
结果:
函数内 : 30
函数外 : 30
7、python 数据结构
列表:python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能。
列表:
a = [66.25, 333, 333, 1, 1234.5]
print(a.count(333), a.count(66.25), a.count('x'))
结果:2 1 0
a.reverse()
结果:[333, 1234.5, 1, 333, -1, 66.25]
a.sort()
结果:[-1, 1, 66.25, 333, 333, 1234.5]
注意:类似 insert, remove 或 sort 等修改列表的方法没有返回值。
将列表当做堆栈使用
列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。
stack = [3, 4, 5]
stack.append(6)
stack.append(7)
print(stack)
stack.pop()
print(stack)
stack.pop()
print(stack)
结果:
[3, 4, 5, 6, 7]
[3, 4, 5, 6]
[3, 4, 5]
将列表当作队列使用
也可以把列表当做队列用,只是在队列里第一加入的元素,第一个取出来;但是拿列表用作这样的目的效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)。
from collections import deque
queue = deque(["Eric", "John", "Michael"])
queue.append("Terry")
queue.append("Graham")
print(queue)
queue.popleft() #第一个到达的现在离开
print(queue)
queue.popleft()
print(queue)
结果:
deque(['Eric', 'John', 'Michael', 'Terry', 'Graham'])
deque(['John', 'Michael', 'Terry', 'Graham'])
deque(['Michael', 'Terry', 'Graham'])
列表推导式
列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。
每个列表推导式都在 for 之后跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。
>>> 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]]
del语句
使用del语句可以从一个列表中根据索引来删除一个元素,而不是值来删除元素,这与使用pop()返回一个值不同。可以用del语句从列表中删除一个切割,或清空整个列表。
a = [-1, 1, 66.25, 333, 333, 1234.5]
del a[0]
print(a)
del a[1:3]
print(a)
del a[:]
print(a)
结果:
[1, 66.25, 333, 333, 1234.5]
[1, 333, 1234.5]
[]
元组和序列
元组由若干逗号分隔的值组成,用括号括起来,注意也可以在定义时没有括号。
t = (12345, 54321, 'hello!')
print(t)
print(type(t))
t = 12345, 54321, 'hello!'
print(t)
print(type(t))
结果:
(12345, 54321, 'hello!')
<class 'tuple'>
(12345, 54321, 'hello!')
<class 'tuple'>
集合
集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。
可以用大括号({})创建集合。注意:如果要创建一个空集合,你必须用 set() 而不是 {} ;后者创建一个空的字典
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket) # 删除重复的
print(type(basket))
结果:{'orange', 'banana', 'pear', 'apple'}
<class 'set'>
字典
另一个非常有用的 Python 内建数据类型是字典。
序列是以连续的整数为索引,与此不同的是,字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。
理解字典的最佳方式是把它看做无序的键=>值对集合。在同一个字典之内,关键字必须是互不相同。一对大括号创建一个空的字典:{}。
tel = {'jack':4998, 'sape':4139}
print(tel)
print(type(tel))
tel['guido'] = 4127
print(tel)
print('guido' in tel)
结果:
{'jack': 4998, 'sape': 4139}
<class 'dict'>
{'jack': 4998, 'sape': 4139, 'guido': 4127}
True
8、python 模块
在前面的几个章节中我们基本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。
为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。
import 语句
想使用 Python 源文件,只需在另一个源文件里执行 import 语句。当解释器遇到impo语句,如果模块在当前的搜索路径就会被导入。搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support,需要把命令放在脚本的顶端。
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
当我们使用import语句的时候,Python解释器是怎样找到对应的文件的呢?这就涉及到Python的搜索路径,搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块。
这看起来很像环境变量,事实上,也可以通过定义环境变量的方式来确定搜索路径。
搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量。
from … import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。
from fibo import fib, fib2
注意:这个声明不会把整个fibo模块导入到当前的命名空间中,它只会将fibo里的fib函数引入进来。
from … import * 语句
from modname import *
注意:这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
import sys
print('命令行参数如下:')
for i in sys.argv:
print(i)
print('\n\npython 路径为:', sys.path, '\n')
结果:
命令行参数如下:
C:/Users/breeze/PycharmProjects/pythonProject/main.py
python 路径为: ['C:\\Users\\breeze\\PycharmProjects\\pythonProject', 'C:\\Users\\breeze\\PycharmProjects\\pythonProject', 'D:\\JetBrains\\PyCharm 2021.2\\plugins\\python\\helpers\\pycharm_display', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39\\python39.zip', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39\\DLLs', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39\\lib', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39', 'C:\\Users\\breeze\\PycharmProjects\\pythonProject\\venv', 'C:\\Users\\breeze\\PycharmProjects\\pythonProject\\venv\\lib\\site-packages', 'D:\\JetBrains\\PyCharm 2021.2\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
Process finished with exit code 0
import sys
print(sys.path)
注意:
['C:\\Users\\breeze\\PycharmProjects\\pythonProject', 'C:\\Users\\breeze\\PycharmProjects\\pythonProject', 'D:\\JetBrains\\PyCharm 2021.2\\plugins\\python\\helpers\\pycharm_display', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39\\python39.zip', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39\\DLLs', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39\\lib', 'C:\\Users\\breeze\\AppData\\Local\\Programs\\Python\\Python39', 'C:\\Users\\breeze\\PycharmProjects\\pythonProject\\venv', 'C:\\Users\\breeze\\PycharmProjects\\pythonProject\\venv\\lib\\site-packages', 'D:\\JetBrains\\PyCharm 2021.2\\plugins\\python\\helpers\\pycharm_matplotlib_backend']
深入模块
模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。
每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。
所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞混。
从另一个方面,当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。
模块是可以导入其他模块的。在一个模块(或者脚本,或者其他地方)的最前面使用 import 来导入一个模块,当然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。
还有一种导入的方法,可以使用 import 直接把模块内(函数,变量的)名称导入到当前操作模块。
__name__属性
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
dir() 函数
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回。
标准模块
Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。
有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。
这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。
应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串
包
包是一种管理 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。 他必须使用全名去访问:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
还有一种导入子模块的方法是:
from sound.effects import echo
这同样会导入子模块: echo,并且他不需要那些冗长的前缀,所以他可以这样使用:
echo.echofilter(input, output, delay=0.7, atten=4)
还有一种变化就是直接导入一个函数或者变量:
from sound.effects.echo import echofilter
同样的,这种方法会导入子模块: echo,并且可以直接使用他的 echofilter() 函数:
echofilter(input, output, delay=0.7, atten=4)
注意当使用 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 也更新了啊。
9、Python 输入和输出
把输出的值转成字符串:
- str(): 函数返回一个用户易读的表达形式。
- repr(): 产生一个解释器易读的表达形式。
用户可以每次只导入一个包里面的特定模块,比如:
import math
print("常量PI的值近似为:%5.3f." %math.pi)
结果:常量PI的值近似为:%5.3f. 3.141592653589793
读取键盘输入
str = input("请输入:")
print("你输入的内容是:", str)
结果:
请输入:菜鸟教程
你输入的内容是: 菜鸟教程
python 文件方法
open() 将会返回一个 file 对象,基本语法格式如下:
open(filename, mode)
- filename:包含了你要访问的文件名称的字符串值。
- mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读?。
# 打开一个文件 首先这个文件要存在,在windows下是C:tmp/foo.txt
f = open("/tmp/foo.txt", "w")
f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
f = open("/tmp/foo.txt", "r")
str = f.read()
print(str)
# 打开一个文件
f = open("/tmp/foo.txt", "r")
str = f.readline()
print(str)
# 关闭打开的文件
f.close()
结果:
Python 是一个非常好的语言。
# 打开一个文件
f = open("/tmp/foo.txt", "r")
str = f.readlines()
print(str)
# 关闭打开的文件
f.close()
结果:
['Python 是一个非常好的语言。\n', '是的,的确非常好!!\n']
# 打开一个文件
f = open("/tmp/foo.txt", "w")
num = f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
print(num)
# 关闭打开的文件
f.close()
结果:29
注意:f.write(string)将string写入到文件中,然后返回写入的字符数。
# 打开一个文件
f = open("/tmp/foo1.txt", "w")
value = ('www.runoob.com', 14)
s = str(value)
f.write(s)
# 关闭打开的文件
f.close()
结果:('www.runoob.com', 14)
注意:如果要写入一些不是字符串的东西,那么需要将它先进行转换。
>>> f.close()
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file
Python3 OS 文件/目录方法
os 模块提供了非常丰富的方法用来处理文件和目录。
|