注释
python中的注释有两种方法
-
单行注释
# 这是一个单行注释
-
多行注释
''' 这是一个多行注释 这是一个多行注释 '''
""" 这是一个多行注释 这是一个多行注释 """
多行注释使用单引号或多引号
变量
变量的定义
变量用来存储数据,是数据在存储器中的存放位置的名称。
变量的类型
-
数字型
- int(有符号整型)
- long(长整型,也可以代表八进制和十六进制)
- float(浮点型)
- complex(复数)
-
布尔型
- True
- False
-
字符串
-
string
可以+和*
-
-
列表
- list
-
元组
- tuple
-
字典
- dictionary
-
集合
- set
查看变量的类型
-
可以使用IDE环境中的debug功能来查看变量的类型
-
type(变量名)
a = 10 print(type(a))
数据类型转换
通过input()输入的数据都是string类型,此时就需要通过数据类型转换来得到所需要类型的数据。
函数 | 说明 |
---|---|
int(x [,base ]) | 将x转换为一个整数 |
float(x ) | 将x转换为一个浮点数 |
complex(real [,imag ]) | 创建一个复数,real为实部,imag为虚部 |
str(x ) | 将对象 x 转换为字符串 |
repr(x ) | 将对象 x 转换为表达式字符串 |
eval(str ) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s ) | 将序列 s 转换为一个元组 |
list(s ) | 将序列 s 转换为一个列表 |
chr(x ) | 将一个整数转换为一个Unicode字符 |
ord(x ) | 将一个字符转换为它的ASCII整数值 |
hex(x ) | 将一个整数转换为一个十六进制字符串 |
oct(x ) | 将一个整数转换为一个八进制字符串 |
bin(x ) | 将一个整数转换为一个二进制字符串 |
a = int(input('请输入一个数'))
print(type(a)) # <class 'int'>
print(a/2) # input()输入的是字符串型,无法直接计算,所以必须转换为数字型
print(int('23',8)) # 将字符串23设为一个8进制数,并以十进制整数型输出
# 输出结果: 19
# 可以设为任何进制:九进制、十一进制、十八进制之类的都可以
标识符和关键字
标识符的定义
标识符是开发人员在程序中自定义的一些满足某些规则的符号和名称。
标识符的命名规则
标识符由字母、数字和下划线组成,且数字不能开头,不能与关键字相同。
可以定义为python自带的函数,列如input、print,但是这样会使这些函数失去本身的作用。
通常使用的命名方法
-
见名知意
列如:名字就定义为name、学生就定义为student
-
驼峰命名法
-
小驼峰命名法
第一个单词以小写字母开始;第二个单词的首字母大写,例如:myName、aDog
-
大驼峰命名法
每一个单字的首字母都采用大写字母,例如:FirstName、LastName
-
-
下划线命名法
使用下划线“_”来连接所有单词,列如:my_name
给自己定的规则:使用英文命名,定义变量时使用下划线命名法,定义函数时使用驼峰命名法。
关键字的定义
关键字是python已经使用了的、具有某些功能的标识符,所以不允许开发者自己定义和关键字相同名字的标识符。
查看关键字
import keyword
print(keyword.kwlist)
[‘False’, ‘None’, ‘True’, ‘and’, ‘as’, ‘assert’, ‘async’, ‘await’, ‘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’] (不知道全不全)
输入
-
input()
name = input('请输入您的姓名:')
- 通过input()输入的数据都是字符串类型,如果想要变更数据类型,需要进行数据类型转换。
- 回车键(Enter)结束输入
- input()中,单引号和双引号作用相同
输出
-
普通的输出
print(输出的数据)
name = input('请输入您的姓名:') print('您的姓名是:',name)
运行结果:
请输入您的姓名:liuyang 您的姓名是: liuyang
-
格式化输出
print(’%格式‘%变量)
a = 10 b = 1.1 c = 'asdfadsf' print('整型:%d,浮点型:%f,字符串型:%s'%(a,b,c))
运行结果:
整型:10,浮点型:1.100000,字符串型:asdfadsf
- 格式化符号的一些特殊应用,列如:
a = 12 # 假如这是一个学号,需要和其他同学的学号保持整齐
b = 1
c = 108
print('同学a的学号是:%6d\n同学b的学号是:%6d\n同学c的学号是:%6d'%(a,b,c))
# 不足6位数则右侧对齐,超过6位数则原样输出
print('同学a的学号是:%06d\n同学b的学号是:%06d\n同学c的学号是:%06d'%(a,b,c))
# 用0填补不足6位的空位
运行结果:
同学a的学号是: 12
同学b的学号是: 1
同学c的学号是: 108
同学a的学号是:000012
同学b的学号是:000001
同学c的学号是:000108
pi = 3.1415926
print('保留两位小数:%.2f\n保留三位小数:%.3f'%(pi,pi))
运行结果:
保留两位小数:3.14
保留三位小数:3.142
-
常用的格式化符号
如果想输出一个带%的数,需要写成%%格式:
a = 80 print('商品的不合格率是:%d%%'%a) # 商品的不合格率是:80%
使用格式化符号进行输出时,会将部分符合规则的变量强制变换为格式化符号所代表的类型(数字型可以转换为字符型,字符型不可以转换为数字型):
a = 80 print('%f'%a) # 80.000000
格式符号 转换 %s 字符串 %d 有符号十进制整数 %f 浮点数 %c 字符 %u 无符号十进制整数 %o 八进制整数 %x 十六进制整数(小写字母0x) %X 十六进制整数(大写字母0X) %e 科学计数法(小写’e’) %E 科学计数法(大写“E”) %g %f和%e 的简写 %G %f和%E的简写 -
f输出
print(f’{变量}’)
a = 10 b = 1.1 c = 'asdfadsf' d = (1,2) print(f'整型:{a},浮点型:{b},字符串型:{c},元组型:{d}')
运行结果:
整型:10,浮点型:1.1,字符串型:asdfadsf,元组型:(1, 2)
-
一些输出格式
- print()默认输出结束后换行,是print(输出数据,end=’\n’)的简写
- print(输出数据,end=’’)输出后不进行任何操作
- print(输出数据,end=’\n’)输出后换行
- print(输出数据,end=’\t’)输出后间隔一个制表符,也就是与下一项输出直接间隔四个空格
print('*****') print('*****',end='') print('*****') print('*****',end='\n') print('*****') print('*****',end='\t') print('*****')
运行结果:
***** ********** ***** *****
- print(输出数据,end=字符串型数据) 输出结束后再在末尾处加上字符串型数据(不可以使用其他类型数据)
```python
print('*****')
print('*****',end='adsfadsfdasfadsf')
print('*****')
a = 'fadsf'
print('*****',end=a)
print('*****')
运行结果:
*****
*****adsfadsfdasfadsf*****
*****fadsf*****
运算符
算术运算符
下面以a=10,b=20为例进行运算
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 | 两个对象相加 a + b 输出结果 30 |
- | 减 | 得到负数或是一个数减去另一个数 a - b 输出结果 -10 |
* | 乘 | 两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200 |
/ | 除 | b / a 输出结果 2 |
// | 取整除 | 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0 |
% | 取余 | 返回除法的余数 b % a 输出结果 0 |
** | 指数 | a**b 为10的20次方, 输出结果 100000000000000000000 |
注意:混合运算时,优先级顺序为: **高于 * / % // 高于 + - ,为了避免歧义,建议使用 ()来处理运算符优先级。并且,不同类型的数字在进行混合运算时,整数将会转换成浮点数进行运算。
赋值运算符
a = 100 # 为单个变量赋值
b,c,d = 1.1,'adsfad',True # 为多个变量赋不同的值
e,f,g = 5 # 为多个变量赋相同的值
e = a # 将变量a的值赋给变量e,e=100
复合赋值运算符
a = 2
b = 3
c = 4
d = 6
a += 1 # a = a + 1 :a=3
b -= 1 # b = b - 1 :b=2
c *= 1 # c = c * 1 :c=4
d /= 2 # d = d / 2 :d=3
e = 4
e *= 3 + 5 # e = e*(3+5) :e=32
逻辑运算符
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔“与”:如果x为False,x and y 返回False,否则它返回y的值。 | True and False,返回False。 |
or | x or y | 布尔“或”:如果x是True,它返回True,否则它返回y的值。 | False or True,返回True。 |
not | not x | 布尔“非”:如果x为True,返回False。如果x为False,它返回True。 | not True返回False,not False返回True |
比较运算符
运算符 | 描述 | 示例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果是则条件变为真。 | 如a=3,b=3,则(a==b)为True |
!= | 检查两个操作数的值是否相等,如果值不想等,则条件变为真。 | 如a=1,b=3,则(a!=b)为True |
> | 检查左操作数的值是否大于右操作数的值,如果是,则条件成立。 | 如a=7,b=3,则(a>b)为True |
< | 检查左操作数的值是否小于右操作数的值,如果是,则条件成立。 | 如a=7,b=3,则(a<b)为False |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件成立。 | 如a=3,b=3,则(a>=b)为True |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件成立。 | 如a=3,b=3,则(a<=b)为True |
判断语句
if
- 格式
if 判断条件:
条件成立时,要执行的语句
......
# None [] {} '' 这些都和False一样判断为假
-
if语句有严格的格式要求,if中所执行的语句要和if保持一个Tab键的缩进,也就是四个空格。
-
示例:
a = 3 if a > 1: print(a) # 输出:3
if-else
- 格式
if 判断条件:
满足条件时,要执行的语句
......
else:
不满足条件时,要执行的语句
......
-
else语句也遵循一个Tab键的缩进格式
-
示例:
a = 3 if a > 4: print('a比较大') else: print('a比较小') # 输出:a比较小
if-elif
- 格式
if 判断条件1:
满足判断条件1时,要执行的代码
......
elif 判断条件2:
满足判断条件2时,要执行的代码
......
elif 判断条件3:
满足判断条件3时,要执行的代码
......
......
......
-
elif同样要满足一个Tab键的缩进格式
-
也可以和if-elif-else一起使用
-
示例:
grade = int(input('请输入您的考试成绩:')) if grade >= 90: print('非常优秀') elif grade >= 80: print('优秀') elif grade >= 70: print('一般') elif grade >= 60: print('及格') else: print('不及格')
运行结果:
请输入您的考试成绩:77 一般
if嵌套
- 格式:
if 判断条件 1:
满足条件1时,要做的事情
......
if 判断条件2:
满足条件2时,要做的事情
......
if ......
......
- if嵌套可以与elif和else连用,具体情况具体分析
- 示例:
money = 1 # 兜里的钱
seat = 1 # 公交车座位
if money >= 1:
print("您可以上车")
if seat >= 1:
print('车上有座位,您请坐')
else:
print('车上没有座位了,请站稳')
else:
print("您的车票钱不够,不可以上车") # 这里的缩进在博客上被向后推了,不知道为啥。。。(把tab换成空格就好啦)
运行结果:
您可以上车
车上有座位,您请坐
三目运算符
-
变量 = 值1 if 条件 else 值2
满足条件时为变量赋予值1,不满足条件时为变量赋予值2.
-
示例:
a = 3 if 8 < 7 else 2 print(a) # 输出:2
循环语句
循环语句也遵守一个Tab键缩进的格式。
while
- 格式:
while 判断条件:
满足条件时执行的命令
......
# 所有满足条件的命令执行完后,重新返回while条件判定位置进行新一次判定。
-
示例:
# 计算1~100的累加和 i = 1 # 这个用途变量也被称为步长 sum = 0 while i <= 100: # 用来判定循环是否继续 sum += i i += 1 # 更改步长,以进行新一轮的循环判定 print(sum)
运行结果:
5050
for
- 格式:
for 临时变量 in 列表或者字符串等可迭代对象:
循环条件满足时执行的代码
......
# 所有满足条件的命令执行后,重新返回for循环判定位置,临时变量根据可迭代对象变更,进行新一轮的循环判定
# 临时变量中保存的并不是指针或下标
-
示例1:
a = 'akjsdflkad'
for i in a:
print(i)
运行结果:
a
k
j
s
d
f
l
k
a
d
-
示例2:
for i in range(5): #range(结束位置)是生成一个有序的数列,从0开始,到结束位置结束(不包含结束位置) print(i) for j in range(1,5): #range(开始位置,结束位置)是生成一个有序的数列,从开始位置开始,到结束位置结束(不包含结束位置) print(j)
运行结果:
0 1 2 3 4 1 # 第二个print开始输出的位置 2 3 4
-
示例3:
a = [1,'adsf',2,True]
for i in a:
print(i)
运行结果:
1
adsf
2
True
break和continue
break和continue只能在循环中使用。当在嵌套循环中使用时,只对最近一层的循环起作用。
-
break
break会立即终止循环
i = 1 while i <= 5: if i == 3: print('不想刷了') break print('刷了%d个碗了'%i) i += 1
运行结果:
刷了1个碗了 刷了2个碗了 不想刷了
-
continue
continue会结束当次循环
i = 1 while i <= 5: if i == 3: print('不想刷了') i += 1 continue print('刷了%d个碗了'%i) i += 1
运行结果:
刷了1个碗了 刷了2个碗了 不想刷了 刷了4个碗了 刷了5个碗了
循环嵌套
-
while
# 计算100~200之间的素数 i = 100.0 while i <= 200: j = 2.0 while j <= i / 2: if i % j == 0: break j += 1 else: print('%s是素数'%i, end =' ') i += 1
运行结果:
101.0是素数 103.0是素数 107.0是素数 109.0是素数 113.0是素数 127.0是素数 131.0是素数 137.0是素数 139.0是素数 149.0是素数 151.0是素数 157.0是素数 163.0是素数 167.0是素数 173.0是素数 179.0是素数 181.0是素数 191.0是素数 193.0是素数 197.0是素数 199.0是素数
-
for
字符串
双引号和单引号之间的数据就是字符串。
对字符串进行的操作无法直接改变字符串中的数据。
字符串的赋值
a = '23dghj43g@#^'
b = "dsaf32f3AZ#@"
c = ''' ADFJAD97dag*897&* ''' # 三个双引号也可以
d = input('请输入一串字符:') # input()中输入的数据都是字符串
# 也可以通过数据类型转换来给变量赋一个字符串的值
print(a, b, c, d)
print('%s %s %s %s'%(a, b, c, d))
print(f'{a} {b} {c} {d}')
运算结果:
请输入一串字符:dasfdaf
23dghj43g@#^ dsaf32f3AZ#@ ADFJAD97dag*897&* dasfdaf
23dghj43g@#^ dsaf32f3AZ#@ ADFJAD97dag*897&* dasfdaf
23dghj43g@#^ dsaf32f3AZ#@ ADFJAD97dag*897&* dasfdaf
下标
-
字符串实际上就是字符所组成的数组,所以可以用下标来索引其中的字符。
-
列如:
name = 'zhuxing' print(name[0]) # 数组的下标是从0开始的,这里的name[0]对应的就是'z' print(name[3])
运行结果:
z x
字符串的常见操作
-
切片
-
字符串[起始下标:结束下标:步长]
切片包含起始下标所对应的字符,不包含结束下标所对应的字符,步长表示选取间隔。默认起始位为0,默认步长是1,默认结束位为空到底(按步长方向到底)。
-
列如:
name = 'zhuxing' print(name[1:5:1]) print(name[1:5:2])
运行结果:
huxi hx
-
下标和步长都可以是负数,下标为负数表示从字符串的尾部开始计算的下标,步长为负数表示反方向选取。
-
切片的查找方向和选取的方向需要一致。
-
列如:
name = 'zhuxing' print(name[1:5:-1]) print(name[-1:-5:-1])
运行结果:
#无查找结果 gnix
-
可以用于对字符串进行倒叙操作
name = 'zhuxing' print(name[::-1])
运行结果:
gnixuhz
-
-
find
-
用于检测一个字符串中是否存在另一个字符串,如果存在返回所查找的字符串的下标,如果不存在则返回-1。
-
字符串.find(所查找的字符串,开始下标,结束下标)
mystr.find(str,start=0,end=len(mystr))
-
列如:
a = 'dafjkd23akjfhuihf782y5hkjndasfad' print(a.find('23')) #未填写下标时默认在全部字符串中查找 print(a.find('ak',3,10)) print(a.find('ak',12,18))
运行结果:
6 8 -1
-
-
index
-
作用和find相同,如果存在返回所查找的字符串的下标,如果不存在则报错。
-
字符串.index(所查找的字符串,开始下标,结束下标)
mystr.index(str,start=0,end=len(mystr))
-
列如:
a = 'dafjkd23akjfhuihf782y5hkjndasfad' print(a.index('23')) #未填写下标时默认在全部字符串中查找 print(a.index('ak',3,10)) print(a.index('ak',12,18))
运行结果:
6 8 Traceback (most recent call last): File "<input>", line 4, in <module> ValueError: substring not found
-
-
count
-
在字符串中查找另一个字符串出现的次数
-
字符串.(所查找的字符串,开始下标,结束下标)
mystr.count(str,start=0,end=len(mystr))
-
列如:
name = 'zhuxingru' print(name.count('u'))
运行结果:
2
-
-
replace
-
在字符串中的一些字符串替换成另一些字符串,替换次数不超过规定次数
-
字符串.replace(被替换的字符串,替换的字符串,次数)
mystr.replace(str1,str2,count=mystr.count(mystr))
-
列如:
grade = '70,89,59,89,59' print(grade.replace('59','不及格')) print(grade.replace('59','不及格',1))
运行结果:
70,89,不及格,89,不及格 70,89,不及格,89,59
-
-
split
-
在字符串中以某些字符为分隔符,将字符串分割。
-
字符串.split(分割字符,分割次数)
mystr.split(str=’ ‘,count=mystr.count(’ '))
-
列如:
grade = '70,89,59,89,59' print(grade.split(','))
运行结果:
['70', '89', '59', '89', '59']
-
获取被分割字符串中的一部分
grade = '70,89,59,89,59' print(grade.split(',')[2])
运行结果:
59
-
-
join
-
将字符串插入到列表的每个元素之间,生成一个新的字符串
-
新的字符串=字符串.join(列表)
new_mystr=mystr.join(list1)
-
列如:
grade = ['70','89','59','89','59'] myGrade=' '.join(grade) print(myGrade)
运行结果:
70 89 59 89 59
-
字符串的其余操作
-
capitalize
-
若字符串的第一个字符为字母则大写,否则不发生改变
-
mystr.capitalize()
-
列如:
name1 = '4dasf' name2 = 'a4dasf' print(name1.capitalize()) print(name2.capitalize())
运行结果:
4dasf A4dasf
-
-
title
-
把字符串的每个单词的首字母大写
-
mystr.title()
-
列如:
name ='adskf@daskfj adsfkj8adfklj' print(name.title())
运行结果:
Adskf@Daskfj Adsfkj8Adfklj
-
-
startswith
-
检查字符串是否是以某个字符串开头,是则返回True,否则返回False
-
mystr.startswith(str)
-
列如:
name = 'zhuxing' print(name.startswith('zhu'),name.startswith('wang'))
运行结果:
True False
-
-
endswith
-
检查字符串是否是以某个字符串结尾,是则返回True,否则返回False
-
mystr.endswith(str)
-
列如:
name = 'zhuxing' print(name.endswith('xing'),name.endswith('g'),name.endswith('n'))
运行结果:
True True False
-
-
lower
-
将字符串中的所有大写字母转为小写
-
mystr.lower()
-
列如:
str1 = 'dalksfh1234$@^AJKDGJ' print(str1.lower())
运行结果:
dalksfh1234$@^ajkdgj
-
-
upper
-
将字符串中的所有小写字母转为大写
-
mystr.upper()
-
列如:
str1 = 'dalksfh1234$@^AJKDGJ' print(str1.upper())
运行结果:
DALKSFH1234$@^AJKDGJ
-
-
ljust
-
将字符串左对齐,并使用空格填充不满长度width的位置
-
mystr.ljust(width)
-
列如:
name = 'zhu' print(name.ljust(10)+'####')
运行结果:
zhu ####
-
-
rjust
-
将字符串右对齐,并使用空格填充不满长度width的位置
-
mystr.ljust(width)
-
列如:
name = 'zhu' print(name.rjust(10)+'####')
运行结果:
zhu####
-
-
center
-
将字符串居中,并使用空格填充不满长度width的位置
-
mystr.center(width)
-
列如:
name = 'zhu' print(name.center(10)+'####')
运行结果:
zhu ####
-
-
strip
-
删除字符串两端的空白字符
-
mystr.strip()
-
列如:
name = ' zhu ' print(name.strip()+'####')
运行结果:
zhu####
-
-
lstrp
- 删除字符串左端的空白字符
-
rstrp
- 删除字符串右端的空白字符
-
rfind
- 类似find(),不过rfind()是从字符串的右端开始查找。
-
rindex
- 类似index(),不过rindex()是从字符串的右端开始查找。
-
partition
-
将字符串以某个字符串为分隔符分为三个部分:某个字符串前、某个字符串、某个字符串后。
-
my.partition(str)
-
列如:
name = 'zhuxiurui' print(name.partition('u'))
运行结果:
('zh', 'u', 'xiurui')
-
-
rpartition
-
从右侧开始将字符串以某个字符串为分隔符分为三个部分:某个字符串前、某个字符串、某个字符串后。
-
mystr.rpartition(str)
-
列如:
name = 'zhuxiurui' print(name.rpartition('u'))
运行结果:
('zhuxiur', 'u', 'i')
-
-
splitlines
-
将一个被分为多行的字符串组合成一个列表
-
mystr.splitlines()
-
列如:
str1 = 'hello\nworld\ni\nlove\npythonn' print(str1.splitlines())
运行结果:
['hello', 'world', 'i', 'love', 'pythonn']
-
-
isalpha
-
如果字符串中的所有字符都是字母,就返回True,否则返回False
-
mystr.isalpha()
-
列如:
str1 = 'helloworldilovepythonn' print(str1.isalpha()) str2 = 'hello\nworld2i%love\tpythonn' print(str2.isalpha())
运行结果:
True False
-
-
isdigit
- 如果字符串中的所有字符都是数字,就返回True,否则返回False
-
isalnum
- 如果字符串中的所有字符都是字母或数字,就返回True,否则返回False
-
isspace
- 如果字符串中的所有字符都是空格,就返回True,否则返回False2
列表
name_List = [1,‘dafadfa’,True,3.245]
列表就像一个可以存放各种类型数据的数组。
列表的相关操作会直接改变列表中的数据。
name_List = [1,'dafadfa',True,3.245]
print(name_List)
print(name_List[1])
print(name_List[1][1])
运行结果:
[1, 'dafadfa', True, 3.245]
dafadfa
a
列表的相关操作
切片
- list2 = list1[开始位置:结束位置:步长]
增
-
append
-
可以通过append向列表中增加元素
-
List.append[新增元素]
-
列如:
name_List = ['leilei','xiaozhu','humouren','xinlin'] print(name_List) name_List.append('qiliang') print(name_List) new_name = ['jiang'] name_List.append(new_name) print(name_List)
运行结果:
['leilei', 'xiaozhu', 'humouren', 'xinlin'] ['leilei', 'xiaozhu', 'humouren', 'xinlin', 'qiliang'] ['leilei', 'xiaozhu', 'humouren', 'xinlin', 'qiliang', ['jiang']]
-
-
extend
-
extend可以将一个列表中的元素依次加入到另一个列表中
-
List1.extend(List2)
-
列如:
name_List = ['leilei','xiaozhu','humouren','xinlin'] print(name_List) new_name = ['jiang','qilin'] name_List.extend(new_name) print(name_List)
运行结果:
['leilei', 'xiaozhu', 'humouren', 'xinlin'] ['leilei', 'xiaozhu', 'humouren', 'xinlin', 'jiang', 'qilin']
-
-
insert
-
将新增元素插入到列表的指定位置之前。
-
List.insert(指定位置,新增元素)
-
列如:
new_list = ['ads','dfa',4,'324'] new_list.insert(2,'新元素') print(new_list)
运行结果:
['ads', 'dfa', '新元素', 4, '324']
-
删
-
del
-
根据下标进行删除
-
del List[num]
-
列如:
name = ['zhu','jiang','hu'] del name[2] print(name)
运行结果:
['zhu', 'jiang']
-
-
pop
-
删除最后一个元素
-
也可以根据下标进行删除
-
会返回被删除的值
-
List.pop()
-
列如:
name = ['zhang','wang','li','zheng'] name.pop() print(name)
运行结果:
['zhang', 'wang', 'li']
-
-
remove
-
根据元素的值进行删除,当有多个相同元素时只删除第一个。
-
List.remove(item)
-
列如:
name = ['zhang','wang','li','zheng'] name.remove('wang') print(name)
运行结果:
['zhang', 'li', 'zheng']
-
改
-
通过下标进行修改
-
列如:
new_list = ['ads','dfa',4,'324'] new_list[2] ='3' print(new_list)
运行结果:
['ads', 'dfa', '3', '324']
-
查
-
in
-
如果存在所查找的元素就返回True,否则返回False
-
item in List
-
列如:
new_list = ['ads','dfa',4,'324'] a = 'dfa' in new_list print(a)
运行结果:
True
-
-
not in
-
如果不存在所查找的元素就返回True,否则返回False
-
item not in List
-
列如:
new_list = ['ads','dfa',4,'324'] a = 'dfa' not in new_list print(a)
运行结果:
False
-
-
index
- 同字符串中的index
-
count
- 同字符串中的count
排序
-
sort
-
将列表按照特定顺序重新排序,默认由小到大,sort中的参数reverse=True可以将排序后的列表逆置。
-
List.sort()
-
列如:
num_list = [1,2,3,6,4,5,9,2,23,32,1] num_list.sort() print(num_list) num_list.sort(reverse = True) print(num_list)
运行结果:
[1, 1, 2, 2, 3, 4, 5, 6, 9, 23, 32] [32, 23, 9, 6, 5, 4, 3, 2, 2, 1, 1]
-
-
reverse
-
可以将列表逆置
-
List.reverse()
-
列如:
num_list = [1,2,3,6,4,5,9,2,23,32,1] num_list.reverse() print(num_list)
运行结果:
[1, 32, 23, 2, 9, 5, 4, 6, 3, 2, 1]
-
列表嵌套
-
list[[],[],[]]
-
列如:
# 使用列表嵌套,完成8名老师随机分配3个办公室 import random room = [[],[],[]] teacher = [1,2,3,4,5,6,7,8] for i in teacher: j = random.randint(0,2) room[j].append(i) print(room)
运行结果:
[[1, 8], [3, 4], [2, 5, 6, 7]] # 这个结果为随机结果
集合
-
set是集合类型
-
set、list、tuple之间可以相互转换
-
set可以快速的对字符串、列表进行去重操作,并将列表转换成集合
a = 'helloworld' print(set(a)) b = 'helloworld' c = list(b) print(set(c))
运行结果:
{'r', 'w', 'd', 'o', 'e', 'l', 'h'} {'r', 'w', 'd', 'o', 'e', 'l', 'h'}
元组
- 元组与列表类似,不过元组不能被修改,只能查询。
- 查询
- index
- count
- 切片
- a=tuple[开始位置:结束位置:步长]
字典
字典的作用与组成
- 字典和列表类似,都可以存储多个不同类型的数据。
- 字典中的数据都以键值对的形式存放,键:值。
- 字典主要用于存放关联性强的一些数据。
- dict = {‘姓名’:‘朱’,‘电话’:‘182’,‘住址’:‘安居’}
字典的常见操作
查看元素
-
通过键来查看元素
-
dict[键]
-
列如:
name_dict = {'username':'zhu','password':'123'} print(name_dict['username']) print(name_dict['age'])
运行结果:
zhu # 有这个键,就正常输出对应的值 Traceback (most recent call last): File "<input>", line 3, in <module> KeyError: 'age' #没这个键,就报错
-
-
get
-
dict.get(值)
-
列如:
name_dict = {'username':'zhu','password':'123'} print(name_dict.get('username')) print(name_dict.get('age')) print(name_dict.get('age',0)) # !!!!
-
运行结果:
```python
zhu # 有这个键,就正常输出对应的值
None # 没这个键,就返回None
0 # 没有这个键,就返回0
修改元素
-
通过对字典的键进行赋值来修改其对应的值
-
dict[键] = 新值
-
列如:
name_dict = {'username':'zhu','password':'123'} print(name_dict['username']) name_dict['username'] = 'jiang' print(name_dict['username'])
运行结果:
zhu jiang
-
添加元素
-
对字典中的键赋值时,如果存在就赋新值,如果不存在就新建一个键
-
dict[新键] = 值
-
列如:
name_dict = {'username':'zhu','password':'123'} print(name_dict) name_dict['address'] = 'anju' print(name_dict)
运行结果:
{'username': 'zhu', 'password': '123'} {'username': 'zhu', 'password': '123', 'address': 'anju'}
-
删除元素
-
del
-
删除指定键值
-
删除整个字典
-
列如:
name_dict = {'username':'zhu','password':'123','address':'anju'} print(name_dict) del name_dict['address'] print(name_dict) del name_dict print(name_dict)
运行结果:
{'username': 'zhu', 'password': '123', 'address': 'anju'} {'username': 'zhu', 'password': '123'} Traceback (most recent call last): File "<input>", line 6, in <module> NameError: name 'name_dict' is not defined # 内存中查找不到字典,说明字典已经被删除
-
-
clear
-
清空字典
-
dict.clear()
-
列如:
name_dict = {'username':'zhu','password':'123','address':'anju'} print(name_dict) name_dict.clear() print(name_dict)
运行结果:
{'username': 'zhu', 'password': '123', 'address': 'anju'} {} # 空字典
-
对字典中键值的调用
-
keys
-
dict.keys()
-
返回一个包含字典所有键的列表
-
列如:
name_dict = {'username':'zhu','password':'123','address':'anju'} print(name_dict.keys())
运行结果:
dict_keys(['username', 'password', 'address'])
-
-
values
-
dict.values()
-
返回一个包含字典所有值的列表
-
列如:
name_dict = {'username':'zhu','password':'123','address':'anju'} print(name_dict.values())
运行结果:
dict_values(['zhu', '123', 'anju'])
-
-
items
-
dict.items()
-
返回一个包含字典所有键值对的列表
-
列如:
name_dict = {'username':'zhu','password':'123','address':'anju'} print(name_dict.items())
运行结果:
dict_items([('username', 'zhu'), ('password', '123'), ('address', 'anju')])
-
遍历字典
-
遍历字典的键
name_dict = {'username':'zhu','password':'123','address':'anju'} for i in name_dict.keys(): print(i)
运行结果:
username password address
-
遍历字典的值
name_dict = {'username':'zhu','password':'123','address':'anju'} for i in name_dict.values(): print(i)
运行结果:
zhu 123 anju
-
遍历字典的键值对
name_dict = {'username':'zhu','password':'123','address':'anju'} for i in name_dict.items(): print(i)
运行结果:
('username', 'zhu') ('password', '123') ('address', 'anju')
-
遍历字典的每一项
name_dict = {'username':'zhu','password':'123','address':'anju'} for i,j in name_dict.items(): print(i) print(j)
运行结果:
username zhu password 123 address anju
有序字典
- Python3.6以上字典都是有序字典
- 3.6以下需要代码创建:my_dict = OrderedDict()
公共方法
序号 | 方法 | 描述 |
---|---|---|
1 | len(item) | 计算容器中元素个数 |
2 | max(item) | 返回容器中元素最大值 |
3 | min(item) | 返回容器中元素最小值 |
4 | del(item) | 删除变量 |
运算符 | Python 表达式 | 结果 | 描述 | 支持的数据类型 |
---|---|---|---|---|
+ | [1, 2] + [3, 4] | [1, 2, 3, 4] | 合并 | 字符串、列表、元组 |
* | [‘Hi!’] * 4 | [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] | 复制 | 字符串、列表、元组 |
in | 3 in (1, 2, 3) | True | 元素是否存在 | 字符串、列表、元组、字典 |
not in | 4 not in (1, 2, 3) | True | 元素是否不存在 | 字符串、列表、元组、字 |
可变与不可变类型
-
数字 不可变
-
字符串 不可变
-
列表 可变
-
元组 不可变
-
字典 可变
-
集合 可变
-
可不可变就是看地址有没有发生变化
-
“=” 一定会生成新的地址
-
“+=” 如果是可变类型,那么地址不会发生变化,如果是不可变类型则会生成新的地址
print('数字:') int_a = 1 print(id(int_a)) # id()查看变量地址 int_a = 2 print(id(int_a)) int_a += 1 print(id(int_a)) print('字符串:') str_a = 'abc' print(id(str_a)) str_a = 'def' print(id(str_a)) str_a += 'ghi' print(id(str_a)) print('列表:') list_a = [1,2,3] print(id(list_a)) list_a = [4,5,6] print(id(list_a)) list_a += [7,8,9] print(id(list_a)) print('元组:') tuple_a = (1,2,3) print(id(tuple_a)) tuple_a = (4,5,6) print(id(tuple_a)) tuple_a += (7,8,9) print(id(tuple_a)) print('字典:') dict_a = {'name':'zhu'} print(id(dict_a)) dict_a = {'age':'18'} print(id(dict_a)) dict_a['address'] = 'anju' print(id(dict_a))
运行结果:
数字: 140722036184736 140722036184768 140722036184800 字符串: 1436332717232 1436362637936 1436362639856 列表: 1436361823168 1436362513728 1436362513728 元组: 1436362533504 1436361834240 1436332756224 字典: 1436332732096 1436332732160 1436332732160
函数
函数的定义
函数就是把具有一定功能的一组代码封装在一起,通过参数的传递来实现功能。
函数的格式
def 函数名():
代码
调用函数
被调用的函数必须已经创建,也就是说函数必须在被调用之前就已经创建。
一个函数里可以调用另一个函数,这就是函数嵌套。
# 函数名(参数)
def sum1 (a,b):
print(a+b)
sum1(1,2)
# 输出:3
print(sum1)
# 输出:<function sum1 at 0x000001955271C3A0>
# 当直接使用函数名,没有后面的()跟随时,输出函数在内存中的地址
sum2 = sum1 # 将函数名sum1所对应的函数地址传递给sum2
sum2(3,4)
# 输出:7 说明sum2完美的引用了sum1的函数
添加说明文档
在函数中添加一段说明性文字,使函数外部可以使用help(函数名)命令获取此函数的说明文档。
def sum1 (a,b):
"用来相加"
print(a+b)
help(sum1)
运行结果:
Help on function sum1 in module __main__:
sum1(a, b)
用来相加
函数的参数
-
Python中函数参数是引用传递(注意不是值传递)
-
对于不可变类型,因变量不能修改,所以运算不会影响到变量自身
-
而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量
-
如果没有缺省参数那么实参和形参的数量需要一致
-
传参数要么顺序一致(位置参数),要么名字一致(关键字参数)
def test1(a,b): print('test1:a=%d,b=%d'%(a,b)) def test2(a,b): print('test2:a=%d,b=%d' % (a, b)) test1(1,2) test2(b=2,a=1)
带有参数的函数
参数用于将函数外部的数据传递到函数内部。定义函数时的参数是形参,调用函数时的参数是实参。
-
定义带有参数的函数
def sum1(a,b) print(a + b)
-
调用带有参数的函数
def sum1(a,b) print(a + b) sum1(1,2)
缺省参数
如果调用函数时没有填写实参,那么可以使用定义函数时给形参赋的值,这个值就是缺省默认值,缺省参数默认放在最后。
def Idcard(name,age = 23): #没有对应age的实参传递数据,所以此时age使用缺省参数23
print('name=%s'%name)
print('age=%d'%age)
Idcard(name = 'zhu')
运行结果:
name=zhu
age=23
不定长参数
-
def functionname(*args,**kwargs)
-
*args用于存储未命名参数,**kwargs用于存储命名参数。
-
*和**才是本体,后面的args和kwargs可以为任意名。
-
*args相当于一个元组,不断接收未命名参数。**相当于一个字典,不断接收命名参数。
-
当形参是不定长参数,实参可以为空,形参相当于一个空元组或字典。
-
列如:
def fun1(*args): #*后的args可以为任意变量名,比如*a for i in args: print(i) print(args) def fun2(**kwargs): #**后的kwargs可以为任意变量名,比如**b for i,j in kwargs.items(): print(i) print(j) print(kwargs) fun1(1,2,3,4,5,6) fun2(a=1,b=2,c='3')
运行结果:
1 2 3 4 5 6 (1, 2, 3, 4, 5, 6) a 1 b 2 c 3 {'a': 1, 'b': 2, 'c': '3'}
缺省参数与不定长参数连用
- 如果很多个值都是不定长参数,那么这种情况下,最好将缺省参数放到 *args的的前面, 但如果有**kwargs的话,**kwargs必须是最后的
函数的返回值
返回值就是函数最后给调用者的一个结果
-
return 返回值
-
函数通过这种方法将值返回给调用者
-
如果函数中有多个return,那么函数会在执行到第一个return语句时结束,其余return无意义。
-
列如:
def name() return 'zhu' def nameMore() a = 'jiang' b = 'zhang' c = 'wang' return a,b,c name_me = name() print(name_me) name_1,name_2,name_3 = nameMore() print(name_1,name_2,name_3)
运行结果:
zhu jiang zhang wang
-
-
无返回值或return后不接任何返回值
-
会返回一个None
-
列如:
def _1(): pass def _2(): return a = _1() b = _2() print(a) print(b)
运行结果:
None None
-
局部变量
-
局部变量就是在函数中定义,仅可以在函数中生效的变量。
-
不同的函数可以定义相同变量名的局部变量。
-
仅当w函数被调用时,函数中的局部变量才会被创建。当函数调用结束时,局部变量就会被干掉。
def aA(): a = 10 print(a) aA() print(a)
运行结果:
10 # 这是函数中的输出 Traceback (most recent call last): File "<input>", line 5, in <module> NameError: name 'a' is not defined # 在函数外部调用局部变量时会报错,表示该变量未被定义
全局变量
-
在函数外边定义的变量就是全局变量,全局变量可以在所有的函数中使用。
-
全局变量需要在调用函数前声明。
-
当局部变量和全局变量重名时,函数会使用自己的局部变量
a = 10 def aA(): a = 20 print(a) aA()
运行结果:
20
-
在函数中修改或创建全局变量
-
global 全局变量名
a = 100 def test1(): global a #声明修改全局变量 print('test1修改前a=%d'%a) a = 200 #如果未使用global a声明对全局变量a进行修改,这里就是创建局部变量a=200 print('test1修改后a=%d'%a) def test2(): print('test2a=%d'%a) test1() test2()
运行结果:
test1修改前a=100 test1修改后a=200 test2a=200
-
拆包
- 函数如果只有一个返回值,则默认其返回值类型是其本身
- 函数如果有多个返回值,则默认其返回值类型是元组
- 当一个函数有多个返回值,调用此函数时通过多个变量来接收这些数值就是拆包。
- 元组,列表,字典都可以被拆包
def aa():
a = 1
b = 2
c = '3'
return a,b,c
tuple_a = aa()
unpack_a,unpack_b,unpack_c = aa()
print(tuple_a)
print(type(tuple_a))
print(unpack_a,unpack_b,unpack_c)
print(type(unpack_a),type(unpack_b),type(unpack_c))
运行结果:
(1, 2, '3')
<class 'tuple'>
1 2 3
<class 'int'> <class 'int'> <class 'str'>
匿名函数
-
用lambda关键字能创建匿名函数
-
lambda 参数列表:expression
-
列如:
a = lambda n1,n2 : n1 + n2 b = a(1,2) print(b)
运行结果:
3
-
-
lambda函数能接收任何数量的参数但只能返回一个表达式的值
列表推导式
列表推导式就是循环创建多元素列表(集合)的方法
-
list = [ 临时变量 for 临时变量 in 可迭代序列]
-
列表推导式中的临时变量是一个局部变量,在列表推导式外部无效。
-
列如:
a = [x for x in range(10)] print(a) str1 = 'ajkdsfhkj' b = [y for y in str1] print(b)
运行结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ['a', 'j', 'k', 'd', 's', 'f', 'h', 'k', 'j']
-
在列表推导式中使用if条件判断
a = [x for x in range(10) if x % 2 == 0] print(a)
运行结果:
[0, 2, 4, 6, 8]
-
多循环列表推导式
- 多循环需要多个对应的临时变量,否则结果会出错。
a = [(x,y) for x in range(5) for y in range(5)] print(a) b =[(x,y,z) for x in range(3) for y in range (3) for z in range(3)] print(b)
运行结果:
[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)] [(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 2, 0), (0, 2, 1), (0, 2, 2), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 2, 0), (1, 2, 1), (1, 2, 2), (2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 0), (2, 1, 1), (2, 1, 2), (2, 2, 0), (2, 2, 1), (2, 2, 2)]
交换
-
python特有交换
a = 1 b = 2 a, b = b, a print('a=%d'%a) print('b=%d'%b)
运行结果:
a=2 b=1
-
通用交换
a = 1 b = 2 temp = a a = b b = temp print('a=%d'%a) print('b=%d'%b)
运行结果:
a=2 b=1
递归
递归就是函数通过循环调用自身来完成某些计算
-
通过递归计算阶乘
def test1(a): if a == 1: return a else: return a*test1(a - 1) b = test1(4) print(b)
运行结果:
24
-
使用递归的函数必须有结束函数运行的地方
-
递归调用层数过多时会使内存崩溃
文件
文件的打开和关闭
-
open
-
变量 = open(文件名,操作类型)
-
以写入类型打开文件,如果存在就打开文件并清空文件
-
以写入类型打开文件,如果不存在就创建文件
f = open('test.txt','w') # 以写入的方式打开test.txt,如果这个文件不存在那么就创建这个文件 #文件名可以带有路径 列如:f = open('D:\\pythonproject\\test.txt','w'),就是打开D盘下prythonproject文件夹中的test文件,如果不存在则创建
-
-
close
-
指向文件的变量.close()
f.close() # 文件被关闭
-
使用之后关闭文件是个好习惯
-
-
自动打开关闭文件
-
with open (文件名,操作类型) as 变量:
-
打开文件并在使用完之后自动关闭
with open ('test.txt','w') as f: # 打开文件 f.write('happy') #使用结束自动关闭
-
文件的读写
-
向文件写入数据
-
指向文件的变量.write(写入内容)
f = open('D:\\test1.txt','w',encoding ='utf -8') # 需要在打开文件时将操作类型设为写入('w') # encoding 编码格式,用什么编码格式写,就用什么编码格式读,工作格式使用utf-8 f.write('hello world\niamaboy') f.close()
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v644z2ja-1586761261437)(https://github.com/IthinkIcandoit/IthinkIcandoit.github.io/blob/master/images/setupfile.jpg )]
-
向文件追加数据
-
将操作类型改为‘a’
f = open('D:\\test1.txt','r') # 追加操作类型 ‘a’ f.write('\nhappy') f.close()
-
-
从文件中读取数据
-
接收数据的变量=指向文件的变量.read(读取数据的数量)
f = open('D:\\test1.txt','r')# 需要在打开文件时将操作类型设为读取('r') a = f.read(5) b = f.read() # read()中无参数时默认读取所有未读取的数据 print(a) print(b) f.close()
运行结果:
hello # 第一个read(5)读取的5个数据 world # 第二个read()读取的剩下的数据 iamaboy # 第二个read()读取的剩下的数据
-
大文件读取
# 文件过大时需要一段一段的读取 f = open('D:\\test1.txt','r') white True: a = f.read(1024) print(a) if not a: # 当读取为空时结束读取 break f.close()
-
-
以行的方式读取所有数据
-
接收数据的变量=指向文件的变量.readlines()
-
这种方式读取会将数据以列表的方式返回,列表中的每一个元素就是文件中的每一行。
f = open('D:\\test1.txt','r')# 需要在打开文件时将操作类型设为读取('r') a = f.readlines() print(type(a)) print(a) f.close()
运行结果:
<class 'list'> ['hello world\n', 'iamaboy']
-
-
读取一行数据
-
接收数据的变量=指向文8件的变量.readline()
-
返回的值时字符串类型
f = open('D:\\test1.txt','r')# 需要在打开文件时将操作类型设为读取('r') a = f.readline() # 读取一行数据 print(type(a)) print(a) b = f.readline() # 读取下一行数据 print(type(b)) print(b) f.close()
运行结果:
<class 'str'> hello world <class 'str'> iamaboy
-
备份文件
# 输入想要备份的文件名
# 提取文件的后缀
# 创建备份文件 文件名+备份+后缀
# 将原文件中的数据导入到备份文件
old_file = input('请输入想要备份的文件名:')
file_flag_num = old_file.rfind('.')
file_flag = old_file[file_flag_num::]
new_file = old_file[:file_flag_num:]+'备份'+file_flag # 确定备份文件名
f = open(new_file,'wb') #创建备份文件
# 'wb'以二进制写
g = open(old_file,'rb') #打开想要备份的文件
# 'rb'以二进制读
for i in g.readlines(): #将旧文件中的数据按行写入到新文件中
f.write(i)
f.close()
g.close()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pnsttUHP-1586761261438)(https://github.com/IthinkIcandoit/IthinkIcandoit.github.io/blob/master/images/copyfile.jpg?raw=true)]
文件重命名
-
os.rename(旧文件名,新文件名)
import os f = open('t.txt','w') f.write('abc') f.write('\ndef') f.close() os.rename('t.txt','tx.txt')
删除文件
-
os.remove(待删除文件名)
import os os.remove('ttt.txt')
创建文件夹
-
os.mkdir(待创建文件夹名)
import os os.mkdir('朱')
删除文件夹
-
os.rmdir(待删除文件夹名)
import os os.rmdir('朱')
获取当前目录
-
接收变量=os.getcwd()
import os a=os.getcwd() #返回的是一个字符串 print(a)
运行结果:
D:\pythonproject\projectname
-
用于获取当前文件所在的文件夹路径
改变默认目录
-
os.chdir(目录)
import os os.chdir('D:\\') #chdir可以将当前的默认目录更改,通常配合其他命令在别的目录进行创建删除之类的操作 os.mkdir('t1') # 列如这两个命令配合就可以在D盘下新键一个文件夹t1
获取目录列表
-
接收变量=os.listdir(目录)
import os a = os.listdir('D:\\pythonproject') #返回的是一个列表 print(type(a)) print(a)
运行结果:
<class 'list'> ['demo01', 'lianyilian', 'untitled', 'projectname']
切割文件名
-
接收变量=os.path.splitext(文件)
-
将文件切割为文件名和后缀两个部分,返回元组形式的值。
import os a=os.path.splitext('ppp.py') print(a)
运行结果:
('ppp', '.py')
面向对象
面向对象的三大特征:继承,封装,多态
类和对象
-
类是一些属性(变量)和方法(行为)的抽象集合,对象是这些属性和方法的具体应用。比如说手机是一个类,小米手机、华为手机、苹果手机就是对象。
-
定义类
class 类名(): 方法列表
class Hero(object): # object用于表示这个类是一个最顶级父类 def info(self): # self用于表示对象自身 print('英雄何必问出处') print(self) print(id(self)) gangtiexia = Hero() # 用类Hero创建对象gangtiexia gangtiexia.info() #调用对象中的实例方法 print(gangtiexia) print(id(gangtiexia))
运行结果:
英雄何必问出处 <__main__.Hero object at 0x0000029BC46D7430> # self的十六进制地址 2868038693936 # self的二进制地址 <__main__.Hero object at 0x0000029BC46D7430> # 对象gangtiexia的十六进制地址 2868038693936 #对象gangtiexia的二进制地址
运行结果中的四个地址一致表示self代表的就是对象本身,同一个类所创建的不同对象的内存地址不同。
添加和获取对象的属性
-
可以在类外面通过:对象.属性=值 的方式添加属性,通过对象.属性 的方式之间调用。
class Phone(): def screen(self): print('%s手机的屏幕是全面屏,类中调用'%self.name) # 在类中的方法里调用对象的属性需要用self.属性 的格式,这里的self代表的就是对象自身 xiaomi = Phone() xiaomi.name = 'xiaomi' print("%s真好,类外调用"%xiaomi.name) # 类外调用对象的属性时,直接用对象名.属性 就可以 xiaomi.screen()
运行结果:
xiaomi真好 xiaomi手机的屏幕是全面屏
魔法方法
-
_init_()
-
_init_()方法可以手动创建,也可以在类建立的时候自动被创建。
-
_init_()方法会在类实例化对象的时候被自动调用,适合用来做变量(属性)的初始化或赋值操作。
-
也就是说无论__init__()方法是否被调用过,此方法中的属性都可以被直接调用。
class Phone(object): a = '智能手机' # 类属性,在类里的方法中调用此变量时需要加self def __init__(self): self.name = '小米手机' #实例属性 def Redmi(self): self.rename ='红米手机' my_phone = Phone() print(my_phone.name) # 有效输出,因为方法__init__()方法在类实例化时就被自动调用 print(my_phone.rename) # 报错,因为Redmi()方法还未被调用,所以属性rename还未被初始化
运行结果:
小米手机 Traceback (most recent call last): File "<input>", line 8, in <module> AttributeError: 'Phone' object has no attribute 'rename'
-
有参数的__init__()方法
-
_init_()方法可以用来接收参数,不过形参的第一个必须是self(代表对象自身),其后的形参才和所接收的实参一一对应
class People(object): def __init__(self,name,age,high,weight): self.name = name self.age = age self.high = high self.weight = weight zhu_xing = People('zhuxin','21','1.80','140') jiang_guang = People('jiangguang','20','1.90','150') print(zhu_xing.name) print(zhu_xing.age) print(zhu_xing.high) print(zhu_xing.weight) print() print(jiang_guang.name) print(jiang_guang.age) print(jiang_guang.high) print(jiang_guang.weight)
运行结果:
zhuxin 21 1.80 140 jiangguang 20 1.90 150
-
-
-
_str_()
-
_str_()方法用于显示信息,该方法只有一个参数self,并且需要return一个数据,这个数据只能是字符串!!!!!
-
当没有__str__()方法时,print(对象名)输出该对象在内存中的地址。有此方法时print(对象名)则打印该方法return中的数据
class People(object): def __init__(self,name,age,high,weight): self.name = name self.age = age self.high = high self.weight = weight def __str__(self): return '人名:%s,年龄:%s,身高:%s,体重:%s'%(self.name,self.age,self.high,self.weight) zhu_xing = People('zhuxin','21','1.80','140') jiang_guang = People('jiangguang','20','1.90','150') print(zhu_xing) print(jiang_guang)
运行结果:
人名:zhuxin,年龄:21,身高:1.80,体重:140 人名:jiangguang,年龄:20,身高:1.90,体重:150
-
-
_del_()
-
删除对象时,会自动调用__del__()方法,可以在此方法中添加一些输出,用来说明该对象已经被删除。
-
如果有多个对象都指向同一个同一个对象,则它们所指向的内存地址都相同。所以当删除对象时,只有将它们全部删除才算是删除干净,也只有在彻底删除干净时才会调用__del__()方法。
class People(object): def __del__(self): print('%s的信息被彻底删除'%self.name) zhu = People() zhu.name = 'zhu' xiaozhu = zhu zhuzhu = zhu print("第一次删除") del zhu print("第二次删除") del xiaozhu print("第三次删除") del zhuzhu
运行结果:
第一次删除 第二次删除 第三次删除 zhu的信息被彻底删除
-
继承
-
当A类中的方法和属性会被多次复用时,就可以使B类继承A类。A类称为父类,B类称为子类。
-
在建立类时的小括号()中写入父类的名字,就建立了一个继承父类的子类。
-
子类继承父类的方法和属性
-
可以多层继承
class A(object): def aaa(self): print('这是父类定义的方法') class B(A): pass obj = B() obj.aaa()
运行结果:
这是父类定义的方法
多继承
-
一个子类可以继承多个父类的属性和方法
-
当多个父类中的属性或方法重名时,则按照定义子类时继承父类的顺序,使用第一个父类的方法和属性。
class A(object): def aaa(self): print('这是父类A定义的方法') class B(object): def aaa(self): print('这是父类B定义的方法') class C(A,B): pass obj = C() obj.aaa()
运行结果:
这是父类A定义的方法
通过__mro__查看继承关系
-
通过子类的魔法方法__mro__查看子类的继承关系
class A(object): def aaa(self): print('这是父类A定义的方法') class B(object): def aaa(self): print('这是父类B定义的方法') class C(A,B): pass print(C.__mro__)
运行结果:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
子类重写父类的同名属性和方法
-
当子类的方法和属性与父类的方法和属性重名时,会优先使用子类的方法和属性,这就是重写。
class A(object): def aaa(self): print('这是父类A定义的方法') class B(object): def aaa(self): print('这是父类B定义的方法') class C(A,B): def aaa(self): print('这是子类重写的方法') obj = C() obj.aaa()
运行结果:
这是子类重写的方法
-
子类可以通过方法调用父类的同名方法和属性
class A(object): def aaa(self): print('这是父类A定义的方法') class B(object): def aaa(self): print('这是父类B定义的方法') class C(A,B): def aaa(self): print('这是子类重写的方法') def bbb(self): A.aaa(self) B.aaa(self) obj = C() obj.bbb()
运行结果:
这是父类A定义的方法 这是父类B定义的方法
-
使用super()可以在子类中调用父类重名方法
class A(object): def aaa(self): print('这是父类A定义的方法') class B(object): def aaa(self): print('这是父类B定义的方法') class C(A,B): def aaa(self): print('这是子类重写的方法') def bbb(self): super().aaa() # 无法指定父类 super(C,self).aaa() # 无法指定父类 B.aaa(self) obj = C() obj.bbb()
运行结果:
这是父类A定义的方法 这是父类A定义的方法 这是父类B定义的方法
私有属性和私有方法
-
在属性和方法的前面加上两个下划线__就会变成私有的属性和方法。
-
私有的属性和方法只能在类中被调用,无法被对象访问和使用。
-
私有的属性和方法无法被子类继承。
class A(): def __aaa(self): print('aaa') def bbb(self): self.__aaa() self.__ccc = 10 a = A() a.__aaa() # 报错 a.bbb() # 输出aaa print(a.__ccc) # 报错 class B(A): def baaa(self): self.__aaa() b = B() b.baaa() # 报错
-
修改私有属性的值,只能通过类中的方法来修改。
class A(): def aaa(self): self.__aa = 10 print(self.__aa) def bbb(self): self.__aa = 20 print(self.__aa) a = A() a.aaa() a.bbb() print(a.__aa)
运行结果:
10 20 Traceback (most recent call last): File "<input>", line 11, in <module> AttributeError: 'A' object has no attribute '__aa'
-
通过子类对象强行使用父类的私有属性
- 只能强行使用父类在魔法方法__init__中定义的私有属性
class A(object): def __init__(self): self.__pi = 3.14 class B(A): pass b =B() print(b._A__pi)
运行结果:
3.14
类属性和实例属性
- 类中直接通过变量名命名的属性就是类属性
- 类中通过self.变量名命名的属性就是实例属性
- 同名的实例属性会覆盖类属性
静态方法和类方法
-
通过@classmethod修饰的就是类方法,类方法中的第一个参数必须是类对象,通过cls来代替类对象,一般对类属性的操作都在类方法中进行
class People(object): country = 'china' #类方法,用classmethod来进行修饰 @classmethod def get_country(cls): return cls.country def get_num(self,country): self.country = country a = People() print(a.country) #通过实例对象调用类属性 a.get_num('japan') print(a.country) # 实例属性和类属性重名,实例属性覆盖类属性 print(a.get_country()) #通过实例对象调用类方法 print(People.country) #通过类对象调用类属性 print(People.get_country()) #通过类兑现调用类方法
运行结果:
china japan china china china
-
静态方法用@staticmethod修饰,静态方法中没有类参数和实例参数,只有正常的参数。一般用于不需要类和对象参与运算的场景。
class Sumadd(): @staticmethod def sum(a,b): print(a+b) c = Sumadd() c.sum(100,200) #输出 300
多态
-
在需要使用父类对象的地方也可以使用子类对象,这种情况就叫多态。
class Father(): def doctor(self): print('父亲为病人治好了病') class Son(Father): def doctor(self): print('儿子为病人治好了病') def patient(doc): doc.doctor() patient(Father()) patient(Son())
运行结果:
父亲为病人治好了病
儿子为病人治好了病
异常
异常就是程序出现错误导致无法其继续运行。
print('1---------------')
open('test.txt', 'r', encoding='utf-8')
print('2---------------')
运行结果:
1---------------
Traceback (most recent call last):
File "<input>", line 2, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
# 由于文件不存在出现了一个FileNotFoundError型的异常
捕获异常
-
当程序出现异常时,可以通过try…except…捕获异常,使程序可以继续向下运行
-
格式:
try: 异常代码 except 异常类型: 捕获异常时要执行的代码 正常代码
-
示例:
try: print('1---------------') open('test.txt', 'r', encoding='utf-8') except FileNotFoundError: print('就当错误不存在') print('2---------------')
运行结果:
1--------------- 就当错误不存在 2---------------
-
获取异常信息
try: print('1---------------') open('test.txt', 'r', encoding='utf-8') except FileNotFoundError as result: print(result) print('就当错误不存在') print('2---------------')
运行结果:
1--------------- [Errno 2] No such file or directory: 'test.txt' 就当错误不存在 2---------------
-
else
-
当没有捕获到异常时执行else中的代码
-
格式:
try: 异常代码 except 异常类型: 捕获异常时要执行的代码 else: 没有捕获异常时要执行的代码
-
示例:
try: num = 100 print(num) except NameError as errorMsg: print('产生错误了:%s'%errorMsg) else: print('没有捕获到异常,真高兴')
运行结果:
100 没有捕获到异常,真高兴
-
-
try…finally…
-
当一段代码无论程序会不会发生异常都必须要执行时,可以使用try…finally…,列如关闭文件等。
-
格式
try: 异常代码 except 异常类型: 捕获异常时要执行的代码 finally: 无论有没有异常都要执行的代码
-
示例:
# 无论是否遇到异常,都关闭文件 try: f = open('t.txt','w',encoding='utf-8') a = f.read() except : pass finally: print('关闭文件') f.close()
运行结果:
关闭文件
-
捕获多个异常
-
实际程序中可能一串代码中有多个类型的异常,这时就需要一次性捕获多个异常。
-
所有异常错误的顶级父类都是Exception,可以使用这个异常错误的顶级父类来捕获异常。
-
示例:
try: open('test.txt', 'r', encoding='utf-8') except (Exception): # 使用异常错误的顶级父类来捕获异常 print("捕获了异常")
try嵌套
- 内层try发生异常如果没有被处理就会向外层的try传递
#外部的try用于捕获文件打开是否成功,内部的try用于捕获读取文件数据时是否有异常发生
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
finally:
f.close()
print('关闭文件')
except:
print("没有这个文件")
函数嵌套捕获异常
def test1():
print("----test1-1----")
print(num)
print("----test1-2----")
def test2():
print("----test2-1----")
test1()
print("----test2-2----")
def test3():
try:
print("----test3-1----")
test1()
print("----test3-2----")
except Exception as result:
print("捕获到了异常,信息是:%s"%result)
print("----test3-2----")
test3()
print("------华丽的分割线-----")
test2()
运行结果:
----test3-1----
----test1-1----
捕获到了异常,信息是:name 'num' is not defined
----test3-2----
------华丽的分割线-----
----test2-1----
----test1-1----
Traceback (most recent call last):
File "<input>", line 26, in <module>
File "<input>", line 9, in test2
File "<input>", line 3, in test1
NameError: name 'num' is not defined
自定义异常
-
可以自行定义一个异常类,然后通过raise语句来引发一个异常。
-
自定义异常类应是Exception类或Error类的子类。
-
列如:
class UsernameError(Exception): def __init__(self,username): super(UsernameError, self).__init__() self.username = username username = 'zhuzhuxia' def login(): try: user_name = input('请输入管理员账户:') if user_name !=username: raise UsernameError(user_name) except UsernameError as result: print('管理员账户才不是%s呢'%result.username) else: print('输对了也不让你登录,哼哼') while True: login()
运行结果:
请输入管理员账户:zhu 管理员账户才不是zhu呢 请输入管理员账户:zhuzhuxia 输对了也不让你登录,哼哼 请输入管理员账户:
模块调用
-
一个模块就是一个python文件,用于封装类、方法。
-
import 模块名
- 调用该模块中的所有方法、属性
import 模块名 模块名.方法名() 模块名.属性
-
from 模块名 import 方法名,属性
- 调用模块中的某个方法、属性
- from 模块名 import * 调用模块中的所有方法和属性
- 当调用多个模块中的方法有重名时,后调用的会覆盖先调用的
from 模块名 import 方法名,属性名 方法名() 属性名
-
as 别名
-
import 模块名 as 模块名的别名
import random as rd a = rd.randint(0,5) print(a)
-
from 模块名 import 方法名 as 方法名的别名
from random import randint as rdi a = rdi(0,5) print(a)
-
当使用as为模块或方法起别名后,原模块或方法名将无法使用
-
-
_all_
- _all_[方法名] 控制模块中可以被调用的方法,只对from 模块名 import *有用,一般不会使用这个方法。
-
_name_
-
当在本地调用时显示的是__main__,当被别的模块调用时显示的是本地文件名。
-
主要用于在本地模块中测试代码。
if __name__ == '__main__': 一些测试本地函数的代码 ...... # 当非本地调用时不会执行这些测试代码
-
包的调用
-
包用于封装模块,相当于一个文件夹。
-
包中有一个__init__文件,相当于包的控制文件,其中可以写入all控制方法,不过最好空着。
-
import 包.模块
import 模块名 包名.模块名.方法名()
-
from 包.模块 import 方法
from 模块名 import 方法名 方法名()
-
_all_
- _all_[模块名] 控制模块中可以被调用的方法,只对from 模块名 import *有用
并发和并行
-
并发是单cpu交替运行多个软件
-
并行是多cpu同时运行多个软件