Python基础

Python基础语法

1. 注释

Python的单行注释以#开头

1
2
# 第一个注释
print ("Hello, Python!") # 第二个注释

多行注释可以用多个 # 号,还有 ‘’’ 和 **”””**:

2. 代码缩进

python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {}

1
2
3
4
5
6
7
8
9
10
11
if True:
print ("True")
else:
print ("False")

if True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误

3. print输出

print输出默认换行,如果要实现不换行需要在变量末尾加上 end=””

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>x="a"
>y="b"
># 换行输出
>print( x )
>print( y )

>print('---------')

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

>#在 Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法。
>print ("我叫 %s 今年 %d 岁!" % ('小明', 10))

Python数据类型

1. Number(数字类型)

Python3 支持 int、float、bool、complex(复数)

当你指定一个值时,Number 对象就会被创建:

1
2
>var1 = 1
>var2 = 10

2. String(字符串)

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

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

1
>变量[头下标:尾下标]

加号 + 是字符串的连接符, 星号 ***** 表示复制当前字符串,与之结合的数字为复制的次数。实例如下:

1
2
3
4
5
6
7
8
>str = 'Runoob'
>print (str) # 输出字符串
>print (str[0:-1]) # 输出第一个到倒数第二个的所有字符
>print (str[0]) # 输出字符串第一个字符
>print (str[2:5]) # 输出从第三个开始到第五个的字符
>print (str[2:]) # 输出从第三个开始的后的所有字符
>print (str * 2) # 输出字符串两次,也可以写成 print (2 * str)
>print (str + "TEST") # 连接字符串

Python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。实例如下”””

1
2
3
4
5
6
>para_str = """这是一个多行字符串的实例
>多行字符串可以使用制表符
>TAB ( \t )。
>也可以使用换行符 [ \n ]。
>"""
>print (para_str)

注意:

  • 1、反斜杠可以用来转义,使用r可以让反斜杠不发生转义。
  • 2、字符串可以用+运算符连接在一起,用*运算符重复。
  • 3、Python中的字符串有两种索引方式,从左往右以0开始,从右往左以-1开始。
  • 4、Python中的字符串不能改变。
操作符 描述 实例
+ 字符串连接 a + b 输出结果: HelloPython
* 重复输出字符串 a*2 输出结果:HelloHello
[] 通过索引获取字符串中字符 a[1] 输出结果 e
[ : ] 截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。 a[1:4] 输出结果 ell
in 成员运算符 - 如果字符串中包含给定的字符返回 True ‘H’ in a 输出结果 True
not in 成员运算符 - 如果字符串中不包含给定的字符返回 True ‘M’ not in a 输出结果 True
r/R 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 print( r'\n' ) print( R'\n' )

3. List(列表)

List是Python最基本的数据结构

列表的数据项不需要具有相同的类型,创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:

1
2
3
4
>list1 = ['Google', 'Runoob', 1997, 2000]
>list2 = [1, 2, 3, 4, 5 ]
>list3 = ["a", "b", "c", "d"]
>list4 = ['red', 'green', 'blue', 'yellow', 'white', 'black']

和C语言的数组一样,访问列表的元素使用索引,索引从0开始,截取数组的操作和字符串一样

1
2
>nums = [10, 20, 30, 40, 50, 60, 70, 80, 90]
>print(nums[0])

删除数组的元素使用del()

1
2
3
4
>list = ['Google', 'Runoob', 1997, 2000]
>print ("原始列表 : ", list)
>del list[2]
>print ("删除第三个元素 : ", list)

Python列表操作符

Python 表达式 结果 描述
len([1, 2, 3]) 3 长度
[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] 组合
[‘Hi!’] * 4 [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] 重复
3 in [1, 2, 3] True 元素是否存在于列表中
for x in [1, 2, 3]: print(x, end=” “) 1 2 3 迭代

4.Tuple(元组)

创建元组

1
2
3
4
5
tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5 )
tup3 = "a", "b", "c", "d" # 不需要括号也可以
#创建新元组
tup=()

访问元组和截取

元组元素的访问和列表一样,使用索引即可

修改元组

元组的元素不可以修改,但是可以将元组拼接

1
2
3
4
5
6
7
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2
print (tup3)

删除元组

元组的元素不可以删除,但是可以单独删除一整个元组

1
2
3
4
5
tup = ('Google', 'Runoob', 1997, 2000)
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)

5.Dictionary(字典)

创建字典

字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,格式如下所示:

1
d = {key1 : value1, key2 : value2, key3 : value3 }

键必须是唯一的,但是值可以重复

访问字典

1
2
3
dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
print ("dict['Name']: ", dict['Name'])
print ("dict['Age']: ", dict['Age'])

修改字典

1
2
3
4
5
dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8 # 更新 Age
dict['School'] = "菜鸟教程" # 添加信息
print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

删除字典

1
2
3
4
5
6
7
8
dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}

del dict['Name'] # 删除键 'Name'
dict.clear() # 清空字典
del dict # 删除字典

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

6.Set(集合)

创建字典

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

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

集合操作

1.添加\更新集合

1
2
3
4
>>>> thisset = set(("Google", "Runoob", "Taobao"))
>>>> thisset.add("Facebook")
>>>> print(thisset)
>{'Taobao', 'Facebook', 'Google', 'Runoob'}

还有一个方法,也可以添加元素,且参数可以是列表,元组,字典等,语法格式如下:

1
>s.update( x )

2. 移除元素

1
>s.remove( x )

将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误。

此外还有一个方法也是移除集合中的元素,且如果元素不存在,不会发生错误。格式如下所示:

1
>s.discard( x )

我们也可以设置随机删除集合中的一个元素,语法格式如下:

1
>s.pop() 

3.计算集合的个数

语法格式如下

1
>len(s)

4. 清空集合

语法格式如下:

1
s.clear()

5. 判断元素是否存在

语法格式如下:

1
x in s

Python条件控制

1. if语句

1
2
3
4
5
6
>if condition_1:
statement_block_1
>elif condition_2:
statement_block_2
>else:
statement_block_3

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

Python循环语句

while循环

Python 中 while 语句的一般形式:

1
2
>while 判断条件(condition):
执行语句(statements)……

while 循环使用 else 语句

在 while … else 在条件语句为 false 时执行 else 的语句块。

语法格式如下:

1
2
3
4
>while <expr>:
<statement(s)>
>else:
<additional_statement(s)>

for循环

1
2
3
4
>for <variable> in <sequence>:
<statements>
>else:
<statements>

range()函数

如果你需要遍历数字序列,可以使用内置range()函数。它会生成数列,例如:

1
>for i in range(5):  print(i)

pass语句

Python pass是空语句,是为了保持程序结构的完整性。

pass 不做任何事情,一般用做占位语句

Python 迭代器与生成器

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

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

创建迭代器

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

迭代器可以利用for循环进行遍历

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

也可以使用next()函数

1
2
3
4
5
6
7
8
9
10
>import sys  # 引入 sys 模块

>list = [1, 2, 3, 4]
>it = iter(list) # 创建迭代器对象

>while True:
try:
print(next(it))
except StopIteration:
sys.exit()

创建迭代器(构造函数)

把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。

创建一个迭代数字的迭代器,初始值为1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>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))

StopIteration异常

StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>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)

生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>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()

Python函数

函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 **()**。

函数内容以冒号 : 起始,并且缩进。

实例

1
2
3
4
5
6
7
8
9
>def max(a, b):
>if a > b:
return a
else:
return b

a = 4
>b = 5
>print(max(a, b))

参数传递

python 函数的参数传递:

  • 不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
  • 可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。.

python 传不可变对象实例

通过 id() 函数来查看内存地址变化:

1
2
3
4
5
6
7
8
>def change(a):
print(id(a)) # 指向的是同一个对象
a=10
print(id(a)) # 一个新对象

a=1
print(id(a))
>change(a)

传可变对象实例

可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:

1
2
3
4
5
6
7
8
9
10
>def changeme( mylist ):
"修改传入的列表"
mylist.append([1,2,3,4])
print ("函数内取值: ", mylist)
return

# 调用changeme函数
mylist = [10,20,30]
>changeme( mylist )
>print ("函数外取值: ", mylist)

结果:

1
2
>函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
>函数外取值: [10, 20, 30, [1, 2, 3, 4]]

必需参数

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

关键字参数

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

以下实例中演示了函数参数的使用不需要使用指定顺序:

1
2
3
4
5
6
7
8
9
>#可写函数说明
>def printinfo( name, age ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return

#调用printinfo函数
printinfo( age=50, name="runoob" )

默认参数

调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值:

1
2
3
4
5
6
7
8
9
10
11
>#可写函数说明
>def printinfo( name, age = 35 ):
"打印任何传入的字符串"
print ("名字: ", name)
print ("年龄: ", age)
return

#调用printinfo函数
printinfo( age=50, name="runoob" )
>print ("------------------------")
>printinfo( name="runoob" )

匿名函数

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。

实例:

1
2
3
4
5
6
># 可写函数说明
>sum = lambda arg1, arg2: arg1 + arg2

># 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
>print ("相加后的值为 : ", sum( 20, 20 )

Python数据结构

将列表当作堆栈使用

列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>>> 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]

将列表当作队列使用

1
2
3
4
5
6
7
8
9
10
>>>> from collections import deque
>>>> queue = deque(["Eric", "John", "Michael"])
>>>> queue.append("Terry") # Terry arrives
>>>> queue.append("Graham") # Graham arrives
>>>> queue.popleft() # The first to arrive now leaves
>'Eric'
>>>> queue.popleft() # The second to arrive now leaves
>'John'
>>>> queue # Remaining queue in order of arrival
>deque(['Michael', 'Terry', 'Graham'])

列表推导式

将列表中的每一个值乘3

1
2
3
>>>> vec = [2, 4, 6]
>>>> [3*x for x in vec]
>[6, 12, 18]

列表的值平方,并形成一个列表

1
2
>>>> [[x, x**2] for x in vec]
>[[2, 4], [4, 16], [6, 36]]

对列表中的元素调用一个方法

1
2
3
>>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>>> [weapon.strip() for weapon in freshfruit]
>['banana', 'loganberry', 'passion fruit']

Python模块

想使用 Python 源文件,只需在另一个源文件里执行 import 语句,语法如下:

1
2
3
4
5
# Filename: support.py

def print_func( par ):
print ("Hello : ", par)
return
1
2
3
4
5
6
7
# Filename: test.py

# 导入模块
import support

# 现在可以调用模块里包含的函数了
support.print_func("Runoob")

from…import..语句

1
2
from support import print_func
print_func("cnm")
1
from modname import * #这个语句吧modname里的全部方法导入

__name__属性

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。

1
2
3
4
if __name__ == '__main__':
print('程序自身在运行')
else:
print('我来自另一模块')

说明: 每个模块都有一个__name__属性,当其值是’main‘时,表明该模块自身在运行,否则是被引入。

说明:**name** 与 main 底下是双下划线, _ _ 是这样去掉中间的那个空格。

dir() 函数

内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回

Python输入输出

输出格式美化

  • str(): 函数返回一个用户易读的表达形式。
  • repr(): 产生一个解释器易读的表达形式。

输出一个平方与立方的表:

1
2
3
4
5
6
7
8
9
10
11
12
>>>> 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
>101001000

str.format()

1
2
>>>> print('{}网址: "{}!"'.format('菜鸟教程', 'www.runoob.com'))
>菜鸟教程网址: "www.runoob.com!"

括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。

在括号中的数字用于指向传入对象在 format() 中的位置,如下所示:

1
2
3
4
>>>> print('{0} 和 {1}'.format('Google', 'Runoob'))
>Google 和 Runoob
>>>> print('{1} 和 {0}'.format('Google', 'Runoob'))
>Runoob 和 Google

如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。

1
2
>>>> print('{name}网址: {site}'.format(name='菜鸟教程', site='www.runoob.com'))
>菜鸟教程网址: www.runoob.com

可选项 : 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位:

1
2
3
>>>> **import** math
>>>> **print**('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
>常量 PI 的值近似为 3.142

如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。

最简单的就是传入一个字典, 然后使用方括号 [] 来访问键值 :

1
2
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 变量前使用 ** 来实现相同的功能:

1
2
3
>>>> 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

输入

Python提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘。

1
2
>str = input("请输入:");
>print ("你输入的内容是: ", str)

读和写文件

open() 将会返回一个 file 对象,基本语法格式如下:

1
>open(filename, mode)

打开文件的模式

模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
1
2
3
4
5
># 打开一个文件
>f = open("C:/Users/DIAOAN/Desktop/test.txt", "a")
>f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
># 关闭打开的文件
>f.close()

文件的方法

f.read()

1
2
3
4
5
6
7
8
># 打开一个文件
>f = open("C:/Users/DIAOAN/Desktop/test.txt", "r")

>str = f.read()
>print(str)

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

f.readline()

f.readline() 会从文件中读取单独的一行。换行符为 ‘\n’。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。

f.readlines()

f.readlines() 将返回该文件中包含的所有行。

f.write()

f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。

如果写入一些不是字符串的东西,则需要转换

1
2
3
4
5
6
7
8
9
># 打开一个文件
>f = open("/tmp/foo1.txt", "w")

>value = ('www.runoob.com', 14)
>s = str(value)
>f.write(s)

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

f.tell()

f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。

f.seek()

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

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

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

f.close()

在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。

当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常。

Python文件

open()函数

open()函数返回一个文件对象

语法如下:

1
2
>open(file, mode='r')
>open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

Python异常处理

try/except

异常捕捉可以使用 try/except 语句。

1
2
3
4
5
6
>while True:
>try:
x = int(input("请输入一个数字: "))
break
>except ValueError:
print("您输入的不是数字,请再次尝试输入!")

try 语句按照如下方式工作;

  • 首先,执行 try 子句(在关键字 try 和关键字 except 之间的语句)。
  • 如果没有异常发生,忽略 except 子句,try 子句执行后结束。
  • 如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行。
  • 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中。
  • 最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。

try/except…else

try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。

else 子句将在 try 子句没有发生任何异常的时候执行。

try-finally 语句

try-finally 语句无论是否发生异常都将执行最后的代码。

抛出异常

Python 使用 raise 语句抛出一个指定的异常。

raise语法格式如下:

1
2
3
>x = 10
>if x > 5:
raise Exception('x 不能大于 5。x 的值为: {}'.format(x))

用户自定义异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>>> 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!'

定义清理行为

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

1
2
3
4
5
6
7
8
9
>>>> try:
raise KeyboardInterrupt
finally:
print('Goodbye, world!')

>Goodbye, world!
>Traceback (most recent call last):
File "<stdin>", line 2, in <module>
>KeyboardInterrupt

Python面向对象

类的定义

1
2
3
4
5
6
>class ClassName:
><statement-1>
>.
>.
>.
><statement-N>

类对象

1
2
3
4
5
6
7
8
9
10
11
12
>class MyClass:
>"""一个简单的类实例"""
>i = 12345
>def f(self):
return 'hello world'

># 实例化类
>x = MyClass()

># 访问类的属性和方法
>print("MyClass 类的属性 i 为:", x.i)
>print("MyClass 类的方法 f 输出为:", x.f())

类有一个名为 _init_() 的特殊方法(构造方法),该方法在类实例化时会自动调用,像下面这样:

1
2
>def __init__(self):
>self.data = []

__init__()函数可以有参数,参数通过__init()__传递到类的实例化操作

1
2
3
4
5
6
>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代表类的实例,而非类

1
2
3
4
5
6
7
>class Test:
>def prt(self):
print(self)
print(self.__class__)

>t = Test()
>t.prt()

类的方法

在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>class people:
># 定义基本属性
>name = ''
>age = 0
># 定义私有属性,私有属性在类外部无法直接进行访问
>__weight = 0

># 定义构造方法
>def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w

>def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))


># 实例化类
>p = people('runoob', 10, 30)
>p.speak()

类的继承

1
2
3
4
5
6
>class DerivedClassName(BaseClassName):
><statement-1>
>.
>.
>.
><statement-N>

子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。

BaseClassName(实例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:

1
>class DerivedClassName(modname.BaseClassName):

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
>#类定义
>class people:
>#定义基本属性
>name = ''
>age = 0
>#定义私有属性,私有属性在类外部无法直接进行访问
>__weight = 0
>#定义构造方法
>def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
>def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))

>#单继承示例
>class student(people):
>grade = ''
>def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
>#覆写父类的方法
>def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))



>s = student('ken',10,60,3)
>s.speak()

多继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
># 类定义
>class people:
># 定义基本属性
>name = ''
>age = 0
># 定义私有属性,私有属性在类外部无法直接进行访问
>__weight = 0

># 定义构造方法
>def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w

>def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))


># 单继承示例
>class student(people):
>grade = ''

>def __init__(self, n, a, w, g):
# 调用父类的构函
people.__init__(self, n, a, w)
self.grade = g

># 覆写父类的方法
>def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))


># 另一个类,多重继承之前的准备
>class speaker():
>topic = ''
>name = ''

>def __init__(self, n, t):
self.name = n
self.topic = t

>def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name, self.topic))


># 多重继承
>class sample(speaker, student):
>a = ''

>def __init__(self, n, a, w, g, t):
student.__init__(self, n, a, w, g)
speaker.__init__(self, n, t)


>test = sample("Tim", 25, 80, 4, "Python")
>test.

方法重写

1
2
3
4
5
6
7
8
9
10
11
>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

类的方法

在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。

self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self

类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>class JustCounter:
>__secretCount = 0 # 私有变量
>publicCount = 0 # 公开变量

>def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)


>counter = JustCounter()
>counter.count()
>counter.count()
>print(counter.publicCount)
>print(counter.__secretCount) # 报错,实例不能访问私有变量

类的专有方法:

  • init : 构造函数,在生成对象时调用
  • del : 析构函数,释放对象时使用
  • repr : 打印,转换
  • setitem : 按照索引赋值
  • getitem: 按照索引获取值
  • len: 获得长度
  • cmp: 比较运算
  • call: 函数调用
  • add: 加运算
  • sub: 减运算
  • mul: 乘运算
  • truediv: 除运算
  • mod: 求余运算
  • pow: 乘方

Python命名空间和作用域

全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>total = 0  # 这是一个全局变量


># 可写函数说明
>def sum(arg1, arg2):
# 返回2个参数的和."
total = arg1 + arg2 # total在这里是局部变量.
print("函数内是局部变量 : ", total)
return total


># 调用sum函数
>sum(10, 20)
>print("函数外是全局变量 : ", total)

global和nonlocal关键字

当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。

以下实例修改全局变量 num:

1
2
3
4
5
6
7
8
>num = 1
>def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
>fun1()
>print(num)

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

1
2
3
4
5
6
7
8
9
>def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
>outer()