python相关知识

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=" 0shellbashshell(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 模块提供了非常丰富的方法用来处理文件和目录。


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值