一、基础了解
1.发展历史
- 1990年——Python公开发布
- 2000年——Python2发布
- 2008年——Python3发布
- 2020年——Python2. 7停止维护
2.特点
- 解释型编程语言:源代码-中间字节码-机器语言
- 可移植:无需经过修改可在多个平台运行
- 面向对象编程
- 丰富的“库”调用
- 动态类型:在生明变量时不需指定数据类型
3.开发环境
- python编辑器
- python运行所需要的基础库
- 编写和运行工具
4.编写和运行方式
(4.1)交互方式
我们每写一行代码就可以敲回车键运行
运行工具:Python Shell 、IDLE
(4.2)文件方式
代码文件 (*.py) 运行
记事本另存为py文件注意选择编码为“UTF - 8"
二、基础语法
1. 标识符
变量、函数、属性、类、模块等,指由程序员指定名称的代码元素
- 区分大小写
- 首字符:下划线 ( _ ) 或字母 , 不能是数字
- 除首字符外字符必须是 字母 、 数字、下划线 ( _ )
- 关键字不能作为标识符
- 不可用python内置函数做自己的标识符
2. 关键字
由语言本身定义好的由特殊含义的代码元素
3. 变量
程序员声明和赋值的变量
s = "Hello World"
4. 语句
一行代码表示一条语句
语句结束时不需加分号{;}
5. 代码注释#
# 代码注释,记得隔一个空格
6. 模块
- 一个模块就是一个文件
- 模块就是保存代码的最小单位
- 模块中可以声明变量、函数、属性和类等代码元素
7. 序列
- 概述
序列包括列表(list)、字符串(str)、元组(tuple)和字节(bytes)等
- 序列的索引操作
- 序列的加和乘
- 序列的切片操作
切片运算符的语法形式为 [start : end : step]
*注意:切下的小切片包括start位置元素,不包括end位置元素*
- 代码分析
z = 'ABCDE'
print(z[1:3]) # 返回 BC
print(z[0:3]) # 返回 ABC
print(z[:3]) # 返回 ABC
print(z[0:]) # 返回 ABCDE
print(z[1:-1]) # 返回 BCD
print(z[1:5:1]) # 返回 BCDE
print(z[1:5:2]) # 返回 BD
print(z[::-1]) # 返回 EDCBA 。 步长为负值时,从右往左获取元素。
- 成员测试
in
用于测试是否包含某一元素
not in
用于测试是否不包含某一元素
z = 'ABCDE'
n = 'E' in z
m = 'F' not in z
print(n) # 返回 True
print(m) # 返回 True
8. 六种内置数据类型
(1)数字(4种)
整数类型
可正可负,没有取值范围
4种表现形式
2进制 | 0b开头 | 0b11011 |
---|---|---|
8进制 | 0o开头 | 0o33 |
10进制 | 正常显示 | 27 |
16进制 | 0x | 0x1b |
浮点类型
- 浮点数间存在不确定尾数
0.1 + 0.2 == 0.3
# 条件判断结果为 False
round(0.1 + 0.2, 1 ) == 0.3
# 条件判断结果为 True
# round(x, d) 对x四舍五入,d是小数截取位数
- 科学计数法表示
字母e或E 作为 幂 的符号,以10为基数。
4.3e-30.0043
4.3E34300.0
复数类型
如果 x2= -1 ,那么x的值是什么?
1 + 2j
# 返回 (1+2j) ,1为实部、2为虚部。
(1+2j) + (1+2j)
# 返回 (2+4j) ,两个复数的相加。
c = 3 + 4j
type(c)
# 返回 <class 'complex'> ,复数类型为complex
布尔类型
bool是int的子类,只有两值:True 和 False
bool(0) # 整数0 返回 False
bool(1) # 非整数0 返回 True
bool(2) # 非整数0 返回 True
bool('') # 空字符串 返回 False
bool(' ') # 非空字符串 返回 False
bool([]) # 空列表 返回 False
bool({}) # 空字典 返回 False
(2)字符串
字符串表示方式
'Hello' 或 "Hello"
转义字符
如何想在字符串中包含一些特殊字符,例如换行符、制表符等,就需要字符转义。
前面加r就失去转义功能 >> r'hello\n world'
s = 'hello\n world'
print(s)
"""
hello
world
"""
s = 'hello\u000a world'
print(s)
"""
hello
world
"""
s = 'hello\tworld'
print(s)
"""
hello world
检查空格数(3个)
hello---world
"""
s = 'hello\' world'
s1 = 'hello\" world'
print(s)
print(s1)
"""
hello' world
hello" world
"""
s = 'hello\\ world'
print(s)
"""
hello\ world
"""
字符串占位符

格式化控制符

字符串查找
用于查找子字符串,返回索引序号。
语法:str.find(sub[,start[,end]]) 表示索引start到end之间查找子字符串sub。
如果没有找到,则返回 -1 。
s_str = 'hello world'
print(s_str.find('e')) # 返回 1
print(s_str.find('l')) # 返回 2
print(s_str.find('l', 4)) # 返回 9
print(s_str.find('l', 4, 6)) # 返回 -1

字符串替换与切割
语法:str.replace(old,new[,count]) 。
count参数指定了替换old子字符串的个数,如果count被忽略,则替换所有old子字符串。
test = 'AB CD EF GH IJ'
print(test.replace(' ', "|", 2)) # 返回 AB|CD|EF GH IJ
print(test.replace(' ', "|")) # 返回 AB|CD|EF|GH|IJ
print(test.split(' ', maxsplit=0)) # 返回 ['AB CD EF GH IJ']
print(test.split(' ', maxsplit=2)) # 返回 ['AB', 'CD', 'EF GH IJ']
(3)列表 [ ]
列表 list 是一种可变序列类型,我们可以追加、插入、删除和替换列表中的元素
# ---创建列表---
print( [] ) # 输出 [] 。创建空列表
print( [10] ) # 输出 [10] 。创建只有一个元素的列表
print( [10,] ) # 输出 [10] 。列表的每一个元素后面都跟着一个逗号,但经常省略这个逗号
print( ['a', 'b', 1, 2, 3] ) # 输出 ['a', 'b', 1, 2, 3] 。创建一个字符串和整数混合的列表
print( list('abcde') ) # 输出 ['a', 'b', 'c', 'd', 'e']。 通过list(iterable)函数创建列表对象,字符串时序列对象,创建的序列对象包含5个字符
# ---追加元素---
list = [20, 10, 50, 30]
list1 = []
list2 = []
list.append(80)
print(list) # 输出 [20, 10, 50, 30, 80]
list = [50, 30]
t = [1, 2, 3]
list1 = list + t
print(list1) # [50, 30, 1, 2, 3]
list2 = [20, 10]
list2.extend(t)
print(list2) # 输出 [20, 10, 1, 2, 3]
# ---插入元素---
list = [20, 10, 50, 30]
list.insert(2, 80) # 在索引2位置插入一个元素,原来索引序号为2以上的元素的索引序号都+1
print(list) # 输出 [20, 10, 80, 50, 30]
# ---替换元素---
list = [20, 10, 50, 30]
list[1] = 80
print(list) # 输出 [20, 80, 50, 30]
# ---删除元素---
list = [20, 10, 50, 30]
list.remove(10)
print(list) # 输出 [20, 50, 30]
(4)元组 ( )
元组 tuple 是一种不可变序列类型
# ---创建元组---
a = ()
print(a) # 通过()可以创建空元组
print((1, 2, 3, 4)) # 输出 (1, 2, 3, 4)
print(('a', 'b')) # 输出 ('a', 'b')
print(('a', 'b', 1, 2, 3)) # 输出 ('a', 'b', 1, 2, 3)
print(tuple('abcde')) # 输出 ('a', 'b', 'c', 'd', 'e')
print(tuple([1, 2, 3, 4])) # 输出 (1, 2, 3, 4)
t = 1, #创建只有一个元素的元组,元素后面的逗号不能省略
print(t) # 输出 (1,)
t = (1,)
print(t) # 输出 (1,)
print( type(t) ) # 输出 <class 'tuple'>
# ---元组打包与拆包---
s_id, s_name = (102, '张三') # 将元组(102, '张三')拆包到变量s_id和s_name
print(s_id) # 输出 102
print(s_name) # 输出 张三
(5)集合 { }
合集 set 是一种可迭代的、无序的、不能包含重复元素的容器类型的数据
s_heji = set('abbde')
print(s_heji) # 输出 {'b', 'a', 'd', 'e'}。 创建合集
s_set = {'aa', 'bb', 'cc'}
s_set.add('dd')
print(s_set) # 输出 {'dd', 'bb', 'cc', 'aa'} 。 添加元素
s_set = {'aa', 'bb', 'cc'}
s_set.remove('bb')
print(s_set) # 输出 {'cc', 'aa'}。 删除元素
s_set = {'aa', 'bb', 'cc'}
s_set.clear()
print(s_set) # 输出 set() 。 消除合集
(6)字典 {key: value}
字典 dict 是可迭代的、通过键 key 来访问元素的可变的容器类型的数据。
字典由两部分视图构成:键视图和值视图。
键视图不能包含重复元素,值视图能包含重复元素。
# 通过dict()函数创建字典,参数是另外一个字典
d = dict({101:'name1', 102:'name2', 103:'name3'})
print(d) # 输出 {101: 'name1', 102: 'name2', 103: 'name3'}
print(d[101]) # 输出 name1
# 访问字典视图
'''
items():返回字典所有键值对视图
keys():返回字典键视图
values():返回字典值视图
'''
d1 = dict({101:'name1', 102:'name2', 103:'name3'})
print(d1.items()) # 输出 dict_items([(101, 'name1'), (102, 'name2'), (103, 'name3')])
print(list(d1.items())) # 输出 [(101, 'name1'), (102, 'name2'), (103, 'name3')]
print(d1.keys()) # 输出 dict_keys([101, 102, 103])
print(list(d1.keys()) ) # 输出 [101, 102, 103] 为值列表
print(d1.values()) # 输出 dict_values(['name1', 'name2', 'name3'])
9. 运算符
(1)算术
1.0 + True +1
# True被当作整数1参与运算,在操作数种存在浮点数,计算结果也为浮点类型
运算符 | 名称 | 例子 | 说明 |
---|---|---|---|
+ | 加 | a + b | 求和 |
- | 减 | a - b | 求差 |
* | 乘 | a * b | 求积 |
/ | 除 | a / b | 求商 |
% | 取余 | a % b | 求余数 |
** | 幂 | a ** b | 求a的b次幂 |
// | 加地板除法 | a // b | 求小于a与b的商的最大整数 |
(2)比较
(3)逻辑
(4)位
位运算以二进制(bit)为单位进行运算,结果都为整数类型数据
(5)赋值
(6)运算符的优先级
计算的优先级
10. 程序流程控制
(1)分支语句 if
if
- 语法结构
if 条件 :
语句组
- 代码实例
z = int(input("请输入一个0~100的整数: "))
if ( z >= 60 ) and ( z < 85 ):
print("成绩中上")
if else
- 语法结构
if 条件 :
语句组1
else :
语句组2
- 代码实例
z = int(input("请输入一个0~100的整数: "))
if ( z >= 0 ) and ( z < 60 ):
print("不及格")
else :
print("及格")
if elif else
- 语法结构
if 条件1 :
语句组1
elif 条件2 :
语句组2
...
elif 条件n :
语句组n
else :
语句组n+1
- 代码实例
score = int(input("请输入一个0~100的整数: "))
if score >= 90:
grade = 'A'
elif score >= 80:
grade = 'B'
elif score >= 70:
grade = 'C'
elif score >= 60:
grade = 'D'
else :
grade = 'F'
print("Grade = " + grade)
(2)循环语句 for、while
while
- 语法结构
while 循环条件 :
循环体语句组
else :
语句组
- 代码实例
score = int(input("请输入一个0~100的整数: "))
i = 0
while i * i < 10 :
i += 1
print(str(i) + ' * ' + str(i) + ' =', i * i)
else :
print('While Over!')
- 输出结果
1 * 1 = 1
2 * 2 = 4
3 * 3 = 9
4 * 4 = 16
While Over!
for
- 语法结构
for 变量 in 可迭代对象 :
循环体语句组
else :
语句组
- 代码实例
# 迭代字符串
print("----字符串----")
for item in 'hello':
print(item)
# 迭代整数列表
print("----整数列表----")
numbers = [43, 32, 55, 74]
for item in numbers :
print(item)
# 通过range迭代
print("----range()----")
for item in range(10):
print(item)
else :
print('For Over')
- 输出结果
----字符串----
h
e
l
l
o
----整数列表----
43
32
55
74
----range()----
0
1
2
3
4
5
6
7
8
9
For Over
(3)跳转语句 break、continue
break
说明:强行跳出循环体,不再循环
- 代码实例
for item in range(10) :
if item == 3 :
# 跳出循环,不再继续
break
print( item )
- 输出结果
0
1
2
continue
说明:强行结束跳出本次循环,下次继续
- 代码实例
for item in range(10) :
if item == 3 :
# 本次跳出循环,下次继续循环
continue
print( item )
- 输出结果
0
1
2
4
5
6
7
8
9
11. 函数
函数叫法
- 函数:在模块中类之外定义,作用域是当前模块的函数。
- 嵌套函数:在别的函数中定义的函数。
- 方法:在类中定义的函数。
函数语法结构
形式参数:定义函数时的默认参数。
实际参数:调用函数时传递的实际数据。
代码分析:调用函数
def rect_area(width, height): # (width, height)是形参列表
area = width * height
return area
r_area = rect_area(320, 480) # (320, 480)是形参列表
print("{0} * {1} 长方形的面积: {2:.2f}".format(320, 480, r_area))
r_area = rect_area(width=160, height=240)
print("{0} * {1} 长方形的面积: {2:.2f}".format(160, 240, r_area ))
''' 输出结果------
320 * 480 长方形的面积: 153600.00
160 * 240 长方形的面积: 38400.00
'''
代码分析2:参数默认值
def make_coffee(name="卡布奇诺"):
return "制作一杯{0}咖啡。".format(name)
coffee1 = make_coffee()
coffee2 = make_coffee("拿铁")
print(coffee1)
print(coffee2)
''' 输出结果------
制作一杯卡布奇诺咖啡。
制作一杯拿铁咖啡。
'''
代码分析3:可以定义不确定数量的参数( 语法: * 可变参数 )
#---基于元组的可变参数---
def sum(*numbers):
total = 0.0
for number in numbers:
total += number
return total
print(sum(100.0, 20.0, 30.0)) # (100.0, 20.0, 30.0)等多个参数被组成元组numbers
print(sum(30.0, 80.0))
''' 输出结果------
150.0
110.0
'''
#---基于字典的可变参数---
def show_info(**info):
print('-----show_info-----')
for key, value in info.items():
print('{0}: {1}'.format(key, value))
show_info(name='Tony', age=18, sex="male")
''' 输出结果------
-----show_info-----
name: Tony
age: 18
sex: male
'''
变量的作用域
- 作用域:指变量的有效范围。
- 全局变量:在整个模块中创建的变量,作用域是整个模块。
- 局部变量:在函数中创建的变量,作用域是函数内。
x = 20 # 创建全局变量x
def print_value():
x = 10
print("函数中x (局部变量x)= {0}".format(x))
print_value()
print("全局变量x = {0}".format(x) )
''' 输出结果------
函数中x (局部变量x)= 10
全局变量x = 20
'''
函数类型 数据类型
任意一个函数都有数据类型 function,被称为数据类型。
代码分析1:函数可作为另一个函数的返回值使用
def add(a, b):
return a + b
def sub(a, b):
return a - b
def calc(opr):
if opr == '+':
return add
else:
return sub
f1 = calc('+')
f2 = calc('-')
print(type(f1))
print("10 + 5 = {0}".format(f1(10, 5)))
print("10 + 5 = {0}".format(f2(10, 5)))
'''-----输出-----
<class 'function'>
10 + 5 = 15
10 + 5 = 5
'''
过滤函数 filter()
在调用filter()函数时,iterable会被遍历,它的元素会被逐一传入function()函数中。
function()函数若返回True,则元素被保留;若返回False,则元素被过滤。
最后遍历完成,已保留的元素被放到一个新的容器数据中。
注意:filter()函数并不返回列表,需要list()函数转换成列表数据类型
代码分析:
def f1(x):
return x > 50
data1 = [66, 15, 91, 28, 98, 50, 7, 80, 99]
filtered = filter(f1, data1)
data2 = list(filtered)
print(data2)
'''-----结果输出-----
[66, 91, 98, 80, 99]
'''
映射函数 map()
map()函数用于对容器中的元素进行映射(或变换)。
function()函数是一个提供变换规则的函数,返回变换后的元素。
最后遍历完成,已保留的元素被放到一个新的容器数据中。
注意:map()函数并不返回列表,需要list()函数转换成列表数据类型
代码分析:
def f1(x):
return x * 2
data1 = [66, 15, 91, 28, 98, 50, 7, 80, 99]
filtered = map(f1, data1)
data2 = list(filtered)
print(data2)
'''-----结果输出-----
[132, 30, 182, 56, 196, 100, 14, 160, 198]
'''
lambda函数
可以在python中使用lambda关键字定义匿名函数,被称为lambda函数。
语法结构:lambda 参数列表 : lambda 体
。
注意:只有一条语句,不需要 return() 语句返回。
代码分析:
def calc(opr):
if opr == '+':
return lambda a, b: (a+b)
else:
return lambda a, b: (a-b)
f1 = calc('+')
f2 = calc('-')
print("10 + + = {0}".format(f1(10, 5)))
print("10 + + = {0}".format(f2(10, 5)))
'''-----结果输出-----
10 + + = 15
10 + + = 5
'''
12. 类与对象
(1)什么是面向对象?
面向对象是一种编程思想,既按照真实世界的思维方式构建软件系统。
例如:
在真实世界的校园里有学生和老师,
学生有学号、姓名、所在班级等属性数据
,
还有学习、提问、吃饭和走路等动作方法
。
如果我们要开发一个校园管理系统,那么在构建软件系统时,也会有学生和老师等“类
”,
张同学、李同学等是学生类的个体,被称为“对象
”,对象也被称为“实例
”。
(2)什么是类?(类=数据类型)
我们自定义类,既创建一种新的数据类型。
语法格式:
# 父类可以省略声明,表示直接继承object类
class Car(object):
# 类体
pass
实例化类,创建对象
类相当于一个模版,依据这样的模板来创建对象,就是类的实例化,所以对象也被称为“实例”。
语法格式:
# 创建一个小汽车对象,小括号表示调用“构造方法”,构造方法用于初始化对象。
car = Car()
(2.0)在类体中包含的“类的成员”
(2.1)实例变量
实例变量就是对象个体特有的“数据”,例如名称和年龄。
代码分析:
class Dog:
# __init__()方法是构造方法,构造方法用来初始化实例变量。
# 类中的self表示当前对象
# 注意:init前后是两个下划线。
def __init__(self, name, age):
self.name = name # 创建和初始化实例变量name
self.age = age # 创建和初始化实例变量age
d = Dog('大黄', 2) # 创建对象
print('我们家的小狗叫{0},{1}岁了!'.format(d.name, d.age)) # d.name指对实例变量通过“对象.实例变量”形式访问
'''-----结果输出-----
我们家的小狗叫大黄,2岁了!
'''
(2.2)构造方法
类中的 init() 方法是“构造方法
”,用来创建和初始化实例变量。
代码分析:
class Dog:
# 第一个参数必须是self
def __init__(self, name, age, sex='雌性'):
self.name = name # 创建和初始化实例变量name
self.age = age # 创建和初始化实例变量age
self.sex = sex # 创建和初始化实例变量sex
d1 = Dog('球球', 2)
d2 = Dog('哈哈', 1, '雄性')
d3 = Dog(name='琪琪', sex='雄性', age=3)
print('{0}: {1}岁{2}。'.format(d1.name, d1.age, d1.sex))
print('{0}: {1}岁{2}。'.format(d2.name, d2.age, d2.sex))
print('{0}: {1}岁{2}。'.format(d3.name, d3.age, d3.sex))
'''-----结果输出-----
球球: 2岁雌性。
哈哈: 1岁雄性。
琪琪: 3岁雄性。
'''
(2.3)实例方法
实例方法与实例变量一样,都是某个实例(或对象)个体特有的方法。
代码分析:
class Dog:
# 定义构造方法
def __init__(self, name, age, sex='雌性'):
self.name = name # 创建和初始化实例变量name
self.age = age # 创建和初始化实例变量age
self.sex = sex # 创建和初始化实例变量sex
# 定义实例方法
def run(self):
print("{}在跑...".format(self.name))
# 定义实例方法
def speak(self, sound):
print('{}在叫, "{}"!'.format(self.name, sound))
dog = Dog('球球', 2)
dog.run()
dog.speak('旺 旺 旺')
'''-----结果输出-----
球球在跑...
球球在叫, "旺 旺 旺"!
'''
(2.4)类变量
类变量是属于类的变量,不属于单个对象。
代码分析:
class Account:
interest_rate = 0.0568 # 类变量
def __init__(self, owner, amount):
self.owner = owner # 创建并初始化实例变量owner
self.amount = amount # 创建并初始化实例变量amount
account = Account('Tony', 800000.0)
print('账户名:{0}'.format(account.owner))
print('账户金额:{0}'.format(account.amount))
print('利率:{0}'.format(Account.interest_rate)) # 类名.类变量
'''-----结果输出-----
账户名:Tony
账户金额:800000.0
利率:0.0568
'''
(2.5)类方法
类方法与类变量相似,属于类,不属于个体实例。
在定义类方法时,它的第一个参数不是self,而是类本身。
代码分析:
class Account:
interest_rate = 0.0668 # 类变量
def __init__(self, owner, amount):
self.owner = owner # 创建并初始化实例变量owner
self.amount = amount # 创建并初始化实例变量amount
# 类方法,定义类方法需要的装饰器。
@classmethod
def interest_by(cls, amt): # cls代表类自身,即Account类
return cls.interest_rate * amt
interest = Account.interest_by(12000.0) # 对类方法可以通过”类名.类方法“形式访问
print('计算利息:{0:.4f}'.format(interest))
'''-----结果输出-----
账户名:Tony
账户金额:800000.0
利率:0.0568
'''
(3)私有变量与私有方法
- 为了防止外部调用者随意存取类的内部数据(成员变量),内部数据会被封装为“私有变量”。变量前加双画线(__)
- 与私有变量类似,方法前加双画线(__)
代码分析:私有变量
class Account:
__interest_rate = 0.0568 # 类变量(私有类变量)
def __init__(self, owner, amount):
self.owner = owner # 创建并初始化公有实例变量owner
self.__amount = amount # 创建并初始化私有实例变量__amount
def desc(self): # 在类的内部可以访问私有变量
print("{0} 金额:{1} 利率:{2}".format(self.owner, self.__amount, Account.__interest_rate))
account = Account('Tony', 800000.0)
account.desc()
print('账户名:{0}'.format(account.owner))
print('账户金额:{0}'.format(account.__amount)) # 错误发生
print('利率:{0}'.format(account.__interest_rate)) # 错误发生
# 在类的外部不可以访问私有变量
'''-----结果输出-----
Tony 金额:800000.0 利率:0.0568
账户名:Tony
'''
代码分析:私有方法
class Account:
__interest_rate = 0.0568 # 类变量(私有类变量)
def __init__(self, owner, amount):
self.owner = owner # 创建并初始化公有实例变量owner
self.__amount = amount # 创建并初始化私有实例变量__amount
def __get_info(self): # 定义私有方法
return "{0} 金额:{1} 利率:{2}".format(self.owner, self.__amount, Account.__interest_rate)
def desc(self): # 在类的内部可以调用私有方法
print(self.__get_info())
account = Account('Tony', 800000.0)
account.desc()
account.__get_info() # 错误发生
'''-----结果输出-----
Tony 金额:800000.0 利率:0.0568
'''
(4)类中,通过公有的set和get方法访问
为了实现对象的封转,在一个类中不应该有公有的成员变量。这些成员变量应该被设计为私有的,然后通过公有的set(赋值)和get(取值)方法访问。
代码分析:
class Dog:
# 构造方法
def __init__(self, name, age, sex='雌性'):
self.name = name # 创建和初始化实例变量name
self.__age = age # 创造和初始化私有实例变量 __age
# 实例方法
def run(self):
print("{}在跑...".format(self.name))
# get 方法取值,定义get()方法,返回私有实例变量 __age
def get_age(self):
return self.__age
# set 方法赋值,定义set()方法,通过age参数更新私有实例变量 __age
def set_age(self, age):
self.__age = age
dog = Dog('球球', 2)
print('{0}年龄:{1}'.format(dog.name, dog.get_age()))
dog.set_age(3)
print('{0}年龄:{1}'.format(dog.name, dog.get_age()))
'''-----结果输出-----
球球年龄:2
球球年龄:3
'''
代码分析:类中定义属性
class Dog:
# 构造方法
def __init__(self, name, age, sex='雌性'):
self.name = name # 创建和初始化实例变量name
self.__age = age # 创造和初始化私有实例变量 __age ,属性名是age
# 实例方法
def run(self):
print("{}在跑...".format(self.name))
# 在方法前加上装饰器使方法称为属性,属性用起来呢类似公有变量
@property # 定义age属性的get()方法,使用@property装饰器进行修饰,方法名就是属性名,既age
def age(self): # 替换get_age(self)
return self.__age
@age.setter # 定义age属性的set()方法,使用@age.setter进行修饰,age是属性名
def age(self, age): # 替换set_age(self, age)
self.__age = age
dog = Dog('球球', 2)
print('{0}年龄:{1}'.format(dog.name, dog.age)) #方法后面是加()的,属性则不需要
dog.age = 4
print('{0}年龄:{1}'.format(dog.name, dog.age))
'''-----结果输出-----
球球年龄:2
球球年龄:4
'''
(4)继承性
简单理解:
猫是一种特殊动物,具有动物的全部特征 数据
和行为 操作
。
在面向对象中动物是一般类 父类
猫是特殊类 子类
。
特殊类拥有一般类的全部数据
和 操作
,可称之为 子类继承父类
。
注意:构造方法作用是初始化类的实例成员变量。
代码分析:子类继承父类,只有公有的才可被继承。
class Animal: # 定义父类动物 Animal
def __init__(self, name):
self.name = name # 创建并初始化公有实例变量 name
def show_info(self):
return "animal's name: {0}".format(self.name)
def move(self):
print("动一动···")
class Cat(Animal): # 定义子类猫 Cat
def __init__(self, name ,age):
super().__init__(name) # 调用父类构造方法,初始化父类成员变量
self.age = age # 创建并初始化公有实例变量 age
cat = Cat('Tom', 2)
cat.move()
print(cat.show_info())
'''-----结果输出-----
动一动···
animal's name: Tom
'''
代码分析:子类继承多个父类,优先级根据类从高到低。
class Horse:
def __init__(self, name):
self.name = name
def show_info(self):
return "马的名字:{0}".format(self.name)
def run(self):
print("马跑...")
class Donkey:
def __init__(self, name):
self.name = name
def show_info(self):
return "驴的名字:{0}".format(self.name)
def run(self):
print("驴跑...")
def roll(self):
print("驴打滚...")
class Mule(Horse, Donkey):
def __init__(self, name, age):
super().__init__(name)
self.age = age
m = Mule('莉莉', 1)
m.run() # 继承父类Horse方法
m.roll() # 继承父类Donkey方法
print(m.show_info()) # 继承父类Horse方法
'''-----结果输出-----
马跑...
驴打滚...
马的名字:莉莉
'''
(4.1)方法重写(Override覆盖)
如果子类的方法名与父类的方法名相同,子类方法会重写(既覆盖)父类的同名方法。
注意:
代码分析:子类继承父类,只有公有的才可被继承。
class Horse:
def __init__(self, name):
self.name = name
def show_info(self):
return "马的名字:{0}".format(self.name)
class Mule(Horse):
def __init__(self, name, age):
super().__init__(name)
self.age = age
def show_info(self): # 重写父类方法 show_info()
return "驴的名字:{0}".format(self.name)
m = Mule('莉莉', 1)
print(m.show_info())
'''-----结果输出-----
驴的名字:莉莉
'''
(5)多态性
python解释器不检查发生多态的对象是否继承了同一个父类,只要它们有相同的行为(方法),它们之间就是多态的。
Tip:函数start()接收具有“叫” speak()方法的对象。
# 接收的obj 对象具有speak()方法
def start(obj):
obj.speak()
代码分析:子类继承父类,只有公有的才可被继承。
class Animal:
def speak(self):
print('动物叫!')
class Dog(Animal):
def speak(self):
print('小狗叫!')
class Cat(Animal):
def speak(self):
print('小猫叫!')
class Car:
def speak(self):
print('汽车嘀!')
start(Dog())
'''-----结果输出-----
'''
13. 异常处理
13.1 除零异常
在数学中,任何整数都不能除以0,如果在计算机程序中将整数除以0,则会引发异常。
程序运行出错时会有Traceback信息,Traceback信息是“异常堆栈(zhan)信息”,描述了程序运行的过程及引发异常的信息。
代码分析:
i = input('请输入数字:')
n = 8888
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
'''-----结果输出-----
请输入数字:0
Traceback (most recent call last):
File "C:\000NoteBook\WY202105\pythontest\test\000test.py", line 4, in <module>
result = n / int(i)
ZeroDivisionError: division by zero
'''
13.2 捕获异常 | try-except 语句
我们不能防止用户输入0,但在出现异常后我们能捕获并处理异常,不至于让程序发生终止并退出。
代码分析:单个except代码块。
# coding=utf-8
# 代码文件:test.py
i = input('请输入数字:')
n = 8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e: # e是一个异常对象,是一个变量。异常类型:ZeroDivisionError。
print("不能除以0,异常:{}".format(e))
'''-----结果输出-----
请输入数字:0
不能除以0,异常:division by zero
'''
代码分析:多个except代码块。
# coding=utf-8
# 代码文件:test.py
i = input('请输入数字:')
n = 8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e: # e是一个异常对象,是一个变量。异常类型:ZeroDivisionError。
print("不能除以0,异常:{}".format(e))
except ValueError as e: # 捕获整数转换异常
print("输入的是无效数字,异常:{}".format(e))
'''-----结果输出-----
请输入数字:A
输入的是无效数字,异常:invalid literal for int() with base 10: 'A'
'''
代码分析:多重异常捕获,多个except代码块合并。
# coding=utf-8
# 代码文件:test.py
i = input('请输入数字:')
n = 8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except (ZeroDivisionError, ValueError) as e:
print("异常发生:{}".format(e))
'''-----结果输出-----
请输入数字:0
异常发生:division by zero
请输入数字:A
异常发生:invalid literal for int() with base 10: 'A'
'''
代码分析:语句嵌套。
# coding=utf-8
# 代码文件:test.py
i = input('请输入数字:')
n = 8888
try:
i2 = int(i)
try:
result = n / int(i2)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e1:
print("不能除以0,异常:{}".format(e1))
except ValueError as e2:
print("输入的是无效数字,异常:{}".format(e2))
'''-----结果输出-----
请输入数字:0
不能除以0,异常:division by zero
请输入数字:A
输入的是无效数字,异常:invalid literal for int() with base 10: 'A'
'''
13.3 使用finally代码释放资源
代码分析:
# coding=utf-8
# 代码文件:test.py
i = input('请输入数字:')
n = 8888
try:
result = n / int(i)
print(result)
print('{0}除以{1}等于{2}'.format(n, i, result))
except ZeroDivisionError as e: # e是一个异常对象,是一个变量。异常类型:ZeroDivisionError。
print("不能除以0,异常:{}".format(e))
except ValueError as e: # 捕获整数转换异常
print("输入的是无效数字,异常:{}".format(e))
finally:
# 释放资源代码
print('资源释放...')
'''-----结果输出-----
请输入数字:0
不能除以0,异常:division by zero
资源释放...
请输入数字:A
输入的是无效数字,异常:invalid literal for int() with base 10: 'A'
资源释放...
'''
13.4 自定义异常类
实现自定义异常类,需要继承Exception类或其子类,之前我们遇到的ZeroDivisionError和ValueError异常都属于Exception的子类。
# coding=utf-8
# 代码文件:test.py
class MyException(Exception):
def __init__(self, message): # 构造方法,其中的参数message是异常描述信息。
super().__init__(message) # 调用父类构造方法,并把参数message传给父类构造方法。
'''-----结果输出-----
'''
14. 常用模块
14.1.1 内置模块-数学计算(math)
14.1.2 内置模块-日期时间(datetime)
在datetime模块中提供了以下几个类,
类名 | 描述 |
---|---|
datetime | 包含时间和日期 |
date | 只包含日期 |
time | 只包含时间 |
timedelta | 计算时间跨度 |
tzinfo | 时区信息 |
datetime类
构造方法创建datetime对象:
datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
# coding=utf-8
# 代码文件:test.py
import datetime
d0 = datetime.datetime(2020, 1, 29, 23, 56, 59, 10000)
d1 = datetime.datetime.today() # datetime.now(tz=None),参数tz设置时区,为None或省略,则等同于today()
d2 = datetime.datetime.now()
d3 = datetime.datetime.fromtimestamp(999999999.999) # datetime.fromtimestamp(timestamp,tz=None)返回与UNIX时间戳对应的本地时期和时间。
print(d0)
print(d1)
print(d2)
print(d3)
# UNIX时间戳是从1970年1月1日00:00:00开始到现在为止的总秒数。
'''-----结果输出-----
2020-01-29 23:56:59.010000
2021-07-24 21:59:49.964642
2021-07-24 21:59:49.964641
2001-09-09 09:46:39.999000
'''
date类
datetime.date(year, month, day)
# coding=utf-8
# 代码文件:test.py
import datetime
d0 = datetime.date(2020, 2, 29)
d1 = datetime.date.today()
d2 = datetime.date.fromtimestamp(999999999.999)
print(d0)
print(d1)
print(d2)
# UNIX时间戳是从1970年1月1日00:00:00开始到现在为止的总秒数。
'''-----结果输出-----
2020-02-29
2021-07-24
2001-09-09
'''
time类
datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
timedelta类
将日期时间与字符串相互转换
- 将 “日期时间对象” 转换为 “字符串” 时,称之为 “日期时间格式化”。实例方法
strftime(format)
- 将 “字符串” 转换为 “日期时间对象” 时,称之为 “提起时间解析”。实例方法
datetime.strptime(date_string,format)
# coding=utf-8
# 代码文件:test.py
import datetime
d0 = datetime.datetime.today()
d0.strftime('%Y-%m-%d %H:%M:%S')
str_date = '2020-02-29 10:40:26'
d1 = datetime.datetime.strptime(str_date, '%Y-%m-%d %H:%M:%S')
print(d0)
print(d1)
'''-----结果输出-----
2021-07-24 22:27:17.256225
2020-02-29 10:40:26
'''
14.1.3 内置模块-正则表达式(re)
正则表达式:指预先定义好一个“字符串模版”,可以匹配、查找和替换那些匹配“字符串模版”的字符串。
# coding=utf-8
# 代码文件:test.py
import re
p = r'\w+@163\.com' # 验证邮箱的正则表达式,既 字符串模版
email1 = 'pindar25@163.com' # 要验证的邮箱字符串
m = re.match(p, email1) # 返回非空的Match对象,说明匹配成功
print(m)
'''-----结果输出-----
<re.Match object; span=(0, 16), match='pindar25@163.com'>
解析:
输出Match对象;
span指字符串跨度,(0, 16)表示找到的字符串位置;
'''
15.文件读写
15.1 文件打开
知识点
open()函数的语法结构:
open(file, mode='r' ,encoding=None, errors=None)
file | 表示要打开的文件,可以是字符串或整数 |
---|---|
mode | 设置文件打开模式 |
encoding | 指定文件编码,默认是UFT-8编码 |
errors | 异常处理。如果取值为ignore,表示编码错误仍然继续执行不会退出。 |
案例分析
# coding=utf-8
# 代码文件:test.py
# 案例1
f = open('test.txt', 'w+') # 以w+读写模式打开文件,如果文件不存在,则在py文件所在路径下创建文件
f.write('World')
# 案例2
f = open('test.txt', 'r+') # 以r+读写模式打开文件,如果文件不存在,则抛出异常。由于前面已经创建文件,所以会覆盖文件内容。
f.write('Hello')
# 案例3
f = open('test.txt', 'a') # 以a读写模式打开文件,会在文件末尾追加内容。
f.write(' Human')
fname = 'F:/0_HOME/WORK/Python/Projects/Panxjtest_Prj/test.txt'
f = open(fname, 'a+')
f.write(", I'm a tmp.py.")
'''-----结果输出-----
'''
15.2 关闭文件
知识点
对文件的操作往往会抛出异常,为了保证对文件的操作无论是正常结束还是异常结束,都能够关闭文件。
我们应该将对close()方法的调用放在异常处理的finally代码块中。
案例分析:在finally代码块中关闭文件
# coding=utf-8
# 代码文件:test.py
# 使用finally关闭文件
f_name = 'test.txt'
f = None
try:
f = open(f_name) # 可能引发FileNotFoundError异常
content = f.read() # 可能引发OSError异常
print(content)
except FileNotFoundError as e:
print('文件不存在,请先使用test.py程序创建文件')
except OSError as e:
print('处理OSError异常')
finally:
if f is not None:
f.close()
'''-----结果输出-----
Hello Human, I'm a tmp.py.
'''
案例分析:在with as代码块中关闭文件
在as后面生命一个资源变量,结束后自动释放资源。
# coding=utf-8
# 代码文件:test.py
# 使用with as自动资源管理
f_name = 'test.txt'
with open(f_name) as f:
content = f.read()
print(content)
'''-----结果输出-----
Hello Human, I'm a tmp.py.
'''
15.3 案例-复制文本文件
知识点
read(size= -1) | 从文件中读取字符串,size限制读取的字符数,size= -1指对读取的字符数没有限制。 |
---|---|
readline(size= -1) | 在读取到换行符或文件尾时返回字符串。如果已经到文件尾,则返回一个字符串。size限制读取的字符数,size= -1指对读取的字符数没有限制。 |
readlines() | 读取文件数据到一个字符串列表中,每一行数据都是列表的一个元素。 |
write(s) | 将字符串s写入文件中,并返回写入的字符数。 |
writelines(lines) | 向文件中写入一个字符串列表。不添加行分隔符,因此通常为每一行末尾都提供行分隔符。 |
flush() | 刷新写缓冲区,在文件没有关闭的情况下将数据写入文件中。 |
案例分析
# coding=utf-8
# 代码文件:test.py
f_name = 'test.txt'
with open(f_name, 'r', encoding='gbk') as f:
lines = f.readlines() # 读取所有数据到一个列表中
copy_f_name = 'copy_test.txt'
with open(copy_f_name, 'w', encoding='utf-8') as copy_f:
copy_f.writelines(lines)
'''-----结果输出-----
'''