python3 - 入门导读

简单记录python的基础语法

Posted by LOLITA0164 on February 28, 2019

Python 是一门简单易学并且功能强大的编程语言。它拥有高效的高级数据结构,并且能够简单而又高效的方式进行面向对象编程。Python 优雅的语法和动态类型,再结合它的解释性,使其在大多数平台的许多领域成为编写脚本或者开发应用程序的理想语言。

你可以自由地从 Python 官方点:http://www.python.org,以源代码或者二进制形式获取 Python 解释器及其标准扩展库,并可以自由的分发。此站点同时也提供了大量的第三方 Python 模块、程序和工具,及其附加文档。

如果需要了解相关标准库或者对象的详细介绍,请查阅 Python 参考文档


环境搭建

两种编程方式

交互式编程

我们可以在命令提示符/终端中输入”Python”命令来启动Python解释器:$ python3

执行上述命令之后,窗口信息显示如下:

Python 3.5.0 (v3.5.0:374f501f4567, Sep 12 2015, 11:00:19) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 

在 python 提示符中输入以下语句,然后按回车键查看运行效果:

>>> 1+2
3
>>> print("hello,world")
hello,world
>>> 

脚本式编程

将如下代码拷贝至 hello.py文件中:

print ("Hello, world!");

通过以下命令执行该脚本:

python3 hello.py

输出结果为:

Hello, world!

基础语法

编码

默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码:

# -*- coding: cp-1252 -*-

标识符命名规则

  • 首字母必须是字母或者下划线’_’
  • 其他部分由字母、数字、或下划线组成
  • 大小写敏感

保留字

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']

注释

  • 单行注释

在 Python 中使用 # 进行单行注释

# 第一个注释
print ("Hello, Python!") # 第二个注释
  • 多行注释

可以使用 ''' 或者 """ 进行多行注释

'''
第一注释
第二注释
'''
 
"""
第三注释
第四注释
"""

行与缩进

Python 中,使用缩进来表示代码块,不需要使用大括号 {},但是,同一个代码块的语句必须包含相同的缩进空格数,否则会抛出异常。

if True:
    print ("True")
else:
    print ("False")

多行语句

如果语句很长,我们可以使用反斜杠 \ 来实现多行语句。

total = item_one + \
        item_two + \
        item_three

但是在 []、{} 或 () 中,不需要使用反斜杠。

total = ['item_one', 'item_two', 'item_three',
        'item_four', 'item_five']

数字类型

在 Python 中,有四种数字类型:整数、布尔型、浮点型、复数

  • int,如1
  • bool,True 和 Flase (大小写敏感)
  • float,如1.23
  • complex,如 1+2j

字符串

  • 单引号和双引号作用一致
  • 使用 '''""" 可以指定多行字符串
  • 反斜杠用来转义,使用 r 可以让反斜杠不发生转移。 如 r”this is a line with \n” 则\n会显示,并不是换行。
  • 可以使用 + 来进行字符串拼接,使用 * 来重复
  • 字符串是不可变类型,不能改变
  • 没有字符类型,字符就是长度为 1 的字符串
  • 字符串可以类似列表一样进行遍历,截取:string[头下标:尾下标:步长]
word = '字符串'
sentence = "这是一个句子。"
paragraph = """这是一个段落,
可以由多行组成"""

str='Runoob'
 
print(str)                 # 输出字符串
print(str[0:-1])           # 输出第一个到倒数第二个的所有字符
print(str[0])              # 输出字符串第一个字符
print(str[2:5])            # 输出从第三个开始到第五个的字符
print(str[2:])             # 输出从第三个开始的后的所有字符
print(str * 2)             # 输出字符串两次
print(str + '你好')        # 连接字符串

多个语句构成的代码组

缩进相同的一组语句构成一个代码块,我们称之为代码组。

类似的,if、while、def 和 class 这样的复合语句,首行以关键字开始,以冒号结束,该行之后代码都成代码组。

if expression : 
   suite
elif expression : 
   suite 
else : 
   suite

print 默认输出是换行的,如果要补换行,需要在变量末尾加上 end="";

x="a"
# 换行输出
print( x )
 
# 不换行输出
print( x, end=" " )

import 与 from……import

  • 将整个模块(somemodule)导入,格式为: import somemodule
  • 从某个模块中导入某个函数,格式为: from somemodule import somefunction
  • 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
  • 将某个模块中的全部函数导入,格式为: from somemodule import *

条件控制

if 语句

Python中if语句的一般形式如下所示:

if condition_1:
   statement_block_1
elif condition_2:
   statement_block_2
else:
   statement_block_3

Python 中用 elif 代替了 else if,所以if语句的关键字为:if – elif – else。

  1. 每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语句块。
  2. 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
  3. 在Python中没有switch – case语句。

循环语句

  • while 循环

Python中while语句的一般形式:

while 判断条件:
    语句
  • for 语句

Python中for循环的一般格式如下:

for <variable> in <sequence>:
    <statements>
else:
    <statements>
  • 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(0, 10, 3) :
    print(i)   
0
3
6
9

数据类型

Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋之后该变量才会被创建。

Python 中,变量就是变量,它没有类型,我们所说的 “类型” 是变量所指的内存中对象的类型。

counter = 100          # 整型变量
miles   = 1000.0       # 浮点型变量
name    = "runoob"     # 字符串

a = b = c = 1				# 多个变量赋值
a, b, c = 1, 2, "runoob" # 多个变量赋值

标准数据类型

Python3 中有六个标准的数据类型:

  1. Number(数字)

  2. String(字符串)

  3. List(列表)

  4. Tuple(元组)

  5. Set(集合)

  6. Dictionary(字典)

Python3 的六个标准数据类型中:

  • 不可变数据(3个):Number(数字)、String(字符串)、Tuple(元组)

  • 可变数据(3个):List(列表)、Dictionary(字典)、Set(集合)

内置函数 type() 可以用来查询变量所指的对象类型,isinstance() 也是类似的,区别在于,type() 不会认为子类是父类类型,isinstance() 则认为子类是父类的一种类型。

Number 数字

>>>5 + 4  # 加法
9
>>> 4.3 - 2 # 减法
2.3
>>> 3 * 7  # 乘法
21
>>> 2 / 4  # 除法,得到一个浮点数
0.5
>>> 2 // 4 # 除法,得到一个整数
0
>>> 17 % 3 # 取余 
2
>>> 2 ** 5 # 乘方
32

注意:

  • Python 可以同时为多个变量赋值,如a, b = 1, 2
  • 一个变量可以通过赋值指向不同类型的对象,变量类型由最后赋值的对象相同
  • 数值的除法包含两个运算符:/ 返回一个浮点数,// 返回一个整数
  • 在混合计算时,Python会把整型转换成为浮点数

String 字符串

Python中的字符串用单引号 ‘ 或双引号 “ 括起来,同时使用反斜杠 \ 转义特殊字符。

字符串的截取的语法格式如下:

变量[头下标:尾下标:步长]

实例:

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

Python 的字符串内建函数:

函数 说明
capitalize() 首字母转换为大写
count(str, beg= 0,end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数
endswith(suffix, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False
startswith(substr, beg=0,end=len(string)) 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查
find(str, beg=0 end=len(string)) 检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1
isdigit() 如果字符串只包含数字则返回 True 否则返回 False
islower() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False
isupper() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False
join(seq) 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
len(string) 返回字符串长度
strip() 截掉字符串左右两边的空格或指定字符
replace(old, new [, max]) 把 将字符串中的 str1 替换成 str2,如果 max 指定,则替换不超过 max 次
split(str=””, num=string.count(str)) num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串
lower() 转换字符串中所有大写字符为小写
upper() 转换字符串中的小写字母为大写

List 列表

List(列表) 是 Python 中使用最频繁的数据类型。

列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。

列表是写在方括号 [] 之间、用逗号分隔开的元素列表。

和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。

字符串的截取的语法格式如下:

变量[头下标:尾下标:步长]

实例:

list = [ 'abcd', 786 , 2.23, 'runoob', 70.2 ]
tinylist = [123, 'runoob']
 
print (list)            # 输出完整列表
print (list[0])         # 输出列表第一个元素
print (list[1:3])       # 从第二个开始输出到第三个元素
print (list[2:])        # 输出从第三个元素开始的所有元素
print (tinylist * 2)    # 输出两次列表
print (list + tinylist) # 连接列表

列表中的元素是可以改变的:

>>>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]

除此之外,Python 内置了很多操作列表方法。

函数 说明
len(list) 列表中元素个数
max(list) 列表中最大值
min(list) 列表中最小值
list(seq) 将元组转换为列表
list.append(obj) 在列表末尾添加新的对象
list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.insert(index, obj) 将对象插入列表
list.count(obj) 统计某个元素在列表中出现的次数
list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
list.remove(obj) 移除列表中某个值的第一个匹配项
list.clear() 清空列表
list.reverse() 反向列表中元素
list.sort( key=None, reverse=False) 对原列表进行排序
list.copy() 复制列表(浅拷贝)

Tuple 元组

元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在()里,元素之间用逗号隔开。元组中的元素类型也可以不相同。

tuple = ( 'abcd', 786 , 2.23, 'runoob', 70.2  )
tinytuple = (123, 'runoob')
 
print (tuple)             # 输出完整元组
print (tuple[0])          # 输出元组的第一个元素
print (tuple[1:3])        # 输出从第二个元素开始到第三个元素
print (tuple[2:])         # 输出从第三个元素开始的所有元素
print (tinytuple * 2)     # 输出两次元组
print (tuple + tinytuple) # 连接元组

构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:

tup1 = ()    # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号

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

由于元组是不可变类型,针对元组的操作相对于列表就少了很多。

函数 说明
len(tuple) 列表中元素个数
max(tuple) 列表中最大值
min(tuple) 列表中最小值
tuple(seq) 将列表转换为元组

Set 集合

集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员。

基本功能是进行成员关系测试删除重复元素

可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

创建格式:

parame = {value01,value02,...}
或者
set(value)

实例:

>>>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'}

集合内置方法完整列表

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

Dictionary 字典

字典是 Python中另外一个非常有用的内置数据类型。

列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。

键(key)必须使用不可变类型。

在同一个字典中,键(key)必须是唯一的。

dict = {}					  # 空字典
dict['one'] = "1 - 菜鸟教程"	# 添加元素1
dict[2]     = "2 - 菜鸟工具"	# 添加元素1
 
tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'}
 
print (dict['one'])       # 输出键为 'one' 的值
print (dict[2])           # 输出键为 2 的值
print (tinydict)          # 输出完整的字典
print (tinydict.keys())   # 输出所有键
print (tinydict.values()) # 输出所有值

构造函数 dict() 可以直接从键值对序列中构建字典如下:

>>>dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)])
{'Taobao': 3, 'Runoob': 1, 'Google': 2}
 
>>> {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}

字典内置函数&方法

函数 说明
len(dict) 计算字典元素个数
str(dict) 输出字典,以可打印的字符串表示
dict.clear() 删除字典内所有元素
dict.copy() 返回一个字典的浅复制
dict.fromkeys() 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回default值
key in dict 如果键在字典dict里返回true,否则返回false
dict.items() 以列表返回可遍历的(键, 值) 元组数组
dict.keys() 返回一个迭代器,可以使用 list() 来转换为列表
dict.setdefault(key, default=None) 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
dict.update(dict2) 把字典dict2的键/值对更新到dict里
dict.values() 返回一个迭代器,可以使用 list() 来转换为列表
pop(key[,default]) 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值
popitem() 随机返回并删除字典中的一对键和值(一般删除末尾对)

数据类型转换

如果需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可。

函数 说明
int(x [,base]) 将x转换为一个整数
float(x) 将x转换到一个浮点数
complex(real [,imag]) 创建一个复数
str(x) 将对象 x 转换为字符串
repr(x) 将对象 x 转换为表达式字符串
tuple(s) 将序列 s 转换为一个元组
list(s) 将序列 s 转换为一个列表
set(s) 转换为可变集合
dict(d) 创建一个字典。d 必须是一个序列 (key,value)元组
frozenset(s) 转换为不可变集合
chr(x) 将一个整数转换为一个字符
ord(x) 将一个字符转换为它的整数值
hex(x) 将一个整数转换为一个十六进制字符串
oct(x) 将一个整数转换为一个八进制字符串

运算符

Python 中支持以下类型的运算符:

  1. 算术运算符
  2. 比较(关系)运算符
  3. 赋值运算符
  4. 逻辑运算符
  5. 位运算符
  6. 成员运算符
  7. 身份运算符
  8. 运算符优先级

Python中的运算符的操作和其他语言大体相似,这里只介绍一些比较特别的运算符。

  • 算术运算符
运算符 说明 实例
** 幂 - 返回x的y次幂 2**3 为2的3次方
// 取整除 - 向下取接近除数的整数 9//2 结果为4
  • 赋值运算符
运算符 说明 实例
**= 幂赋值运算符 c **= a 等效于 c = c ** a
//= 取整除赋值运算符 c //= a 等效于 c = c // a
  • 逻辑运算符

假设变量 a 为 10, b为 20:

运算符 说明 实例
and x and y,布尔”与” - 如果 x 为 False,x and y 返回 False,否则它返回 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
  • 成员运算符
运算符 说明 实例
in 如果在指定的序列中找到值返回 True,否则返回 False x 在 y 序列中 , 如果 x 在 y 序列中返回 True
not in 如果在指定的序列中没有找到值返回 True,否则返回 False x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True
  • 身份运算符
运算符 说明 实例
is is 是判断两个标识符是不是引用自一个对象 x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is not is not 是判断两个标识符是不是引用自不同对象 x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False

id()函数用于获取对象内存地址。

is 与 == 区别:

is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。

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

函数

函数是实现相关功能,可重复使用的代码片段,它可以提用应用的模块性,和代码l重复利用率。

定义一个函数

函数定义使用 def 开头

语法

def 函数名 (参数列表) :
	函数体

实例:

>>>def hello() :
   print("Hello World!")
 
>>> hello()
Hello World!

参数传递

  • 不可变类型: 类似 c++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身,如果此时在函数内部修改 a 的值,只是修改了另外一个复制的对象,不会影响 a 本身。
  • 可变类型: 类似 c++ 的引用传递 ,如列表、字典。如 fun(1),则是将 a 真正的传过去,此时在函数内部修改 a 的值,函数外部再次使用 a 时,已经是修改后的值。
def ChangeInt( a ):
    a = 10
 
b = 2
ChangeInt(b)
print( b ) # 结果是 2

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]]

参数

Python中,调用函数时可以使用以下几种正式参数类型:

  1. 必需参数
  2. 关键字参数
  3. 默认参数
  4. 不定长参数

必须参数

必须参数必须以正确的顺序传入函数,调用时的数量必须和声明时一致。

def printme( str ):
   print (str)
   return
 
# 调用printme函数,不传递必须参数,此时会发生异常
printme()

关键字参数

关键字参数和函数调用有着密切关系,函数调用使用关键字参数来确定传入的参数值。

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

def printinfo( name, age ):
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数, 直接使用 key 指定值
printinfo( age=50, name="runoob" )

默认参数

在自定义函数时候,我们有时候会设置一些默认参数,此时,当我们调用时,就可以不传递这类参数,而采用默认参数值。

def printinfo( name, age = 35 ):
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数,age采用默认值
printinfo( name="runoob" )

不定长参数

如果你需要一个函数能处理比预期更多的参数时,就可以使用不定长参数,和之前的几种参数不同,不定长参数声明时不会命名。

def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]

加了 * 的参数会以元组的形势导入,存放所有未命名的变量参数。

def printinfo( arg1, *vartuple ):
   print (arg1)
   print (vartuple)
 
# 调用printinfo 函数
printinfo( 70, 60, 50 )

# 输出:
70
(60, 50)

还有一种加了 ** 的参数,这种会以字典的形式导入。

def printinfo( arg1, **vardict ):
   print ("输出: ")
   print (arg1)
   print (vardict)
 
# 调用printinfo 函数
printinfo(1, a=2,b=3)

# 输出
1
{'a': 2, 'b': 3}

匿名函数

使用 lambda 来创建匿名函数。

所谓匿名,即不再使用 def 语句这样标准的形式来定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda 的主体是一个表达式,而不是一个代码块。仅仅能再 lambda 表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。

语法:

lambda [arg1 [,arg2,…..argn]]:expression

实例:

sum = lambda arg1, arg2: arg1 + arg2
 
# 调用sum函数
sum(10, 20)

变量的作用域

Python中,程序的变量并不是在哪个位置都可以访问,访问权限决定于这个变量是在哪里赋值的。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:

  1. L(Local)局部作用域
  2. E(Enclosing)闭包函数外的函数中
  3. G(Global)全局作用域
  4. B(Built-in)内置作用域(内置函数所在模块的范围)

查找循序为:L -> E -> G -> B,即:在局部找不到,便会去局部外的局部找(例如闭包中),再找不到就会去全局找,再去内置中找。

g_count = 0  # 全局作用域
def outer():
    o_count = 1  # 闭包函数外的函数中
    def inner():
        i_count = 2  # 局部作用域

Python中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其他的代码块(如if/elif/else、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如:

>>> if True:
...  msg = 'I am from Runoob'
... 
>>> msg
'I am from Runoob'

而将 msg 定义在函数中,则它就是局部变量,外部不能访问。

全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

total = 0 # 这是一个全局变量
def sum( arg1, arg2 ):
    total = arg1 + arg2 # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)
    return total
 
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)
# 输出
函数内是局部变量 :  30
函数外是全局变量 :  0

globalnonlocal 关键字

那么,当内部作用域想要修改外部作用域的变量时,我们就需要 globalnonlocal 关键字类。

num = 1
def fun1():
    global num  # 需要使用 global 关键字声明
    num = 123
    
fun1()
print(num)

# 输出
123

如果要修改嵌套作用域(enclosing作用域,外层非全局作用域 )中的变量则需要 nonlocal 关键字了,如:

def outer():
    num = 10
    def inner():
        nonlocal num   # nonlocal关键字声明
        num = 100
        print(num)
    inner()
    print(num)
outer()

# 输出
100
100

迭代器和生成器

迭代器

迭代器是 Python 最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个可以记住遍历位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

迭代器只能往前不会后退。

迭代器有两个基本的方法:iter()next()

序列(sequence)都可以用于创建迭代器,如字符串、列表或元组对象。

手动进行迭代

>>>list=[1,2,3,4]
>>> it = iter(list)    # 创建迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
1
>>> print (next(it))
2

在常规 for 语句中进行遍历:

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")

# 输出
1 2 3 4

自定义迭代器

自定义迭代器需要在类中实现两个方法 __iter__()__next__()

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

__next__() 方法会返回下一个迭代器对象。

实例:

创建一个返回数字的迭代器,初始值为1,逐步递增返回1:

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    if self.a <= 10:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration # 抛出异常,标识迭代完成
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print (x, end=" ")
  
# 输出
1 2 3 4 5 6 7 8 9 10

生成器

在Python中,可以使用关键字 yield 来创建生成器。

和普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作。

在调用生成器运行的过程中,每次遇到 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()
        
# 输出
0 1 1 2 3 5 8 13 21 34 55

异常处理

异常

及时 Python 程序的语法没有错误,在运行期间,也有可能发生错误。运行期间检测到的错误被称为异常,大多数的异常并不会被程序处理,都是以错误信息的形式展现:

>>>10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly

异常处理

我们使用 try/except 语句来处理异常。

>>>while True:
        try:
            x = int(input("Please enter a number: "))
            break
        except ValueError:
            print("Oops!  That was no valid number.  Try again   ")

try 语句的工作方式如下:

  1. 首先,执行 try 子语句
  2. 如果没有异常发生,则忽略 except 子句,try子句执行后结束
  3. 如果发生异常,那么 try 子句剩下的部分将被忽略。如果异常的类型和 except 之后的类型一致,那么对应的 except 子句将被执行。
  4. 如果一个异常没有与任何的 except 匹配,那么这个异常将会被传递到上层的 try 中。

一个 try 语可以包含多个 except 子句,分别来处理不同的特定的异常,但是只有一个 except 分之会被执行。

一个 except 子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,如:

except (RuntimeError, TypeError, NameError):
        pass

try except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后,在 try 没有发生任何异常的时候执行。

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

使用 else 子句比把所有的语句都放在 try 子句中要好,这样可以避免一些意想不到的而 except 又没有捕获的异常。

异常处理不仅仅处理那些直接发生在 try 子句中的异常,而且还能处理子句中调用的函数(甚至是间接调用的函数)里抛出的异常。

自定义异常

可以创建一个继承自 Exception 类的子类来处理自己的异常。

我们可以使用关键字 raise 来抛出一个异常

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

finally 语句

try 语句还有另外一个可选的子句,它定义里无论在任何情况下都会执行的清理行为。

>>>try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
... 
Goodbye, world!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

上述例子不管 try 子句里有没有发生异常,finally 子句都会执行。

如果一个异常在 try 子句里(或者在 excpet 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后再次被抛出。

>>>def divide(x, y):
        try:
            result = x / y
        except ZeroDivisionError:
            print("division by zero!")
        else:
            print("result is", result)
        finally:
            print("executing finally clause")
   
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

with 关键字

一些对象定义里标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。

例如我们尝试打开一个文件,将内容打印到屏幕上:

for line in open("myfile.txt"):
    print(line, end="")

以上的代理问题在于,当执行完毕之后,文件依旧保持打开状态,并没有被关闭。

关键字 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行它的清理方法:

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

在操作文件时,最好使用关键字 with

面向对象

Python 是一门面向对象语言。我们可以使用关键字 Class 来创建一个类。

类定义

语法:

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

对象

在创建好类后,我们就可以使用该类创建其实例。对象的属性引用的标准语法:obj.name。

class MyClass:
    """一个简单的类实例"""
    i = 12345
    def f(self):
        return 'hello world'
 
# 实例化类
x = MyClass()
 
# 访问类的属性和方法
print("MyClass 类的属性 i 为:", x.i)
print("MyClass 类的方法 f 输出为:", x.f())

类有一个名为 __init__() 的特殊方法(构造器),该方法在类实例化时会自动调用。

当然,该方法可以有参数的,这样实例对象时就可以为实例对象赋值。

class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart
x = Complex(3.0, -4.5)
print(x.r, x.i)   # 输出结果:3.0 -4.5

self

类的方法和普通的函数有一个特别的区别,就是他们必须有一个额外的并且是第一个参数名,通常就是 self,当然也可以是其他的名称。

class Test:
    def prt(self):
        print(self)
        print(self.__class__)
 
t = Test()
t.prt()

# 输出
<__main__.Test instance at 0x100771878>
__main__.Test

可以看出,self 代表的是类的一个实例,指向的是该实例的地址,因此 self 可以被其他字符串替换,而 self.__class__ 则指向类。

继承

面向对象的一大特点就是继承,同样的,Python支持类的继承,而且是多继承。

继承的语法:

class DerivedClassName(Base1[, Base2[, Base3……]]):
    <statement-1>
    .
    .
    .
    <statement-N>

方法重写

Python同样支持方法重写。

class Parent:        # 定义父类
   def myMethod(self):
      print ('调用父类方法')
 
class Child(Parent): # 定义子类
   def myMethod(self):
      print ('调用子类方法')
 
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法

类的属性和方法

私有属性

__private_attrs:两个下划线开头,声明该属性为私有的,不能在类的外部被使用或者直接访问。在类的内部使用时:self.__private_attrs。

私有方法

类方法必须包含参 self,并且是第一个,self 代表的是类的实例。

__private_method:和私有属性一样,私有方法的声明需要使用两个下划线开头,同样不能在类外部使用或者直接访问。

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0    # 公开变量
 
    def __count(self):	# 私有方法
        self.__secretCount += 1
        self.publicCount += 1
        print (self.__secretCount)

文件操作

open()

Python 的open()方法用于打开一个文件,并返回文件对象,如果该文件无法被打开,会抛出 OSError 异常。在打开文件后,一定要保证关闭文件对象,调用方法close()关闭。

open(filename, mode)
  1. filename:包含了访问文件的名称的字符串
  2. mode:决定了打开文件的模式:只读、写入、追加等,默认文件访问模式为只读(r)。

不同模式下打开文件:

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

效果对比:

模式 r r+ w w+ a a+
+ +   +   +
  + + + + +
创建     + + + +
覆盖     + +    
指针在开始 + + + +    
指针在结尾         + +

实例:

# 打开一个文件
f = open("/tmp/foo.txt", "w")

f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )

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

file 对象的常用函数:

方法 描述
file.close() 关闭文件
file.readline([size]) 读取整行,包括 “\n” 字符
file.next() 返回文件下一行
file.read([size]) 从文件读取指定的字节数,如果未给定或为负则读取所有
file.readlines([sizeint]) 读取所有行并返回列表
file.tell() 返回文件当前位置
file.seek(offset[, whence]) 设置文件当前位置
file.write(str) 将字符串写入文件,返回的是写入的字符长度

实例

如果要改变文件当前的位置, 可以使用 f.seek(offset[, whence]) 函数。

whence 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:

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

whence 值为默认为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'

with 关键字

例如我们尝试打开一个文件,将内容打印到屏幕上:

for line in open("myfile.txt"):
    print(line, end="")

以上的代理问题在于,当执行完毕之后,文件依旧保持打开状态,并没有被关闭。

关键字 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行它的清理方法:

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

在操作文件时,最好使用关键字 with

其他

列表推导式

列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。

每个列表推导式都在 for 之后跟一个表达式,然后有0到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。 如果希望表达式推导出一个元组,就必须使用括号()。

实例1:

将列表中的元素的立方组成一个新的列表。

>>> list = [1,2,3]
>>> [i**3 for i in list]
[1, 8, 27]

实例2:

关于两个列表的操作。

>>> list1 = [1,2,3]
>>> list2 = [2,4,6]
>>> [x*y for x in list1 for y in list2]
[2, 4, 6, 4, 8, 12, 6, 12, 18]
>>> list1 = [1,2,3]
>>> list2 = [2,4,6]
>>> [item for item in zip(list1,list2)]
[(1, 2), (2, 4), (3, 6)]

实例3:

嵌套的列表,将 3x4 矩阵转换为 4x3 列表:

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
  • del 删除语句

使用 del 语句可以从一个可变序列中依据索引而不是值来删除一个元素。这个和 pop() 返回一个值不同。可以使用 del 语句从可变序列中删除一个切割,或清空整个可变序列。

实例1:

列表

>>> list = [1,2,3,4,5,6]
>>> del list[0]		# 删除第一个
>>> list
[2, 3, 4, 5, 6]
>>> del list[2:]		# 删除[2:],第三个到结束
>>> list
[2, 3]
>>> del list			# 删除整个变量
>>> list
<class 'list'>

字典

>>> dict = dict(name="xiaoming",age=26,sex="male",height=178.0)
>>> dict
{'height': 178.0, 'sex': 'male', 'age': 26, 'name': 'xiaoming'}
>>> del dict['height']
>>> dict
{'sex': 'male', 'age': 26, 'name': 'xiaoming'}

遍历技巧

指定次数

在我们遍历某个序列的数量或者遍历固定次数时,可以使用内置函数 range()

实例:

>>> for i in range(10):
...     print(i, end=' ')
... 
0 1 2 3 4 5 6 7 8 9 

>>> for i in range(10,50,3):
...     print(i, end=' ')
... 
10 13 16 19 22 25 28 31 34 37 40 43 46 49 

>>> list = [1,2,4,6,23,12]
>>> for i in range(len(list)):
...     print(i, end=' ')
... 
0 1 2 3 4 5 

zip() 组合函数

如果你想要遍历字符串等的元素和其对应的索引,你可以使用 zip() 进行组合,此时遍历的元素是元组的形式。

实例:

>>> string = "xiaoming"
>>> for (i,value) in zip(range(len(string)),string):
...     print(i,value)
... 
0 x
1 i
2 a
3 o
4 m
5 i
6 n
7 g

可以看出,如果你想要同时遍历数量相同的序列,你也可以使用zip() 进行组合。

字典和列表

字典类型中内置了三种函数:dict.keys(),dict.values()dict.items(),可分别来遍历字典的 keys、values和元素。

实例:

>>> dict = dict(name="xiaoming",age=26,sex="male",height=178.0)
>>> for key,value in dict.items():
...     print(key,value)
... 
sex male
height 178.0
age 26
name xiaoming

列表类型的遍历通常遍历的是元素,如果你想要获取索引位置和对应的值,除了使用 zip() 函数,也可以使用 enumerate() 达到同样的效果。

实例:

>>> list = ['xiao','ming','xiu','qi']
>>> for index,value in enumerate(list):
...     print(index,value)
... 
0 xiao
1 ming
2 xiu
3 qi

输出格式化: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

可选项 ‘:’ 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 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))
...
Runoob     ==>          2
Taobao     ==>          3
Google     ==>          1

pickle 本地存储

pickle 模块实现了基本的数据序列和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

序列化写入:

pickle.dump(obj, file, [,protocol])

反序列化读取:

x = pickle.load(file)

实例1:

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

实例2:

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

说明

以上内容均来自菜鸟教程,更多内容可继续查阅相关资料。

感谢菜鸟教程的无私奉献!