PYTHON知识笔记

一. Python的概述

1.1 Python 简介

1) Python的概述

Python 是一门开源编程语言,由荷兰程序员吉多·范·罗苏姆(Guido van Rossum)发明(龟叔),并以英国喜剧团体“蒙提·派森(Monty Python)的飞行马戏团”命名,Python这门语言创建的1989年的圣诞节进行开发的;

Python目前存在两个版本Python2.X版本和Python3.X版本,其中Python2.X版本在2020年1月1日不在进行更新,目前Python3.X最新的版本是Python3.8版本。

Python是一门面向对象,解释性,弱类型的脚本语言,其中解释性语言具备天生的跨平台的功能,只需要特点的平台就可以解释执行语句,弱类型是指变量的类型可以随意的改变,不需要其他定义数据类型(既在内存中不需要开辟指定空间的内存);

Python的特点:是清晰的语法可扩展性,其中清晰的语法是清晰,但是格式不是自由的,需要控制缩进来进行对应内容,可扩展性是指模块丰富

Python的缺点:速度慢,比Java,C语言的运行效率都要慢,另一个是元代码加密困难,因为解析性语言不需要进行编译的过程,所以加密困难

2) Python的运行机制

 

 

示意图:

 

1.由源代码转变成机器码的过程分成两类:编译和解释。

2.编译:在程序运行之前,通过编译器将源代码变成机器码,例如:C语言。

-- 优点:运行速度快

-- 缺点:开发效率低,不能跨平台。

3.解释:在程序运行之时,通过解释器对程序逐行翻译,然后执行。例如Javascript

-- 优点:开发效率高,可以跨平台;

-- 缺点:运行速度慢。

4.python是解释型语言,但为了提高运行速度,使用了一种编译的方法。编译之后得到pyc文件,存储了字节码(特定于Python的表现形式,不是机器码)。

源代码 -- 编译 --> 字节码 -- 解释 --> 机器码

|————1次———|

 

1.2 Python环境

1) 环境和软件的下载

移动硬盘:\数据挖掘资源及其环境\python环境

2) 环境和内容介绍

环境:Python 3.7版本

注意:安装环境注意打上勾的添加到Path系统变量当中

软件:pycharm 2019.3版本企业版

注册码在对应软件里面

 

1.3 Python运行方式

1) 交互模式

Python 自带了一个叫 IDLE 的程序,全称是交互式开发环境;它也是“蒙提·派森 的飞行马戏团”的成员埃里克·艾多尔(Eric Idle)的姓氏。我们将在 IDLE 中输入 Python代码。安装好 Python 之后,在 Explorer(PC)、Finder(Mac)或 Nautilus(Ubuntu)中搜索 IDLE。建议为其创建一个桌面快捷方式,以方便查找。点击 IDLE 程序的图标,带有如下文字说明的程序就会启动(准确的文字可能会有所变化,但是即使没有说明或略有不同都不用担心):  

这个程序被称为交互式 shell。可以直接在其中键入 Python 代码,程序就会打印出结果。在提示符>>>后面键入;

总结:

在命令行输入指令,回车即可得到结果。

1.打开终端

2.进入交互式:python3

3.编写代码:print(“hello world”)

4.离开交互式:exit()

2) 文件模式

将指令编写到.py文件,可以重复运行程序。

1.编写文件。

2.打开终端

3.进入程序所在目录:cd 目录

4.执行程序: python3 文件名

二 编程概论

2.1 注释

1) 什么是注释

注释(comment)是用英文或其他自然语言写的一行(或一部分)代码,行首均有一个特殊标志告知编程语言忽略这行代码。

2) 注释的目的

是解释代码的功能。程序员通过注释,使得代码更易于阅读。在注释中, 可以写下任何内容。

3) 注释的分类

单行注释和多行注释

4) 注释的创建

单行注释使用 # 来表示这一行是注释内容;

多行注释使用''' '''或者""" """来创建多行注释,如果多行注释使用在第一行称为文档注释,可以使用方法进行提取文档信息;

5) 案例的展示

'''
注释使用,称为文档注释
'''
# 这是一行单行注释
print('hello word')
'''
这里面是多行的注释
# print('hello word')
'''
""""
三个双引号页可以
"""

实现效果:

 

 

 

2.2 变量

1) 什么是变量

变量是用来存储数据的容器;

常量(constant)是一个永远不会改变的值。上面示例中的每一个数字,都是常量;数字 2 永远表示的值为 2。

变量(variable)则相反,指的是会改变的值。变量由一个或多个字符组成的名称构成,并使用赋值符(assignment operator)等号赋予了这个名称一个值。

Python中没有存在常量的概念,如果需要的常量的话,可以将单词全部大写默认就是常量;

代码演示:

# 创建一个变量
a=3

2) 弱类型定义

弱语言的两个典型的特征:

a.变量无需声明就可以直接赋值:对一个不存在的变量的赋值就是相当于定义了一个的新的变量;

b.变量的数据的类型可以动态的改变的,同一个的变量的可以一会赋值为整数值,一会可以赋值为字符串类型;

代码演示:

# 弱类型的特点
# 无需要声明直接创建:对应JAVA int b=3 声明 b的类型为int类型
b=3
# 可以动态改变数据类型
print('b的初始类型为:{}'.format(type(b)))
b='1'
print('b的改变之后类型为:{}'.format(type(b)))

执行效果:

 

3) 变量的类型及其转换

a. 数据类型

空值对象 None

本质:表示不存在的对象

作用:占位和解除对象关系

代码演示:

# 变量的类型
# None空值对象
a=None
# 打印的a的类型
print('a的类型为{}'.format(type(a)))

效果展示:

 

整型 int

定义:表示整数,包括正数,负数和0;

表示方式:

十进制 5,

二进制 0b开头,

八进制 0o开头,

十六进制0x开头

注意点:小整数对象池:CPython 中整数 -5 至 256,永远存在小整数对象池中,不会被释放并可重复使用。

代码演示:

# 整数类型
# 十进制的形式
i1=12
# 二进制形式
i1=0b11
# 八进制形式
i3=0o01237
# 十六进制
i4=0xf129
# 小数池重用
print(id(5))
print(id(5))

效果展示:

 

浮点型 float

定义:表示小数,包含正数、负数,0.0)。

表示方式:

小数形式 0.0;

科学计数法 e/E(正负号)指数

代码演示:

# 浮点数
# 小数形式
f1=12.0
# 情况省略0
f2=12.
f3=.12
# 科学计数法
f4=1e-3
print(f4)
# 省略0的情况,
f5=.2e-3
print(f5)

效果展示:

 

字符串 str

定义:是用来记录文本信息(文字信息)。

表示方式:

' '/" "/""" """

代码演示:

# 字符串类型
# 字符串表示
s1='1222'
s2="2222"
s3=""" 12333 """
print(s1,s2,s3)

效果展示:

 

 

复数 complex

定义:由实部和虚部组成的数字。虚部是以j或J结尾

表示方式:

1+2j

代码演示:

# 复数的形式
c1=1+2j
print(c1+3j)

效果展示:

 

 

布尔 bool

定义:用来表示真和假的类型

表示方式:

True 表示真(条件满足或成立),本质是1

False 表示假(条件不满足或不成立),本质是0

 

代码演示:

# 布尔类型
b1=True
b2=False

 

b. 数据类型转换

1.转换为整形: int(数据)

2.转换为浮点型:float(数据)

3.转换为字符串:str(数据)

4.转换为布尔:bool(数据)

结果为False:bool(0) bool(0.0) bool(None)

5.混合类型自动升级:

1 + 2.14 返回的结果是 3.14

1 + 3.0 返回结果是: 4.0

代码演示:

# 类型转换
# 将字符串转换成int类型,但是如果是str->int,那么字符串必须是整数,不然会报错
t1='12'
t2=int(t1)
print('t2的类型为{},t2的值是{}'.format(type(t2),t2))
# 转布尔类型 0,0.0,'',None的转为布尔为False
t3=bool(0)
print('t3的类型为{},t3的值是{}'.format(type(t3),t3))
t4=1
print('t4的初始类型为{}'.format(type(t4)))
t4=1+2.0
print('t4的运算之后类型为{}'.format(type(t4)))

效果展示:

 

 

c. del语句

作用:用于删除变量,同时解除与对象的关联.如果可能则释放对象。

语法:del 变量名1 变量2

本质:自动化内存管理的引用计数,每个对象记录被变量绑定(引用)的数量,当为0时被销毁。

代码演示:

del t1,t2
print(t1,t2)

效果展示:

 

 

4) 变量内存图

执行的流程:

1.先创建赋值的对象;

2.在将赋值的对象的地址赋值给变量;

3.变量的本身是没有类型的,它的类型的取决于赋值对象类型;

可以使用type()函数查看类型,id()函数查看的地址

内存图示意:

 

代码演示:

# 变量内存图演示
person_name = '张无忌'
class_id = '1906'
person_name = '张翠山'
name=person_name

# id为2351114977328
print('"张无忌"的id为{}'.format(id('张无忌')))
# id为2351114977328
print('变量person_name 的id为{}'.format(id(person_name)))
# id为2351114977328
print('"1906"的id为{}'.format(id('1906')))
# id为2351114977328
print('"张翠山" 的id为{}'.format(id('张翠山')))
# id
print('变量person_name 的id为{}'.format(id(person_name)))

效果展示:

 

5) 命名的规则

命名:必须是字母或下划线开头,后跟字母、数字、下划线。

不能使用关键字(蓝色),否则发生语法错误:SyntaxError: invalid syntax。

建议命名:字母小写,多个单词以下划线隔开。

如:class_name

代码演示:

# 命名关键字演示错误
int=3
int('4')

效果展示:

 

6) 关键字和内置函数

a.关键字

 

b.内置函数

   

其中的输入和输出的内置函数:

输出函数print的使用

print函数的语法格式为:

 

从语法格式可以知道:value参数可以接受任意多个的变量和值,中间用,分隔 ,也可以修改分隔符 seq参数修改,也可以操作输出之后的操作end,默认是换行;

代码演示:

# 输出函数
# 输出多个参数/变量,中间用,隔开
print('i的值是:',i)
# 修改分割符
print('i的值是:',i,sep='|')
# 修改输出之后的操作,默认是换行
print('i的值是:',i,sep='|',end='\t')
print('i的值是:',i,sep='|',end='\t')

效果展示:

 

输入函数的使用input函数使用:

作用:向用户生成一条的提示,然后获取用户的额输入的内容,由于的input函数总会把用户的输入的内容的放在字符串中,因此的用户输入的任何内容返回的都是一个字符串

代码演示:

# 输入函数的使用
user_age=input('请用户输入的年龄:')
print('获取的数据类型为{},数据为:{}'.format(type(user_age),user_age))
# 需要进行转换
user_age2=int(input('请用户输入的年龄:'))
print('获取的数据类型为{},数据为:{}'.format(type(user_age2),user_age2))

效果展示:

 

压缩函数-zip

使用zip()函数可以把两个列表的'压缩'成一个zip对象的(可以迭代的对象)

代码演示:

c=[1,3]
b=[2,3]
print([x for x in zip(c,b)]) #[(1, 2), (3, 3)]

如果长度不一样,长度以段的列表为准

反转函数-reversed()

该函数可以接收各种的序列的参数,然后返回一个反序排列的迭代器

排序函数 -sorted()

在使用的sorted排序的开可以使用reverse参数。如果设置为True,,那么就反向输出,还可以指定key参数的,指定的排序的关键字。

2.3 运算符

1) 运算符类型

a.算术运算符

+     加法

-     减法

*      乘法

/      除法:结果为浮点数

//    地板除:除的结果去掉小数部分

%     求余

**    幂运算

代码演示:

# 算法运算符
a=1
b=2
c=a+b
# +作为字符串连接使用
a='aa'+"bb"# aabb

# * 乘法 字符串的重复
a='ab'*3 #ababab
c=1*3 #3
# /除法
print(2/1) # 2.0 数学的除法,变成浮点类型
print(1/2) # 0.5
# //地板除
print(1//2) # 0 取整数
# **乘方
print(2**3)  #8
# % 求余
print(3%2)  #1

 

b.增强运算符

y += x           等同于 y = y + x

y -= x            等同于 y = y - x

y *= x            等同于 y = y * x

y /= x            等同于 y = y / x

y //= x           等同于 y = y // x

y %= x            等同于 y = y % x

y **= x           等同于 y = y ** x

c.比较运算符

 <          小于

 <=       小于等于

 \>          大于

 \>=       大于等于

 ==       等于

 !=         不等于

返回布尔类型的值

比较运算的数学表示方式:0 <= x <= 100

d.逻辑运算符

与and

表示并且的关系,一假俱假。         

示例:

​    True and True       # True

​    True and False      # False

​    False and True      # False

False and False     # False

或or

表示或者的关系,一真俱真     

  示例:

True or True         # True

True or False         # True

False or True         # True

False or False        # False 

非 not 

表示取反

例如:

not True   # 返回False

not False  # 返回True

短路运算

一但结果确定,后面的语句将不再执行。

f.身份运算符

语法:

x is y

x is not y

作用:

is 用于判断两个对象是否是同一个对象,是时返回True,否则返回False。

is not 的作用与is相反

e. 赋值运算符

语法:

变量名 = 值

作用:

赋值运算符用于为变量或者常量指定值,通常使用"="作为运算符

代码演示:

# 赋值的操作
a=1
b=3
# 把变量进行赋值操作
a=b
# 多个赋值操作
a=b=3
# 将表达式的结果赋值给变量
c=1+2+b

g.位运算符

位运算的通常的在图形,图像处理的和创建的设备驱动等底层开发进行使用的。使用的位运算的可以直接的操作的数值的原始的bit位。

python的支持的位运算符有6个:

 

 

h.索引运算符

索引运算符就[],在方括号中可以使用单个的索引值,也可以使用索引范围,同时也可以指定步长

代码演示:

# 索引运算符
a='abcdefghjkm'
# 单个范围
print(a[1]) #b
# 指定范围
print(a[1:3]) # bc 不包括3
# 指定范围并且指定步长
print(a[1::2]) #bdfhk
# 反向指定
print(a[-1]) #m

注意点:

布尔类型的的True和False在参与算术运算的时候,会把True当做1,False当做0;

代码演示:

# 注意点
# 参与算术运算
print(1+True) #2
# 其他运算报错误
print('t'+True) #typeError: can only concatenate str (not "bool") to str

l.成员运算符 in

python提供了in运算符,用来判断的某个成员是否存在序列当中;

除了提供in运算之外还提供的:not in 运算

代码演示:

# 成员运算符
a='abcdefghjkm'
# 需要连续的元素
print('ac' in a) #False
print('cd' in a) #True

j.三目运算符

语法格式:

 

运算规则:  

代码演示:

# 三目运算符
a=3
b=4
r= 'a>b' if a>b else b
print(b) # 4

# 复杂的三目运算
# 多条语句以,隔开的,每一条的语句都会执行,程序返回的多条语句的返回值组成的元组,
# 最后一个值会改变
a=3
b=4
r=print('a>b'),'a','c' if a>b else 'a--'
print(r) #(None, 'a', 'a--')
r1=print('a>b'),'a','c' if ab');'a';'c' if a>b else 'a--'
print(r) #None
r1=print('a>b');'a';'c' if a

 

2) 运算符优先级

优先级图:

 

高到低:

算数运算符

比较运算符

快捷运算符

身份运算符

逻辑运算符

 

2.4 语句问题

语句(statement)这个术语可用来描述 Python 语言的多种构成部分。可以将一个Python 语句视作一个命令或计算。

Python 中有两类语句:简单语句(simple statement)和复合语句(compound statement)。简单语句一般就是一行代码,而复合语句通常包括多行代码。

1) 行

  1. 物理行:程序员编写代码的行。

  2. 逻辑行:python解释器需要执行的指令。

  3. 建议一个逻辑行在一个物理行上。

  4. 如果一个物理行中使用多个逻辑行,需要使用分号;隔开。

  5. 如果逻辑行过长,可以使用隐式换行或显式换行。

隐式换行:所有括号的内容换行,称为隐式换行

括号包括: () [] {} 三种

显式换行:通过折行符 \ (反斜杠)换行,必须放在一行的末尾,目的是告诉解释器,下一行也是本行的语句。

2) pass 语句

通常用来填充语法空白。

3) 断言

断言语句和if分支有点类似,它对于的一个bool表达式的进行断言的,如果bool表达式为True,该程序可以接着向下执行,放在会引发AssertionError错误

代码演示:

user_age=int(input('请输入年龄:'))
assert 20

展示效果:

 

2.5 流程控制

在任何的编程语言的当中的最常见的程序的结构就是顺序结构,顺序结构就是程序从上到下一行一行的的执行的,中间没有任何的判断和跳转。

如果Python程序的的多行代码之间没有任何的流程控制,则程序的就是默认从上到下的依次执行,排在后面的代码的后执行的。

1) 选择语句

a.if 分支结构

if语句可以使用任意的表达式的作为分支条件的进行分支控制,Python的if语句提供了三种的形式: 

对应的上面的if分支语句的,执行过程很简单,就是如果if条件为真,程序就会执行if条件的后面的语句块的;否则就会依次判断的elif条件(如果有的话),如果的elif的条件为真的,那么程序就是执行elif条件的后面的语句块...,如果前面条件都为假的话,就会执行else后面的语句块(如果有的话)。

if语句后面 的语句,具备同一个缩进的称为代码块,一个代码块会被当成的一个的整体来执行的(除非在当中遇见跳转语句(return.break,continue)),

python的代码块是通过缩进来进行标记的,具备相同缩进的多行代码属于同一个的代码块的,其中if 条件的:代表代码块的开始点。

代码演示:

user_age=int(input('请输入年龄:'))
if user_age>20:
    print('{}>20岁'.format(user_age))
    print('执行完成')
# 如果放在这里不属于条件语句块的一部分,不具备相同缩进
#print('执行完成')

a=12
if a>12:
    print('{}>12'.format(a))
else:
    print('{}<=12'.format(a))

b=3
if b<0 or b>50:
    print('b不在1到50之间')
elif b>40:  # 隐含条件 b>0 or b<50 加上b>40
     print('b在40到50之间')
elif b>30:
     print('b在30到40之间')
elif b>20:
     print('b在20到30之间')
elif b>10:
     print('b在10到20之间')
else:
     print('b在10之内')

效果:

 

 

b. if条件的类型

python的执行的if语句的时候,会判断的if条件是True还是False,那么if条件表达式不仅仅可以使用的bool类型的表达式,还可以式其他的任意的类型,其中下面的的表达式会被当成False进行处理

False,None,0,'',[],().{}

代码演示:

# 字符串为’‘
if '':
    print('字符非空')
else:
    print('字符串为空')
# 空值对象
if None:
    print('非空值对象')
else:
    print('空值对象')

效果展示:

 

c.if表达式

参考三目表达式

 

2) 循环语句

a.循环语句概述

循环语句可以在满足循环的条件的情况下,反复的执行某一段代码的,这段反复的执行的代码称为的循环体。当反复执行这个的循环体的时候的,需要在合适的时候的把循环的条件改成假,从而结束循环,否则循环会一直执行下去形成死循环。

循环体的组成:

初始化语句: 一条或者多条语句完成一些初始化的操作的,初始语句的在循环体开始之前执行;

循环条件:这是一个布尔表达式的,这个表达式决定是否执行循环体;

循环体:这个部分是循环 的主体,如果循环条件的允许的,这个代码块就会被反复的执行的。

迭代语句:这个部分的在一次的执行的循环体结束的之后的,对循环的条件求值之前操作,通常是控制的循环条件的中的变量的,使循环体在合适的时候结束。

b.循环语句

I.while循环

语法格式:

 

whille循环体的在每一次的执行循环体之前,都会对的布尔循环条件进行求值,如果是真的,就执行循环体。

代码演示:

count_i=0
while count_i<10:
    print('count:',count_i)
    count_i+=1
print('循环结束')

效果展示:

 

应用场景:

使用while来循环遍历列表和元组,字符串

代码演示:

a=['1',12,34,67]
while len(a):
    print(a.pop())

a='sssfsfas'
i=0
while i

II.for循环

for-in循环是专门是遍历范围,列表,元素和字典等的可以迭代的对象包含的元素

语法格式:  

上面语法格式说明:

for-in循环中的 变量的值受到for-in循环控制,该变量的会在每次循环的时候开始被自动赋值,因此程序不应该在循环的中对该变量赋值。

for-in循环可以用在遍历的任何可以迭代的对象的,所谓可以的迭代的对象,就是指对象中包含一个_iter__方法,并且该方法时的返回对象具有next()方法。

for-in 遍历范围/字符串/列表/元组使用:

代码演示:

# 遍历范围
user_num=int(input('请输入阶乘的数:'))
result=1
for num in range(1,user_num+1):
    result*=num
print('阶乘法的结果为{}'.format(result))

# 遍历字符串
a='s我so13'
for i in a:
    print('遍历字符串的结果:{}'.format(i))

# 遍历列表
l=[1,'3','sds',(1,2)]
for i in l:
    print('遍历列表的结果为:{}'.format(i))

# 遍历元组
t=(1,'2','21')
for i in t:
    print('遍历元组的结果为:{}'.format(i))

实现效果:

 

案例演示:

src_list=[12,1.0,'22',(1,2),2,3.0,True]
my_sum=0
my_count=0
for ele in src_list:
    # 如果该元素是整数会在是浮点数
    if isinstance(ele,int) or isinstance(ele,float):
        print(ele)
        # 累加元素的值
        my_sum += ele
        # 累加元素的个数
        my_count += 1
print('总和为:{}'.format(my_sum))
print('平均数为:{}'.format(my_sum/my_count))
# 其中布尔类型在isinstance当中会被当中0/1进行处理

效果展示:

 

 

for-in+range范围的方式遍历元素:

也可以通过索引来进行遍历列表和元组的,只要让循环计数遍历0到列表的长度的区间的。通过使用来获取对应的元素;

代码演示:

src_list=[12,1.0,'22',(1,2),2,3.0,True]
for i in range(0,len(src_list)):
    print(src_list[i])

 

采用for-in来遍历字典:

使用for-in 遍历的字典其实也是通过遍历的普通的列表的来实现的,字典包含的三个方法:

items():返回字典的中所有的key-value对的列表

keys():返回的字典当中的所有的key的列表

values():返回的字典的当中的所有的value列表

案例演示:

my_dict={'语文':89,'数学':90,'英语':89}

for i in my_dict.items():
    print(i)

# 遍历key,通过key获取value
for i  in my_dict.keys():
    print('key为:{}的对应的value为:{}'.format(i,my_dict[i]))

# 遍历的value
for i in my_dict.values():
    print(i)

效果展示:

 

 

for表达式

for列表推导式

for表达式可以利用的区间的.元组。列表等的可迭代的元素的创建新的列表,

for表达式的语法格式:

 

for表达式和for循环的区别:

在for关键字之前定义一个表达式,这个表达式通常会包含的循环计数器;

for表达式没有循环体,所以不需要冒号;

for表达式也是有循环的,同样会对迭代对象的进行循环的操作,可迭代对象包含几个对象,该循环就对for之前的表达式执行几次,并且将每一次执行的值的收集起来的作为新的元素。

代码演示:

# 演示for列表推导式
a_range=range(10)
a_list=[x * x for x in a_range ]
print(a_list) # 结果 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 有条件的推导式
a_list=[x * x for x in a_range if x % 2 ==0]
print(a_list) # 结果 [0, 4, 16, 36, 64]

for生成器推导式

对于使用的圆括号的for表达式的,最终的返回的是生成器的,因此的这种for表达式称为生成器推导式

代码演示:

# for生成器的推导式---返回的是一个生成器
a_range=range(10)
c_g=(x * x for x in a_range if x % 2 ==0)
for g in c_g:
    print(g,end='\t') #0	4	16	36	64

嵌套循环

for表达式可以使用多个循环的,就像嵌套循环一样;

代码演示

d_list=[(x,y) for x in range(5) for y in range(4)]
#[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), 
# (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), 
# (3, 0), (3, 1), (3, 2), (3, 3), (4, 0), (4, 1), 
# (4, 2), (4, 3)]
print(d_list)

 

 

c.循环体使用else

python的循环体的都可以定义的else代码块,当循环条件为False的时候,程序就会执行的else代码块

for循环体也可以使用else代码的,当for循环执行完成的就会执行else代码块

案例演示:

my_dict={'语文':89,'数学':90,'英语':89}

for i in my_dict.items():
    print(i)
else:
   print('最后一个元素:{}'.format(i))

实现效果:

 

3) 跳转语句

Python没有提供的goto语句来控制的程序的跳转,提供了continue和break来控制循环结构。出除此之外还可以使用return结束整个方法。

a.break语句

满足某种的条件就需要强制终止的循环,可以使用break结束循环,跳出循环体;执行循环体之后的代码

b.continue语句

满足某种条件的之后就结束本次的循环进入下次的循环的,可以使用continue语句;

c.return语句

return后面没有任何的值, retuen 表示结束整个方法,return 带上值表示返回数据。

案例演示:

for i in range(0,10):
    print('i 的值为:{}'.format(i))
    if i % 2 ==0:
        break

for i in range(0,10): 
    if i % 2 ==0:
         continue
    print('i 的值为:{}'.format(i))

 

三 容器类型

3.1 字符串

1) 什么是字符串

由一系列字符组成的不可变序列容器,存储的是字符的编码值。

1.不可以变:说明是在内存是按需分配,不会预留空间;

2.序列:表示是按照顺序来存储元素;

3.编码:

  • 字节byte:计算机最小存储单位,等于8 位bit.

  • 字符:单个的数字,文字与符号。

  • 字符集(码表):存储字符与二进制序列的对应关系。

  • 编码:将字符转换为对应的二进制序列的过程。

  • 解码:将二进制序列转换为对应的字符的过程。

4.示意图:  

 

案例演示:

# 演示字符串不可变
name='悟空'
# 2305516036672
# id 函数可以返回的对象真是的内存地址
print(id(name))
name='齐天大圣'
# 2305515421392
print(id(name))

2) 字符串的创建

方式1: ' 文本数据 '

方式2: " 文本数据"

方式3: """ 文本数据""" 可见既所得的特性

方式4: ''' 文本数据'''

其中:''' '''和""" """在功能上可以作为多行注释的功能,在第一行可以被当成文档注释,其本质上不是一个注释,可以会被程序处理,作为文档注释可以被程序提取。

案例演示:

'''
 字面值
 版本:11
 会被程序进行处理,本质上不是注释
'''
name01='悟空'
name02="悟空"
# 可见既所得
# 功能上是注释
name03='''悟


空'''
print(name03)
name04="""悟空"""

3) 字符的编解码

  • 编码方式:

--ASCII编码:包含英文、数字等字符,每个字符1个字节。

--GBK编码:兼容ASCII编码,包含21003个中文;英文1个字节,汉字2个字节。

--Unicode字符集:国际统一编码,旧字符集每个字符2字节,新字符集4字节。

-- UTF-8编码:Unicode的存储与传输方式,英文1字节,中文3字节。

  • 相关函数

    ord(字符串):返回该字符串的Unicode码。

    chr(整数):返回该整数对应的字符串。

案例演示:

# 字-->数
print(ord('a')) # 97
print(ord('A')) #65
# 数--->字
print(chr(97))

'''
练习:录入一个字符串的,打印每一个字符的编码
练习:在终端中重复录入编码值,然后的打印字符串,如果录入的编码值的空字符的,则退出
'''
user_mesage=input('请输入一段字符串:')
for i in user_mesage:
   print('每一个的字符的编码为:{}'.format(ord(i)))



while True:
    user_code = input('录入编码值:')
    if user_code=="":
        break
    else:
        print('每一个编码对应的字符为:{}'.format(chr(int(user_code))))

4) 转义字符及其处理

a.什么是转义字符

改变字符的原始含义。

举例:

\’  \”  \”””  \n  \\  \t  \0 空字符 

具体如图:

 

 

b.处理转义字符的方式

方式1:使用转义字符

方式2:使用r'字符串'保持原始字符串

案例演示:

# 转义符号:改变原始含义 符号
# \" \' \n
message="我是\"齐天大圣\"."
print(message)

url='H:\学习资料\1907WEB\35.PYTHONWEB'
print(url) #H:\学习资料907WEB.PYTHONWEB
url1=r'H:\学习资料\1907WEB\35.PYTHONWEB'
print(url1)
url2='H:\学习资料\\1907WEB\\35.PYTHONWEB'
print(url2) #H:\学习资料\1907WEB\35.PYTHONWEB

 

5) 字符串的格式

a.字符串格式化的定义

生成一定格式的字符串。

b.符串格式化的语法

字符串%(变量)

'字符串'.form(变量,...)

c.字符串的格式化的方式

方式1:使用% 对各种类型的数据进行格式化的输出;

方式2:采用'字符串'.format()进行格式化输出;

其中:第一部分:格式化的字符串中包含一个'%s'的占位符,它会被变量或者表达式的值进行替代的,第二部分采用固定的%作为分隔符,如果是多个变量采用()j进行括起来;

转换说明符:

 

python还提供字符串的格式化之后的对齐和填充值得操作,具体如下:

-:指定左对齐;

+:表示数值总要带着符号(正数带'+',负数带上'-');

0:表示步补充空格,而是填充0的操作;

.:允许的转换之后的字符串指定小数点之后的数字位数,称为精度值

案例演示:

name='孙悟空'
age=80
score=90.2
print('我叫:%s,今年:%d岁,成绩:%.2f'%(name,age,score))
print('我叫:{},今年:{}岁,成绩:{}分'.format(name,age,score))

6) 通用的操作

a. 数学运算符

实现的字符串的拼接和字符串重复的次数

实现拼接的方式:

方式1:str+str

方式2: str str

案例演示:

# + *
# + 两个字符串实现拼接
name01='八戒'
name01+='唐僧'
print('12'"ww"'23') #12ww23

# *
name02 = '唐僧'
name02 *= 3
print(name02) #唐僧唐僧唐僧

b. 比较运算符

目的: 依次比较两个容器之间元素,一旦发现不同,就返回比较的结果

本质:是比较字符对应的编码值的大小

案例演示:

# 比较运算 == != > < >= <=
# 依次比较两个容器之间元素,一旦发现不同
print('孙悟空'>'唐僧') #True

 

c. 成员运算符

定义:判断连续的元素/单个元素是否在序列/对象当中;

代码演示:

# 成员
print('大圣' in '齐天大圣')  #True
print('天大' in '齐天大圣') #True
print('齐大' in '齐天大圣') #False

 

7) 序列相关方法

字符串本质上就是由多个字符组成的,运行程序通过索引来操作字符,可以在使用[]来获取对应的字符;

其中使用切片的方法的时候可以省略起始索引或者结束索引及其间隔,如果省略起始索引默认是从最开始处进行截取,如果是省略结束索引默认是到字符串的结束,省略间隔默认是1;

可以使用正向索引和方向索引,需要注意的是获取数据的方向性;

获取单个元素使用索引,获取序列片段使用切片的方式;

示意图:

 

代码演示:

# 索引操作
message='我是齐天大圣孙悟空'
print(message[2])
print(message[-2])
#print(message[-2000]) #IndexError: string index out of range
# 切片
# 容器名[开始:结束:间隔]
print(message[2:6]) #齐天大圣
print(message[::2])#  我齐大孙空
print(message[2:-3]) #齐天大圣
print(message[2:-3:-1]) # 空
print(message[-100:100]) #我是齐天大圣孙悟空:没有越界得概念

m='爱生活,我爱编程'
print(m[0])
print(m[-1])
print(m[len(m)//2])
print(m[:3])
print(m[-3:])
print(m[::-1])

8) 字符串的方法

a.数值转换成字符串

Python不允许的直接拼接的数值和字符串,所以需要将数值转换为字符串;

可以使用str()和reper函数,其中str是Python提供的内置函数,repr()则是一个函数。

唯一区别:repr以Python表达式的的形式来表示值,带上引号的字符串就是Python的字符串的表达式的形式。

代码演示:

s1='这本书的价格是'
p=99.8
#print(s1+p) #TypeError: can only concatenate str (not "float") to str
print(s1+str(p))
print(s1+repr(p))
#repr以Python表达式的的形式来表示值
print(str('齐天大圣')) #齐天大圣
print(repr('齐天大圣')) #'齐天大圣'

b.长字符串的处理

当程序当中有大段的文本的字符串的,优先使用的长字符串的形式,因为这种的格式可以包含任何的内容,包括''和" ";

代码演示:

m='''
"ok" ,可以使用str()和reper函数,其中str是Python提供的内置函数,repr()则是一个函数。

​       唯一区别:repr以Python表达式的的形式来表示值,带上引号的字符串就是Python的字符串的表达式的形式。

'''

c.字符串和字节串的处理

python3新增加的bytes类型,代表了的字节串的,字节串有 很多字符的组成。字节串以字节的序列来记录的数据的,就需要采用合适的字符集,主要可以保持原始的字节的数据,存储二进制的数据,比如图片,视频等;

创建bytes对象的方式:

方式1:在b'字符串'

方式2:使用bytes()函数

方式3:使用enocode()

代码演示:

b1=b'hell0' # 只能是英文,中文报错
print(b1) #b'hell0'
b2=bytes('孙悟空',encoding='utf-8') # 如果需要中文,需要指定encodeing属性
print(b2) # b'\xe5\xad\x99\xe6\x82\x9f\xe7\xa9\xba'
b3='唐僧'.encode()
print(b3) # b'\xe5\x94\x90\xe5\x83\xa7'

在字符串当中的每一个数据单位的都是字节,也就是8位,其中每4位可以用一个十六进制来进行表示。

 

d.字符串常用的方法

1.判断

isspace()

如果字符串中只包含空白,则返回 True,否则返回 False.

startswith(substr, beg=0,end=len(string))

检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。

endswith(suffix, beg=0, end=len(string))

检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False.

2.查找

find(str, beg=0 end=len(string))

检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1

rfind(str, beg=0,end=len(string))

类似于 find()函数,不过是从右边开始查找.

count(str, beg= 0,end=len(string))

返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数

3.修改

[replace(old, new [, max])](http://www.runoob.com/python3/python3-string-replace.html)

把 将字符串中的 str1 替换成 str2,如果 max 指定,则替换不超过 max 次。

lstrip()

截掉字符串左边的空格或指定字符。

rstrip()

删除字符串字符串末尾的空格.

[strip([chars])](http://www.runoob.com/python3/python3-string-strip.html)

在字符串上执行 lstrip()和 rstrip()

lower()

转换字符串中所有大写字符为小写.

upper()

转换字符串中的小写字母为大写

swapcase()

将字符串中大写转换为小写,小写转换为大写

4.对齐

center(width, fillchar)

返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。

zfill (width)

返回长度为 width 的字符串,原字符串右对齐,前面填充0

[ljust(width[, fillchar])](http://www.runoob.com/python3/python3-string-ljust.html)

返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。

3.2 列表

1) 列表定义

由一系列变量组成的可变序列容器。

2) 基本操作

创建列表方式:

列表名=[]

列表名 = list(可迭代对象)

 

添加元素方式:

列表名.append(元素)

列表.insert(索引,元素)

 

定位元素

索引: 列表[num]

切片:列表[start:e​n​d:interger]

 

遍历列表

正向:

for 变量名 in 列表名:

变量名就是元素

反向:

for 索引名 in range(len(列表名)-1,-1,-1):

列表名[索引名]就是元素

 

删除元素

列表名.remove(元素)

del 列表名[索引或切片]

代码演示:

# 1.创建
list01=[] # 创建空列表
list02=list()

list01=[100,'悟空',True]
# list(可以迭代对象)
list02=list('齐天大圣孙悟空') 
print(list02) #['齐', '天', '大', '圣', '孙']

# 2.添加
# 追加的操作
list01.append('八戒')
# 插入的操作
list01.insert(0,'唐僧')
print(list01)

# 3.修改
# 索引修改-定位单个元素
list01[1]='飒飒'
# 切片修改-修改范围-可以迭代的元素
list01[-2:]=[10,20,100]
print(list01)
list01[1:1]=[1111,1123,222]

# 4.删除
# 根据元素删除
list01.remove(10)
# 根据索引/切片删除
del  list01[0]
del  list01[-2]
print(list01)

# 5.查询
# 索引
print(list02[1])
#切片:在切片的时候不会产生新的而对象,通过切片获取对象会产生新的对象
print(list02[:5])

# 循环
for i in list02:
    print(i)

for i in range(len(list02)):
    print(list02[i])

for i in range(len(list01)-1,-1,-1):
    print(list01[i])

3) 额外操作

数学运算符 +,*

+: 列表只能和列表进行拼接操作,不能和其他类型进行拼接

*:表示列表的了里面的元素重复几次

成员运算符 in

判断元素是否在列表当中

代码演示:

list01=['我','1',True]
list02=[102,0.1,'c']
print(list01+list02) #['我', '1', True, 102, 0.1, 'c']
list01+=list02 #赋值的操作
print(list02*3) #[102, 0.1, 'c', 102, 0.1, 'c', 102, 0.1, 'c']
print('102' in list02) #False

常用的方法

Python在元组和列表的当中提供很多的内置函数的包括len().max(),min(),sum()等

代码演示:

list01=['我','1',True]
list02=[102,0.1,'c']
#print(max(list02)) # 需要都是可以计算的数据类型,
                   #不然会报错误:not supported between instances of 'str' and 'int'
list03=[1,0,2.9,50]
print(max(list03))

4) 序列封包和序列解包

Python还需要提供的序列封包和序列解包这个功能,支持的两种赋值的方式:

程序把多个值赋值给一个变量的时候,Python会自动把多个值封装成元组,称为序列封包。

程序允许把序列(列表/元组)直接赋值给多个变量,此时序列把各个元素的依次赋值给每一个变量(要求序列的元素个数和变量的个数相等),称为序列解包。

代码演示:

# 序列封包
x=10,20,30,40
print(x) #(10, 20, 30, 40)
# 序列解包
x,y=[10,20]
v,b=(10,20)
print(x,y) #10 20
print(v,b) #10 20
# 还允许用 * 代表部分列表
*s,m,e=10,20,30,40,50
print(s) #[10, 20, 30]
s,*m,e=10,20,30,40,50
print(m) #[20, 30, 40]

5) 深拷贝和浅拷贝

浅拷贝:复制过程中,只复制一层变量,不会复制深层变量绑定的对象的复制过程。

深拷贝:复制整个依懒的变量。

代码演示:

list01 = ["无忌","翠山","三丰"]
# 将list01中存储的列表地址,赋值给list02.
list02 = list01
# 修改列表第一个元素
# list01[0] = "张无忌"
# 修改变量list01的引用(指向)
list01 = "张无忌"
print(list02[0])


# ----------------练习------------------------
list01 = [800,900,1000]
list02 = list01
list03 = list01
list01[0] = "八百"
print(list02[0])# "八百"
list03 = "九百"
print(list02)# ["八百",900,1000]

list01 = [800,900,1000]
# 通过切片创建新列表,赋值给变量list02
list02 = list01[:]
list01[0] = "八百"
print(list02[0])#?

list01 = [800,900,1000]
list02 = list01
# 定位第二个元素,然后进行修改.
list01[1:2] = ["a","b"]
print(list02)# [800, 'a', 'b', 1000]


list01 = [100,[200,300]]
list02 = list01
list01[1][0] = 500
print(list02[1][0])# 500

#------------------------

list01 = [100,[200,300]]
# list02 = list01[:]# 浅拷贝
list02 = list01.copy()# 浅拷贝
list01[1][0] = 500
print(list02[1][0])# 500


list01 = [100,200]
list02 = [100,200]
print(list01 == list02)#true 比较的是内容
print(list01 is list02)#false 比较的是地址 id(list01)  == id(list02)


# 准备拷贝工具
import copy

list01 = [100,[200,300]]
# 深拷贝(“划清界限”:拷贝前与拷贝后的对象互不影响)
# 注意:深拷贝可能占用内存过大.
list02 = copy.deepcopy(list01)
list01[1][0] = 500
print(list02[1][0])# 200

示意图:

浅拷贝的示意图:

 

 

深拷贝的示意图:

 

 

6) 其他常用的方法

a.查找

L.index(v [, begin[, end]]) | 返回对应元素的索引下标, begin为开始索引,end为结束索引,当 value 不存在时触发ValueError错误

L.count(x) | 用于统计某个元素在列表中出现的次数

L.pop([index]) | 删除索引对应的元素,如果不加索引,默认删除最后元素,同时返回删除元素的引用关系

b.修改

L.insert(index, obj) | 将某个元素插放到列表中指定的位置

L.extend(lst) | 向列表追加另一个列表

L.remove(x) | 从列表中删除第一次出现在列表中的值

L.clear() | 清空列表,等同于 L[:] = []

L.sort(reverse=False) | 将列表中的元素进行排序,默认顺序按值的小到大的顺序排列

L.reverse() | 列表的反转,用来改变原列表的先后顺序

c.拷贝

L.copy() | 复制此列表(只复制一层,不会复制深层对象)

 

7) 列表VS字符串

1.列表和字符串都是序列,元素之间有先后顺序关系。

2.字符串是不可变的序列,列表是可变的序列。

3.字符串中每个元素只能存储字符,而列表可以存储任意类型。

4.列表和字符串都是可迭代对象。

5.函数:列表和字符串互换

将多个字符串拼接为一个。

result = "连接符".join(列表)

将一个字符串拆分为多个。

列表 = “a-b-c-d”.split(“分隔符”)

 

8) 列表推导式

定义:

使用简易方法,将可迭代对象转换为列表。

语法:

变量 = [表达式 for 变量 in 可迭代对象]

变量 = [表达式 for 变量 in 可迭代对象 if 条件]

说明:

如果if真值表达式的布尔值为False,则可迭代对象生成的数据将被丢弃。

代码演示:

list01=[i for i in range(1,10) if i % 3 == 0 or i % 5 == 0]
print(list01) #[3, 5, 6, 9]
list02=[i ** 3 for i in range(5,10)]
print(list02) #[125, 216, 343, 512, 729]

9) 列表推导式嵌套

语法:

变量 = [表达式 for 变量1 in 可迭代对象1 for 变量2 in可迭代对象2]

传统写法:

result = []
for r in  ["a", "b", "c"]:
    for c in ["A", "B", "C"]:
        result.append(r + c)

推导写法:

result = [r + c for r in list01 for c in list02]

代码演示:

r=[i+y for i in range(1,3) for y in range(1,3)]
print(r) #[2, 3, 3, 4]

3.3 元组

1) 元组定义

由一系列变量组成的不可变序列容器。

不可变是指一但创建,不可以再添加/删除/修改元素

2) 基本操作

创建空元组:

元组名 = ()

元组名 = tuple()

创建非空元组:

元组名 = (20,) 单个元素的元组后面要加上,不然会被当成元组

元组名 = (1, 2, 3)

元组名 = 100,200,300

元组名 = tuple(可迭代对象)

# 1.创建
tuple01=(1,3)
list01=[1,2,3,4]
tuple02=tuple(list01)
print(tuple02)
# 注意:(元素)--->元素
#      (元素,)--->元组
tuple03=(10)
print(type(tuple03))

获取元素

索引:获取单个元素;

切片:获取元组的子元素

代码演示:

print(tuple03[0])
print(tuple03[1])
print(tuple03[:3])

遍历元组:

正向:

for 变量名 in 列表名:

变量名就是元素

反向:

for 索引名 in range(len(列表名)-1,-1,-1):

元祖名[索引名]就是元素

代码演示:

for item in tuple03:
    print(item)

for i in range(len(tuple03)-1,-1,-1):
    print(tuple03[i])

 

3) 元组作用

1.元组与列表都可以存储一系列变量,由于列表会预留内存空间,所以可以增加元素。

2.元组会按需分配内存,所以如果变量数量固定,建议使用元组,因为占用空间更小。

3.列表和元组的区别:

 

 

4.应用:

变量交换的本质就是创建元组:x, y = y, x

格式化字符串的本质就是创建元祖:"姓名:%s, 年龄:%d" % ("tarena", 15)

 

3.4 字典

1) 字典定义

1.由一系列键值对组成的可变散列容器。

2.散列:对键进行哈希运算,确定在内存中的存储位置,每条数据存储无先后顺序。

3. 键必须惟一且不可变(字符串/数字/元组),值没有限制。

4.对应的内存图为:

 

 

解析:

字典是Python提供的一种常用的数据结果,它用在存放具有的映射的关系的数据。

比如:语文:79,数学:80,英语:92,看上去的两个列表之间的元素有一定的关系的,如果单独存放无法记录两个数据之间的关联关系。

为了保存的具有映射的关系的数据,字典就相当于的保存两个组数据及其关系,其中一组是关键数据称为key,另一组是数据是通过可以来访问称为value.

关联图:

 

2) 基本操作

创建字典

字典名 = {键1:值1,键2:值2}

字典名 = dict (可迭代对象)

其中对迭代的对象有要求:

可以 传入多个的列表/元组作为key-value对象,但是每一个列表/元组都会被当成的一个key-value对,因此这些列表/元组只能包括两个元素,在最外面还需要一个列表/元组来包裹这些列表/元组。

代码演示:

# 1.创建
dict01={}
# 可迭代的对象
dict02=dict()
dict01={'悟空':189,'八戒':150,'张无忌':170}
print(dict01)
#dict02=dict('悟空八戒张无忌')
# 其他的迭代对象的(格式)-->字典
dict02=dict([("悟空",180),('八戒',170)])

添加/修改元素:

语法:

字典名[键] = 数据

说明:

键不存在,创建记录。

键存在,修改映射关系。

代码演示:

dict01['张三']=123
dict01['张三']=321

获取元素:

变量 = 字典名[键] # 没有键则错误

代码演示:

print(dict01['悟空'])
#print(dict01['沙砷']) #KeyError: '沙砷'

遍历字典:

for 键名 in 字典名:

字典名[键名]

for 键名,值名 in 字典名.items():

语句

代码演示:

# 获取key
for key in dict01:
    print(key)

# 获取所有值
for value in dict01.values():
    print(value)

# 获取键值对
for item in dict01.items(): # 遍历结果是元组
    print(item)

for k,v in dict01.items(): # 遍历结果是元组
    print(k,v)

删除元素

del 字典名[键]

代码演示:

# 删除
del dict01['张三']

3) 字典推导式

定义:

使用简易方法,将可迭代对象转换为字典。

语法:

{键:值 for 变量 in 可迭代对象}

{键:值 for 变量 in 可迭代对象 if 条件}

代码演示:

print({item:item ** 2for item in range(1,11) if item % 2==0}) #{2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

4) 字典VS 列表

1.都是可变容器。

2.获取元素方式不同,列表用索引,字典用键。

3.字典的插入,删除,修改的速度快于列表。

4.列表的存储是有序的,字典的存储是无序的。

5.总结字典

  • 通过key访问value

  • 通过key 删除key-value对

  • 通过key 添加key-value对

  • 通过key修改key-value对

  • 通过key判断指定的key-value是否存在

     

5) 常用的方法

a.查找

get(key, default=None) 返回指定键的值,如果值不在字典中返回default

setdefault(key, default=None) 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default

popitem() 随机返回并删除字典中的一对键和值(一般删除末尾对)

items() 以列表返回可遍历的(键, 值) 元组数组

keys() 返回一个迭代器,可以使用 list() 来转换为列表

values() 返回一个迭代器,可以使用 list() 来转换为列表

b.修改

update(dict2) 字典记录

clear() 删除字典内所有元素

 

6) 使用字典格式化字符串

因为变量太多了,按照顺序提供的变量的方式不太合适,可以使用在字符串模板当中按照key指定变量,然后通过字典为字符串的模板当中的key设置值

代码演示:

temp='书名是:%(name)s,价格是%(price)0.2f,出版社是:%(publish)s'
book={'name':'python建议','price':89.0,'publish':'电子社'}
print(temp %book) #书名是:python建议,价格是89.00,出版社是:电子社

3.5 集合

1) 集合定义

1.由一系列不重复的不可变类型变量组成的可变散列容器。

2.相当于只有键没有值的字典(键则是集合的数据)。

3.作用:去重和进行数学运算

2) 基本操作

创建空集合:

集合名 = set()

集合名 = set(可迭代对象)

创建具有默认值集合:

集合名 = {1, 2, 3}

集合名 = set(可迭代对象)

添加元素:

集合名.add(元素)

删除元素:

集合名.discard(元素)

代码演示:

s01={1,2,3}
s02={2,3,4}
set02=set('齐天大圣')
print(set02) #{'大', '天', '圣', '齐'}
set02.add('1')
set02.discard('1')

3) 集合运算

运算示意图:

 

交集&:返回共同元素。

s1 = {1, 2, 3}

s2 = {2, 3, 4}

s3 = s1 & s2  # {2, 3}

 

并集:返回不重复元素

s1 = {1, 2, 3}

s2 = {2, 3, 4}

s3 = s1 | s2  # {1, 2, 3, 4}

补集-:返回只属于其中之一的元素

s1 = {1, 2, 3}

s2 = {2, 3, 4}

s1 - s2  # {1} 属于s1但不属于s2

 

补集^:返回不同的的元素

s1 = {1, 2, 3}

s2 = {2, 3, 4}

s3 = s1 ^ s2  # {1, 4}  等同于(s1-s2 | s2-s1)

 

子集<:判断一个集合的所有元素是否完全在另一个集合中

超集>:判断一个集合是否具有另一个集合的所有元素

s1 = {1, 2, 3}

s2 = {2, 3}

s2 < s1  # True

s1 > s2  # True

 

相同或不同== !=:判断集合中的所有元素是否和另一个集合相同。

s1 = {1, 2, 3}

s2 = {3, 2, 1}

s1 == s2  # True

s1 != s2  # False

子集或相同,超集或相同 <= >=

4) 集合推导式

定义:

使用简易方法,将可迭代对象转换为集合。

语法:

{表达式 for 变量 in 可迭代对象}

{表达式 for 变量 in 可迭代对象 if 条件}

代码演示:

print( { i for i in range(1,10) if i % 2==0}) #{8, 2, 4, 6}

5) 固定集合

定义:

不可变的集合。

作用:

固定集合可以作为字典的键,还可以作为集合的值。

基础操作:

创建固定集合:frozenset(可迭代对象)

数学运算:

等同于set

代码演示:

m=frozenset('齐天大圣') # 迭代对象好像只能是字符串,其他数据类型报错误
print(m)

6) 常用方法

update() 给集合添加元素

clear() 移除集合中的所有元素

copy() 拷贝一个集合

pop() 随机移除元素

 

四 函数

4.1 函数的概念

用于封装一个特定的功能,表示一个功能或者行为。

函数是可以重复执行的语句块, 可以重复调用。

函数的解析:

概念解析:

将实现的特定的功能的代码的定义成为一个函数的,每次程序的需要实现的该功能的时候的,只要的调用的执行的该函数就可以的;

函数的可以接收的零个或者多个的参数的,也可以返回零个的或者多个的值,从使用的角度来看,函数就像一个的'黑匣子',程序的将的零个的或者多个参数的传入这个'黑匣子',然后返回的零个或者多个的值。

函数调用的示意图:

 

从定义函数来说,至少要明确的3点:

1.函数需要的几个关键的需要动态的数据,这些的数据的应该被的定义成的函数的参数。

2.函数需要的传出的几个的重要的值的,这些值应该被定义为返回值。

3.函数内部实现的过程。

功能解析:

侧重于完成一个的功能,不需要考虑太多.

案例:完成两个数字相加的的一个函数

代码演示:

# 方案1:
def add():
    one = int(input("请输入第一个整数:"))
    two = int(input("请输入第二个整数:"))
    # 逻辑处理
    return none + two  # 返回结果,退出方法
    


#方案2: 定义两个数字相加的函数
def add(number_one, number_two):
    # 逻辑处理
    return number_one + number_two  # 返回结果,退出方法
  


# 获取数据
one = int(input("请输入第一个整数:"))
two = int(input("请输入第二个整数:"))
re = add(one, two)
# 显示结果
print("结果是:" + str(re))

选择方案1:原因侧重于完成两个数相加,不考虑数据的来源,将需要的数据作为参数的,好处侧重于功能完成两个的相加,减少耦合,提高通用性。

函数的作用:提高代码的可重用性和可维护性(代码层次结构更清晰),需要函数尽量简洁。

4.2 函数的定义

函数语法:

 def 函数名(形式参数):

     函数体

函数定义说明:

def 关键字:全称是define,意为”定义”。

函数名:对函数体中语句的描述,规则与变量名相同。

形式参数:方法定义者要求调用者提供的信息。

函数体:完成该功能的语句。

函数文档说明:

函数的第一行语句建议使用文档字符串描述函数的功能与参数。

代码演示:

def for_replace(row,colums):
    '''
    :param row: int类型,控制行数
    :param colums: int类型,控制列数
    :return: 无返回值
    '''
    for r in range(row):
        for c in range(colums):
          print('*',end=" ")
        print()

for_replace(3,5)
print(for_replace.__doc__)  # 提取说明文档

pychar的函数查看说明:

快捷键:

Ctrl + P 参数信息(在方法中调用参数)

Ctrl + Q 快速查看文档

Ctrl + Alt + M 提取方法

 

4.3 调用的函数

语法:函数名(实际参数)

说明:根据形参传递内容。

代码演示:

def for_replace(row,colums):
    '''
    :param row: int类型,控制行数
    :param colums: int类型,控制列数
    :return: 无返回值
    '''
    for r in range(row):
        for c in range(colums):
          print('*',end=" ")
        print()

for_replace(3,5) # 函数的调用
print(for_replace.__doc__)

4.4 函数返回值

定义:

方法定义者告诉调用者的结果。

语法:

return 数据

说明:

return后没有语句,相当于返回 None。

函数体没有return,相当于返回None。

程序的需要的多个的返回值的,则的可将多个的值的列表之后的之后的返回,

也可以直接的返回的多个值封装的返回值的元组。

Python提供的序列解包的功能,直接的使用的多个变量的接收函数的返回值的多个值。

代码演示:

def fun02():
    print('fun01执行了')
    # return  # 返回 没有数据 默认为None

m=fun02()
print(m)  # None

# 使用的return 返回的None
def fun03():
    print('fun01执行了')
    return  # 返回 没有数据 默认为None
    print('执行完成')  # 返回就结束方法

m1 = fun03()
print(m1) # None

# 多个返回值会返回值的组成元组
def fun04():
    print('fun01执行了')
   # return  [1,2,3,4,5,6]
    return  1,2,3,4,5,6
m2 = fun04()
print(m2) # (1, 2, 3, 4, 5, 6)

# 序列解包的功能
def fun04():
    print('fun01执行了')
    return  1,2
m3,m4 = fun04()
print(m3,m4) #1 2

4.5 函数内存分配

不可变类型参数有:

数值型(整数,浮点数,复数)

布尔值bool

None 空值

字符串str

元组tuple

固定集合frozenset

可变类型参数有:

列表 list

字典 dict

集合 set

传参说明:

不可变类型的数据传参时,函数内部不会改变原数据的值。

可变类型的数据传参时,函数内部可以改变原数据。

 

函数的参数传递机制:

Python中的参数传递机制都是的'值传递'。所谓的'值传递'就是将实际得参数的

副本的(复制品)传入函数,而参数的本身没有任何的影响。

代码演示:

# 将函数代码存入方法区(不执行函数体)
def fun01():
    a = 100

# 开辟栈帧
fun01()
# 栈帧销毁

def fun02(p):
    # 修改fun02栈帧中的变量
    p = 100

a01 = 1
fun02(a01)
print(a01)# 1

内存示意图:

 

代码演示:

def fun03(p1, p2):
    # 修改列表的元素
    p1[0] = "悟空"
    # 修改栈帧中的变量
    p2 = "八戒"

a02 = ["孙悟空"]
a03 = ["猪八戒"]
fun03(a02, a03)
print(a02)
print(a03)

内存示意图:

 

代码演示:

def fun04(p1, p2):
    # 修改列表的元素
    p1[:] = ["悟空"]# 将["悟空"]遍历后,存入p1指向的列表中
    temp = p2[:]# 浅拷贝p2指向的列表
    temp[:] = ["八戒"]# 修改拷贝后的列表元素

a02 = ["孙悟空"]
a03 = ["猪八戒"]
fun04(a02, a03)
print(a02)#['悟空']
print(a03)# ['猪八戒']

内存示意图:

 

案例练习:

# 1. 向函数传递可变类型对象(列表)
# 2. 函数内部修改可变对象
# 3. 函数执行过后,不用通过返回值,也能拿到修改后的结果。
def sort(list_target):
    # 获取需要与后面比较的数据(除去最后一个)list_target[r]
    for r in range(len(list_target)-1):
        # 与后面 list_target[c] 元素进行比较
        for c in range(r+1,len(list_target)):
            if list_target[r] > list_target[c]:
                list_target[r],list_target[c] = list_target[c],list_target[r]

list01 = [13,5,15,6,7]
sort(list01)
print(list01)

4.6 函数的参数

1) 实参传递方式 argument

a. 位置的传参

定义:实参与形参的位置依次对应。

b. 序列传参

定义:实参用*将序列拆解后与形参的位置依次对应。

c.关键字传参

定义:实参根据形参的名字进行对应。

d.字典关键字传参

定义:实参用**将字典拆解后与形参的名字进行对应。

作用:配合形参的缺省参数,可以使调用者随意传参。

 

代码演示:

# 位置参数
fun10(1,2,3)
#fun10(1,2) #TypeError: fun10() missing 1 required positional argument: 'p3'
#fun10(1,2,3,4) #TypeError: fun10() takes 3 positional arguments but 4 were given
# 序列实参:使用*号拆分序列中的元素,在根据的位置和形参对应
list01=[4,5,7]
#fun10(list) #fun10() missing 2 required positional arguments: 'p2' and 'p3'
# 作用:当参数过多的时候,可以通过容器传递信息
dict01={'a':1,'b':2,'c':3}
set01={"a","b","c"}
fun10(*list01)
fun10(* dict01)
# 3 关键字实参:实参根据名称和形参对应
# 作用:代码可读性高
fun10(p2=2,p1=1,p3=3)

# 4  字典实参:使用**号进行彩粉的字典的键值对的,在根据的位置个形参的对应
#    作用:当参数的过多,可以通过容器的来进行传递的信息
dict02={"p1":2,"p2":3,"p2":5}
fun10(**dict02)

2) 形参定义方式 parameter

a.缺省参数

语法:

def 函数名(形参名1=默认实参1, 形参名2=默认实参2, ...):

函数体

说明:

缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数。

缺省参数可以有0个或多个,甚至全部都有缺省参数。

b.位置形参

语法:

def 函数名(形参名1, 形参名2, ...):

函数体

c.星号元组形参

语法:

def 函数名(*元组形参名):

函数体

作用:

收集多余的位置传参。

说明:

一般命名为'args'

形参列表中最多只能有一个

 

d.命名关键字形参

语法:

def 函数名(*, 命名关键字形参1, 命名关键字形参2, ...):

函数体

def 函数名(*args, 命名关键字形参1, 命名关键字形参2, ...): 函数体

作用:

强制实参使用关键字传参

f.双星号字典形参

语法:

def 函数名(**字典形参名):

函数体

作用:

收集多余的关键字传参

说明:

一般命名为'kwargs'

形参列表中最多只能有一个

 

注意点:参数自左至右的顺序

位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参

代码演示:

# 1.默认参数的,实际参数可以不传递
# 必须向左依次存在
def fun01(p1,p2=0,p3=0):
    print(p1)
    print(p2)
    print(p3)
#fun01()

# 关键字实参+默认参数:实参可以随意传递
fun01(p1=100)

# 位置形参:实参必须传递
def fun01(p1,p2,p3):
    print(p1)
    print(p2)
    print(p3)

# 3 形参:星号元组形参:使用星号形参合并成一个元组
# 作用:位置实参数量无限
# 只能有一个 args
def fun03(*p1):
    print(p1)
fun03()
fun03(4,5,6,7,8)
#fun03(p1=(1,3,4,5,)) #fun03() got an unexpected keyword argument 'p1'

# 4.命名关键字的形参:星号元组的形参的后面的参数
# 实参后续必须是关键字实参
def fun04(*p1,a,b=0):
    print(p1)
    print(a)
    print(b)
fun04(30,4,56,56,4,a=1,b=2)

def fun05(*,a,b=0):
    print(a)
    print(b)
fun05(a=1,b=2)

# 5 命名关键字,要求实参的必须是关键字
def fun06(**kwyword):
   print(kwyword)
fun06(a=2,b=3)

 

五 作用域

1) 作用域概述

定义:

作用域:变量起作用的范围。

分类:

Local局部作用域:函数内部。

Enclosing 外部嵌套作用域 :函数嵌套。

Global全局作用域:模块(.py文件)内部。

Builtin内置模块作用域:builtins.py文件。

2) 变量名的查找规则

由内到外:L -> E -> G -> B

在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,最后是内置变量。

3) 局部变量

定义在函数内部的变量(形参也是局部变量)

只能在函数内部使用

调用函数时才被创建,函数结束后自动销毁

4) 全局变量

定义在函数外部,模块内部的变量。

在整个模块(py文件)范围内访问(但函数内不能将其直接赋值)。

5) global 语句

作用:

在函数内部修改全局变量。

在函数内部定义全局变量(全局声明)。

语法:

global 变量1, 变量2, …

说明:

在函数内直接为全局变量赋值,视为创建新的局部变量。

不能先声明局部的变量,再用global声明为全局变量。

6) nonlocal 语句

作用:

在内层函数修改外层嵌套函数内的变量

语法

nonlocal 变量名1,变量名2, ...

说明

在被嵌套的内函数中进行使用

代码演示:

# 全局的变量:在整个文件可以访问
g01=500
def fun01():
    # 局部变量
    a=1;

def fun02():
    # 在局部作用域当中,可以读取全局变量,但是无法修改
   # print(g01)
    # 声明全局变量
    global g01
    g01=600
    # 声明全局变量(创建全局变量)
    global g02
    g02 = 700


# fun02()
# print(g02)
# #g01=500 执行报错

 

六 面向对象

6.1 面向对象概述

a.面向过程 VS 面向对象

1.面向过程

分析出解决问题的步骤,然后逐步实现。

例如:婚礼筹办

-- 发请柬(选照片、措词、制作)

-- 宴席(场地、找厨师、准备桌椅餐具、计划菜品、购买食材)

-- 婚礼仪式(定婚礼仪式流程、请主持人)

公式:程序 = 算法 + 数据结构

优点:所有环节、细节自己掌控。

缺点:考虑所有细节,工作量大。

2.面向对象

找出解决问题的人,然后分配职责。

例如:婚礼筹办

-- 发请柬:找摄影公司(拍照片、制作请柬)

-- 宴席:找酒店(告诉对方标准、数量、挑选菜品)

-- 婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行)

公式:程序 = 对象 + 交互

优点

(1) 思想层面:

-- 可模拟现实情景,更接近于人类思维。

-- 有利于梳理归纳、分析解决问题。

(2) 技术层面:

-- 高复用:对重复的代码进行封装,提高开发效率。

-- 高扩展:增加新的功能,不修改以前的代码。

-- 高维护:代码可读性好,逻辑清晰,结构规整。

缺点:学习曲线陡峭。

 

 

6.2 类和对象

1) 类和对象的概述

在面向的对象的过程当中的有两个的重要的概念:类和对象(也称为实例),其中类是某一批的对象的抽象。

类名要符合一个合法的标识符,在可读性上的来说,类名必须要由一个或者多个有意义的单词连缀而成,每个单词首字母大写,其他字母都是小写的。

Python的类定义的和函数的定义有点类似,都是以为:作为类体开始的,以统一的缩进的部分作为类体。,类的定义需要使用关键字的class定义

注意点:Python是一门动态的语言的,因此它的类的包括的类变量可以动态的增加/删除,在程序的中的任何的地方增加的变量,程序可以通过del语句删除的已有的类的类变量,类当中定义的方法,默认是实例的方法,实例方法的至少定义的一个参数,通常被命名为se'lf.

Python的类的大体上作用:

1.定义变量

2.创建对象

3.派生子类

总结:

类:一个抽象的概念,即生活中的”类别”。

对象:类的具体实例,即归属于某个类别的”个体”。

类是创建对象的”模板”。

-- 数据成员:名词类型的状态。

-- 方法成员:动词类型的行为。

类与类行为不同,对象与对象数据不同。

 

2) 类的语法及其说明

a. 格式

class 类名:

 “””文档说明”””

   def _init_(self,参数列表):

      self.实例变量 = 参数

   方法成员 

b. 说明

-- 类名所有单词首字母大写.

-- init 也叫构造函数,创建对象时被调用,也可以省略。

-- self 变量绑定的是被创建的对象,名称可以随意。

 

代码演示:

class Wife:
    """
        创建老婆类,抽象的概念
    """
    # 1. 数据 -- 变量
    def __init__(self, name, height, weight):
        self.name = name
        self.height = height
        self.weight = weight

    # 2. 行为 -- 方法(函数)
    def play(self):
        print(self.name, "在玩耍")

c.类变量和类方法操作

1.类变量

语法

(1) 定义:在类中,方法外定义变量。

class 类名:

变量名 = 表达式

(2) 调用:类名.变量名

不建议通过对象访问类变量

说明

(1) 存储在类中。

(2) 只有一份,被所有对象共享。

作用:描述所有对象的共有数据。

2.类方法

语法

(1) 定义:

@classmethod

def 方法名称(cls,参数列表):

方法体

(2) 调用:类名.方法名(参数列表)

不建议通过对象访问类方法

说明

(1) 至少有一个形参,第一个形参用于绑定类,一般命名为'cls'

(2) 使用@classmethod修饰的目的是调用类方法时可以隐式传递类。

(3) 类方法中不能访问实例成员,实例方法中可以访问类成员。

作用:操作类变量。

代码演示:

class ICBC:
    """
        工商银行
    """
    # 类变量
    total_money = 1000000

    # 类方法
    @classmethod
    def print_total_money(cls):
        # print("总行的钱:",ICBC.total_money)
        print("总行的钱:",cls.total_money)


    def __init__(self,name,money):
        self.name = name
        # 实例变量
        self.money = money
        # 总行的钱减少
        ICBC.total_money -= money

i01 = ICBC("天坛支行",100000)
i02 = ICBC("陶然亭支行",100000)
print(ICBC.total_money)
# print(i01.total_money)
ICBC.print_total_money()

 

3) 对象操作

a. 对象的概述

创建对象的是通过构造方法进行实现的,可以通过调用的某个类的构造方法的可以创建的类的对象的。

对象的作用:

1.操作对象的实例变量(包括访问实例变量的值,添加实例变量,删除实例变量)

2.调用对象的方法

对象的访问方法/变量的语法:对象.变量/方法(参数)。在这种的方式中,对象的为主调者,用于访问对象的变量/方法。

由于的Python是动态语言,因此的p对象可以动态的增加/删除实例变量

b.创建对象及其内存存储

代码演示:

# 创建对象:类名(参数)
#         构造函数(参数) -->  __init__
w01 = Wife("铁锤",150,150)
w01.play()# 自动传递w01进入方法

实例对象内存示意图

 

 

案例演示:

案例1:

代码部分

class Dog:
    def __init__(self, pet_name = "", breed = "", price=3000):
        self.pet_name = pet_name
        self.breed = breed
        self.price = price

    def shout(self):
        print(self.pet_name, "旺旺叫")

# 2对象 2套数据
d01 = Dog("米咻","拉不拉多")
d02 = Dog("黑米","拉不拉多",3500)
# 1个方法被多个对象共享
d01.shout()
d02.shout()

内存示意图:

 

 

案例2:

代码部分

class Dog:
    def __init__(self, pet_name = "", breed = "", price=3000):
        self.pet_name = pet_name
        self.breed = breed
        self.price = price

    def shout(self):
        print(self.pet_name, "旺旺叫")

# 1.
d01 = Dog("米咻","拉不拉多")
d02 = d01
d01.pet_name = "小黄"
print(d02.pet_name)# ?

# 2.
def fun01(p1):
    p1.price = 2000
fun01(d01)
print(d01.price)
# 3.
list01 = [
    d01,
    d02,
    Dog("小白","萨魔")
]
list02 = list01[:]
list01[2].pet_name = "小志"
print(list02[2].pet_name)

内存示意图

1的示意图

 

2的示意图

 

3的示意图

 

 

c.对象的操作

1.实例变量的操作

语法

(1) 定义:对象.变量名

(2) 调用:对象.变量名

说明

(1) 首次通过对象赋值为创建,再次赋值为修改.

w01 = Wife()

w01.name = “丽丽”

w01.name = “莉莉”

(2) 通常在构造函数(init)中创建。

w01 = Wife(“丽丽”,24)

print(w01.name)

(3) 每个对象存储一份,通过对象地址访问。

 

作用:描述某个对象的数据。

dict:对象的属性,用于存储自身实例变量的字典。

 

2.实例方法的操作

语法

(1) 定义:

def 方法名称(self, 参数列表):

方法体

(2) 调用: 对象地址.实例方法名(参数列表)

不建议通过类名访问实例方法

说明

(1) 至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"。

(2) 无论创建多少对象,方法只有一份,并且被所有对象共享。

作用:表示对象行为。

代码演示

# 全局变量
# name = "铁锤"

# 局部变量
# def fun01():
#     name = "铁锤"

class Wife:
    def __init__(self, name):
        # 创建实例变量 self.name
        self.name = name

    def play(self):
        # 读取实例变量
        print(self.name, "玩耍")


w01 = Wife("铁锤")
# 读取实例变量
print(w01.name)
# 可以通过__dict__操作所有实例变量
# 修改实例变量
w01.name = "锤锤"

# print(w01.__dict__)
# w01.__dict__["name"] = "锤锤"
# print(w01.name)

w01.play()  # 自动将w01传入方法
# Wife.play(w01)# 也可以用类名调用,但是不建议.

"""
# 可以在类外创建实例变量(不建议)
class Wife:
    pass

w01 = Wife()
# 创建实例变量
w01.name = "铁锤"
# 读取实例变量
print(w01.name)
"""

"""
# 可以在类中其他方法内实例变量(不建议)
class Wife:
    def __init__(self):
        self.fun01()

    def fun01(self):
        self.name = "铁锤"
 
w01 = Wife()
print(w01.name)
"""

6.3 面向对象的特征

1) 封装

a.封装的讲解

I . 数据角度讲

定义:

将一些基本数据类型复合成一个自定义类型。

优势:

将数据与对数据的操作相关联。

代码可读性更高(类是对象的模板)。

II .行为角度讲

定义:

类外提供必要的功能,隐藏实现的细节。

优势:

简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。

私有成员:

(1) 作用:无需向类外提供的成员,可以通过私有化进行屏蔽。

(2) 做法:命名使用双下划线开头。

(3) 本质:障眼法,实际也可以访问。

私有成员的名称被修改为:类名__成员名,可以通过dict_属性或dir函数查看。

属性@property

公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方便。

(1) 定义:

@property

def 属性名(self):

return self.__属性名

@属性名.setter

def 属性名(self, value):

self.__属性名= value

(2) 调用:

对象.属性名 = 数据

变量 = 对象.属性名

(3) 说明:

通常两个公开的属性,保护一个私有的变量。

@property 负责读取,@属性名.setter 负责写入

只写:属性名= property(None, 写入方法名)

代码演示:

初始代码:

# 步骤
# 1. 私有化数据  --> 类外无法操作数据
# 2. 定义公开的读取方法 --> 在读取数据时做判定
# 3. 定义公开的写入方法 --> 在写入数据时做判定

class Wife:
    def __init__(self, name="", age=0):
        self.name = name
        # 目的:保护成员不被类外操作
        # 私有化:使用双下划线命名
        # 障眼法:实际是 _类名 + 私有变量名
        #       _Wife__age
        # self.__age = age
        self.set_age(age)

    def get_age(self):
        return self.__age

    def set_age(self,value):
        if 22 <= value <= 65:
            self.__age = value
        else:
            raise Exception("我不要")

w01 = Wife("锤锤",25)
w01.set_age(26)
print(w01.get_age())
# print(w01._Wife__age)
print(w01.__dict__)

使用拦截方法代码:

"""
    封装(保护)数据
        -- 通过property
"""
# 步骤
# 1. 私有化数据  --> 类外无法操作数据
# 2. 定义公开的读取方法 --> 在读取数据时做判定
# 3. 定义公开的写入方法 --> 在写入数据时做判定
# 4. 类变量指向property对象 --> 将对数据的操作转为对方法的操作

class Wife:
    def __init__(self, name="", age=0):
        self.name = name
        # self.set_age(age)
        self.age = age

    def get_age(self):
        return self.__age

    def set_age(self,value):
        if 22 <= value <= 65:
            self.__age = value
        else:
            raise Exception("我不要")

    # 类变量 --> 覆盖实例变量
    # property --> 拦截
    age = property(get_age,set_age)


w01 = Wife("锤锤",25)
# w01.set_age(26)
w01.age = 26
print(w01.age)

使用装饰器方法:

"""
    封装(保护)数据
        -- 通过属性@property
    练习:exercise01.py
"""


# 步骤
# 1. 私有化数据  --> 类外无法操作数据
# 2. 定义公开的读取方法 --> 在读取数据时做判定
# 3. 定义公开的写入方法 --> 在写入数据时做判定
# 4. 使用@property修饰读取方法
#       @xxx.setter修饰写入方法
#             --> 将对数据的操作转为对方法的操作

class Wife:
    def __init__(self, name="", age=0):
        self.name = name
        self.age = age

    @property  # age =  property(get_age,None)
    def age(self):
        return self.__age

    @age.setter  # age.setter(set_age)
    def age(self, value):
        if 22 <= value <= 65:
            self.__age = value
        else:
            raise Exception("我不要")

w01 = Wife("锤锤", 25)
w01.age = 26
print(w01.age)

 

III.设计角度讲

定义:

(1) 分而治之

将一个大的需求分解为许多类,每个类处理一个独立的功能。

(2) 变则疏之

变化的地方独立封装,避免影响其他类。

(3) 高 内 聚

类中各个方法都在完成一项任务(单一职责的类)。

(4) 低 耦 合

类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。

优势:

便于分工,便于复用,可扩展性强

代码演示:

"""
    封装 - 设计角度
        练习:exercise02.py
            exercise03.py

"""

# 需求:老张开车去东北
"""
写法1: 每次去东北,都会创建新车.
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, pos):
        print("去", pos)
        # 新车
        car = Car()
        car.run()

class Car:
    def run(self):
        print("汽车行驶...")

lz01 = Person("老张")
lz01.go_to("东北") 
"""

"""
写法2: 老张开着自己的车,去东北,去北京.
class Person:
    def __init__(self, name=""):
        self.name = name
        self.car = Car()

    def go_to(self, pos):
        print("去", pos)
        self.car.run()

class Car:
    def run(self):
        print("汽车行驶...")

lz01 = Person("老张")
lz01.go_to("东北")
lz01.go_to("北京")
"""

# 写法3:老张去东北的工具,依赖于外部传入.
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self,car, pos):
        print("去", pos)
        car.run()

class Car:
    def run(self):
        print("汽车行驶...")

lz01 = Person("老张")
bm = Car()
lz01.go_to(bm,"东北")

 

2) 继承

b.继承的讲解

I .语法角度讲

继承方法

代码:

class 父类:

  def 父类方法(self):

    方法体

 

class 子类(父类):

  def 子类方法(self):

    方法体

 

儿子 = 子类()

儿子.子类方法()

儿子.父类方法()

 

说明:

子类直接拥有父类的方法.

 

内置函数

isinstance(对象, 类型)

返回指定对象是否是某个类的对象。

issubclass(类型,类型)

返回指定类型是否属于某个类型。

继承数据

代码

class 子类(父类):

 def __init__(self,参数列表):

   super().__init__(参数列表)

   self.自身实例变量 = 参数

说明

子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类实例变量被正常创建。

定义

重用现有类的功能,并在此基础上进行扩展。

说明:子类直接具有父类的成员(共性),还可以扩展新功能。

优点

一种代码复用的方式。

缺点

耦合度高:父类的变化,直接影响子类。

II .设计角度讲

定义

将相关类的共性进行抽象,统一概念,隔离变化。

适用性

多个类在概念上是一致的,且需要进行统一的处理。

相关概念

父类(基类、超类)、子类(派生类)。

父类相对于子类更抽象,范围更宽泛;子类相对于父类更具体,范围更狭小。

单继承:父类只有一个(例如 Java,C#)。

多继承:父类有多个(例如C++,Python)。

Object类:任何类都直接或间接继承自 object 类。

 

多继承

一个子类继承两个或两个以上的基类,父类中的属性和方法同时被子类继承下来。

同名方法的解析顺序(MRO, Method Resolution Order):

类自身 --> 父类继承列表(由左至右)--> 再上层父类

A

/ \

/ \

B C

\ /

\ /

D

3) 多态

 

6.4 设计原则

 

七 PYTHON核心

7.1 程序结构

 

7.2 函数式编程

 

你可能感兴趣的:(python)