小甲鱼学python的课堂笔记
*BIF == Built-in functions 内置函数
一
*变量:把一个值赋值给一个名字时,它会存储在内存中,称之为变量(variable)
在大多数语言中,都把这种行为称为“给变量赋值”或“把值存储在变量中”。
*在使用变量前,要先对其进行赋值!!
*变量名可以包括字母,数字,下划线,但变量名不能以数字开头,要区分大小写,起名尽量专业!!!
*等号(=)是赋值的意思,左边是名字,右边是值,不能写反
二
*字符串:通常是文本
*原始字符串:只需在字符串前面加一个r,即可避免字符串当中带有“\”所带来的不便
*原始字符串的结尾不能是奇数的“\”,否则会报错,
*长字符串:如果想赋值一个特别长的字符串,需要用到三重引号字符串
*\n代表回车
三
*while循环:在python看来,while后面带有 ‘’ “” () False None {} [] 都被看做为假,其他一切都被解释为真
*python外援----random模块(随机)
*random模块有一个函数叫randint(),它会返回一个随机的整数。
四、数据类型
*整型 int():1 2 3 4 5
*浮点型 float():1.5 0.1 9.8
*e记法:15000=1.5e4 (e代表10,e后面的数字代表10的几次方),返回的值是浮点型(实际为float的科学计数法)
*字符串类型 str(): 代表文本
*布尔类型:特殊的整型。True=1 ,False=0
*type():判断数据为什么类型 例:a = 1, type(a), 返回<class,'int'>
*isinstance():判断数据类型是否成立 例:a = 1, isinstance(a,int),返回True
四、算术操作符
*( + - * / % ** // )
* // (float除法,也叫地板除法,只保留整数部分
)
* % (取余数,例子:5 % 2,得2余1,所以结果等于1)
* ** (幂运算,例子:5 ** 3 = 5 * 5 * 5 = 125)
*优先级问题:幂运算的 左边<**<右边,例子:-3 ** 2 = -(3 ** 2)= -9; 3 ** -2 = 3 ** (-2)= 0.1111111111
五、逻辑操作符
* (and;or;not)
* and操作符:只有两边都为真才返回TRUE,否则都为FALSE
* or操作符:两边有一边为真就会返回TRUE,两边都是错的才返回FALSE
* not操作符: 一般取数据的相反值
* 优先级:not>and>or
第八课、
*elif = else + if
例子:if 100 >= num >= 90: if 100 >= num >= 90:
print('A') print('A')
else: == elif 90 > num >= 80:
if 90 > num >= 80: print('B')
print('B')
*assert:断言
当这个关键字后边的条件为假的时候,程序自动崩溃并抛出AssertionError的异常
例子:>>> assert 3 > 4
应用:一般可以用assert在程序中置入检查点,当需要确保程序中的某个条件一定为真才能让程序正常工作的话,assert就起到了效果。
*三元操作符 (条件表达式)
语法: x if 条件 else y (当条件为真的时候,返回x;当条件为假的时候,返回y)
例子: x, y = 4, 5
if x < y:
small = x == x, y = 4, 5
else: small = x if x < y else y
small = y
*成员资格运算符:in,用于检查一个值是否在序列中,如果在序列中,返回True,否则返回False
例子:>>>name = '小甲鱼'
>>>'鱼' in name
True
>>>'肥鱼' in name
False
第九课、
*while循环:
语法:
while 条件:
循环体
*for循环:可以循环一个列表或者字符串
语法:
for 目标 in 表达式:
循环体
* 【】表示列表
例子:member = ['小甲鱼','小布丁','黑夜','迷途','怡静' ]
*len()
用途:计算参数的长度并返回。
例子:>>>i = 'CSQ'
>>>len(i)
3
*list()
用途:将参数以列表的形式显示
例子:>>>i = 'CSQ'
>>>list(i)
['C','S','Q']
*range()
语法:range([start,] stop[, step=1])
--这个BIF有三个参数,其中用中括号括起来的两个表示这两个参数是可选的;
--step=1表示第三个参数的值默认值是1
--range这个BIF的作用是生成一个从start参数的值开始 到stop参数的值结束的数字 序列
例子:>>>rang(5)
range(0,5)
>>>list(rang(5))
[0,1,2,3,4] 注意:因为是从0开始的,所以列表只到4,并不是到5
*break语句
用途:跳出当前循环
例子:>>>for i in 'Python':
if i == 'h':
break
print(i)
返回:P
y
t
*continue语句
用途:跳出本轮循环并 进入下一个循环
注意:只有当条件为TRUE的时候,才会进下轮循环;否则直接结束循环
例子:>>>for i in 'Python':
if i == 'h':
continue
print(i)
返回:P
y
t
o
n
第十课、
*列表:普通列表(数据类型一样),混合列表(不同的数据类型),空列表(例子:empty = [ ])
`向列表添加元素:append( )----------- 将参数作为一个元素添加到列表的末尾: member.append('CSQ')
extend( )----------- 向参数作为一个列表扩展列表的末尾: member.extend(['竹林小溪','Crazy迷恋'])
insert( )------------- 向列表中的对应位置加入一个对象 : member.insert(1,'牡丹') 注意: 列表中的第一个位置是0而不是1
第十一课、
*从列表中获取元素:通过元素的索引值(index)从列表中获取单个元素
例子:>>>member = ['小甲鱼','牡丹','怡静']
>>>member[0]
'小甲鱼'
*获取列表中的列表的元素
例子: >>>member = [123,['小甲鱼','牡丹'],456]
>>>list[1][0]
'小甲鱼'
*在列表中交换元素位置:
例子:将列表中小甲鱼和牡丹的位置互换
>>>member = ['小甲鱼','牡丹','怡静']
>>>temp = member[0]
>>>member[0] = member[1]
>>>member
['牡丹','牡丹','怡静']
>>>member[1] = temp
>>>member
['牡丹','小甲鱼','怡静']
*从列表中删除元素:remove( )-------------要知道列表中元素的具体名字: member.remove('怡静')
del语句---------------要知道列表中元素的具体位置: del member[0] 注意:del语句也可以删除整个列表:del member
pop( )----------------默认删除列表中最后一个元素并返回元素的值: member.pop( ) 注意:也可以删除某个位置的元素:member.pop(0)
pop( )的例子:
>>>member = ['小甲鱼','牡丹','怡静','Crazy迷恋','黑夜','福禄娃娃']
>>>member.pop( )
'福禄娃娃'
>>>member
['小甲鱼','牡丹','怡静','Crazy迷恋','黑夜']
>>>name = member.pop( ) #可以直接赋值给变量,列表中最后一个元素会直接赋值给变量
>>>name
'黑夜'
>>>member
['小甲鱼','牡丹','怡静','Crazy迷恋']
>>>member.pop(0)
'小甲鱼'
>>>member
['牡丹','怡静','Crazy迷恋']
*列表分片(列表切片):一次性获取列表中的多个元素
例子:>>>member = ['小甲鱼','牡丹','怡静','Crazy迷恋','黑夜']
>>>member[1:3] #注意:1:3不包含第三个元素,实际只返回1和2两个元素
['牡丹','怡静'] #注意:只是拷贝出一个列表,源列表并不会改变
>>>member[:3] #从列表最开始分片
>>>member[3:] #从第三个元素开始一直到最后一个元素分片
>>>member[:] #获得一个列表的拷贝,用于不想改变源列表,单独拷贝出一个列表进行编辑
第十二课、
*比较操作符在比较列表时,从列表中的第一个元素0开始比较并返回True或False
例子:>>>list1 = [123,456]
>>>list2 = [234,123]
>>>list3 = [123,456]
>>>list1 < list2
True
>>>(list1 < list2) and (list1 == list3)
True
*列表的+-*/
例子:>>>list1 = [123,456]
>>>list2 = [234,123]
>>>list3 = [123,456]
>>>list4 = list1 + list2 #列表相加
>>>list4
[123,456,234,123]
>>>list3 * 3 #列表的*
[123,456,123,456,123,456]
>>>list3
[123,456]
>>>list3 *= 3
[123,456,123,456,123,456]
>>>list3
[123,456,123,456,123,456]
*列表的成员操作符的应用
例子:>>>list1 = [123,456]
>>>123 in list1
True
>>>'小甲鱼' not in list1
True
*判断一个元素是否存在于列表中的列表
例子:>>>list5 = [123,['小甲鱼','牡丹'],456]
>>>'小甲鱼' in list5
False
>>>'小甲鱼' in list5[1]
True
*列表类型的内置函数
count( ):返回指定元素在列表中出现的次数------------ member.count( )
>>>member = [123,456,123,456,123,456,123,456,123,456,123,456,123,456,123,456]
>>>member.count(123)
8
index( ):返回指定元素在列表中的位置----------------- member.index( )
>>>member = [123,456,123,456,123,456,123,456,123,456,123,456,123,456,123,456]
>>>member.index(123) #没有指定具体的范围,所以就返回第一次出现的位置
0
>>>member.index(123,3,7) #在列表中3-7的范围内返回第一次出现的位置
4
reverse( ):将列表中的元素前后颠倒-------------------- member.reverse( )
>>>member = [123,['小甲鱼','牡丹'],456]
>>>member.reverse( )
[456,['小甲鱼','牡丹'],123]
sort( ):对列表按照指定的标准进行排队----------------- member.sort( )
>>>member = [4,2,5,1,9,23,32,0]
>>>member.sort( ) #没有参数时默认从小到大排队
[0,1,2,4,5,9,23,32]
>>>member.sort(reverse = True) #将列表中的元素从大到小排序,注意:这里的reverse是参数
copy( ):对列表进行拷贝-------------------------------- member.copy( )
>>>member = [123,['小甲鱼','牡丹'],456]
>>>member1 = member.copy( )
>>>member1
[123,['小甲鱼','牡丹'],456]
clear( ):用于清空列表的元素,清空完后列表仍然存在,会变成一个空列表 member.clear( )
>>>member = [123,['小甲鱼','牡丹'],456]
>>>member.clear( )
>>>member
[ ]
*列表推导式(列表解析):用来动态的创建列表
例子1: >>>[i*i for i in range(10)]
[0,1,4,9,16,25,36,49,64,81]
上述相当于:>>>member = [ ]
for i in range(10):
member.append(i**2)
>>> list3 = [name + ':' + slogan[2:] for slogan in list1 for name in list2 if slogan[0] == name[0]]
第十三课、
*元组:不可改变的类型,里面的元素是不能改变的----------戴上了枷锁的列表
-- 创建和访问一个元组
例子:>>>num = (1,2,3,4,5,6,7,8) #创建一个元组
>>>num
(1,2,3,4,5,6,7,8)
>>>num[1] #访问元组
2
-- 更新和删除一个元组
例子:>>>temp = ('小甲鱼','黑夜','迷途','小布丁')
>>>temp = temp[:2] + ('怡静',) + temp[2:] #向元组中加入元素
>>>temp
('小甲鱼','黑夜','怡静','迷途','小布丁')
>>>del temp #删除元组
>>>temp
name 'temp' is not defined #会报错,因为元组temp已经被删除了
*如何判断是不是元组:看有没有逗号,而不是有没有小括号
例子:>>>num = (1)
>>>num
1
>>>type(num) #num是一个整型,不是一个元组
<class 'int'>
>>>num = 1, #创建只有一个元素的元组
>>>num
(1,)
>>>type(num)
<class 'tuple'>
>>>num = ( ) #创建一个空元组
>>>num
( )
>>>type(num)
<class 'tuple'>
*在元组中用到的操作符
+ : temp = temp[:2] + ('小甲鱼',) + temp[2:]
* : 8 * (8,)== (8,8,8,8,8,8,8,8)
第十四课、
*各种奇葩的内置方法
--字符串切片:
>>>str1 = 'I Love fishc'
>>>str1[:6]
'I Love'
--索引字符串的某个元素:
>>>str1 = 'I Love fishc'
>>>str1[5]
'e'
--修改字符串
>>>str1 = 'I Love fishc'
>>>srt1[:6] + '插入的字符串' + str1[6:] #会返回加入后的结果,但不会改变str1
'I Love插入的字符串 fishc'
>>>str1
'I Love fishc'
>>>str1 = srt1[:6] + '插入的字符串' + str1[6:] #str1会改变
>>>str1
'I Love插入的字符串 fishc'
--修改字符串的参数
capitalize( )-------------------把字符串的第一个字符改为大写:str1.capitalize( )
casefold( )--------------------把整个字符串的所有字符改为小写:str1.casefold( )
center( width)----------------将字符串居中,并使用空格填充至长度width的新字符串:str1.center(40)
count(sub,[,start[,end]])------返回sub在字符串里边出现的次数,start和end参数表示范围,可选:str1.count('xi')
endswith(sub,[,start[,end]])--检查是否以sub结尾,是返回True,不是返回False,start和end参数表示范围,可选:str1.count('xi')
expandtabs([tabsize=8])-----把字符串中的\t转换为空格,如不指定参数,默认空格数tabsize=8:str1.expandtabs( )
find(sub,[,start[,end]])--------检测sub是否包含在字符串中,如果有则返回索引值(sub第一个元素的索引值),否则返回-1:str1.find( )
index(sub,[,start[,end]])------跟find方法一样,不过如果sub不在字符串中会产生一个异常:str1.index( )
isalnum( )---------------------如果字符串至少有一个字符并且所有字符都是字母或数字返回True,否则返回False:str1.isalnum( )
isalpha( )----------------------如果字符串至少有一个字符并且所有字符都是字母返回True,否则返回False:str1.isalpha( )
isdecimal( )--------------------如果字符串只包含十进制数字则返回True,否则返回False:str1.isdecimal( )
isdigit( )-----------------------如果字符串只包含数字则返回True,否则返回False:str1.isdigit( )
islower( )----------------------如果字符串中至少包含一个区分大小写的字符,并且字符都是小写,则返回True,否则返回False:str1.islower( )
isnumeric( )-------------------如果字符串中只包含数字字符,则返回True,否则返回False:str1.isnumeric( )
isspace( )----------------------如果字符串中只包含空格,则返回True,否则返回False:str1.isspace( )
istitle( )------------------------如果字符串是标题化(所有的单词都是以大写开始,其余字母均小写),则返回True,否则返回False:str1.istitle( )
isupper( )---------------------如果字符串中至少包含一个区分大小写的字符,并且这些字符都是大写,则返回True,否则返回False:str1.isupper( )
join(sub)----------------------以字符串作为分隔符,插入到sub中所有的字符之间:str1.join( )
>>>str1 = 'Fishc'
>>>str1.join('12345')
'1Fishc2Fishc3Fishc4Fishc5Fishc'
ljust(width)-------------------返回一个左对齐的字符串,并使用空格填充至长度width的新字符串:str1.ljust( )
lower( )-----------------------转换字符串中所有大写字符为小写:str1.lower( )
lstrip( )-----------------------去掉字符串左边的所有空格:str1.lstrip( )
partition(sub)----------------找到子字符串sub,把字符串分成一个3元组(pre_sub,sub,fol_sub),如果字符串中不含sub则返回('原字符串',' ',' '):str1.partition( )
>>>str1 = 'i love fishc'
>>>str1.partition('ov')
(''i l','ov','e fishc')
replace(old,new,[,count])----把字符串中的old子字符串替换成new子字符串,如果count指定,则替换不超过count次:str1.replace(
rfind(sub,[,start[,end]])-------类似于find( )方法,不过是从右边开始查找:str1.rfind( )
rindex(sub,[,start[,end]])------类似于index( )方法,不过是从右边开始:str1.rindex( )
rjust(width)-------------------返回一个右对齐的字符串,并使用空格填充至长度为width的新字符串:str1.rjust
rpartition(sub)----------------类似于partition( )方法,不过是从右边开始查找:str1.rpartition( )
rstrip( )------------------------删除字符串末尾的空格:str1.rstrip( )
split(sep=None,maxsplit=-1)-不带参数默认是以空格为分隔符切片字符串,如果maxsplit参数有设置,则分隔maxsplit个子字符串,返回切片后的子字符串拼接的列表:str1.split( )
>>>str1 = 'i love fishc'
>>>str1.split( )
['i','love','fishc']
>>>str1.split('i')
[' ','love f','shc']
splitlines(([keepends]))--------按照'\n'分隔,返回一个包含各行作为元素的列表,如果keepends参数指定,则返回钱keepends行:str1.splitlines( )
startswith(prefix[,start[,end]])-检查字符串是否以prefix开头,是则返回True,否则返回False,strat和end参数可以指定范围检查,可选:str1.startswith( )
strip([chars])-------------------删除字符串前边和后边所有的空格,chars参数可以定制删除的字符,可选:str1.strip( )
swapcase( )-------------------翻转字符串中的大小写:str1.swapcase( )
title( )-------------------------返回标题化(所有的单词都是以大写开始,其余字母均小写)的字符串:str1.title( )
translate(table)---------------根据table的规则(可以由str.maketrans('a','b')定制)转换字符串中的字符:str1.translate( )
>>>str1 = 'ssssaaassss'
>>>str1.translate(str.maketrans('a','b'))
'ssssbbbssss'
upper( )-----------------------转换字符串中的所有小写字符为大写:str1.upper( )
zfill(width)--------------------返回长度为width的字符串,原字符串右对齐,前边用0填充:str1.zfill( )
*跨越多行字符串的几种方式
--用三引号''': >>>str1 = '''aaabbb #三引号的方法打印出来的结果也是自动换行的
cccddd
eeefff'''
>>>print(str1)
aaabbb
cccddd
eeefff
--用引号加\: >>>str1 = 'aaabbb\
cccddd\
eeefff'
>>>print(str1)
aaabbbcccdddeeefff
--用小括号加引号: >>>str1 = ('aaabbb'
'cccddd'
'eeefff')
>>>print(str1)
aaabbbcccdddeeefff
第十五课、
*字符串格式化
--format
例子:>>>'{0} love {1}.{2}'.format('I','FishC','com') #format的位置参数
'I love FishC.com'
>>>'{a} love {b}.{c}'.format(a='I',b='FishC',c='com') #format的关键字参数
'I love FishC.com'
>>>'{0} love {b}.{c}'.format('I',b='FishC',c='com') #位置和关键字参数的结合 注意:位置参数(0)要在关键字参数(b,c)前面,否则会报错
'I love FishC.com'
>>>'{a} love {b}.{0}'.format(a='I',b='FishC','com') #注意:位置参数(0)要在关键字参数(b,c)前面,否则会报错
SyntaxError: positional argument follows keyword argument
>>>'{0:.1f}{1}'.format(27.658,'GB') #在替换域中 ':'表示格式化符号的开始,'.1'表示保留小数点后一位,'f'表示打印定点数
'27.7GB'
*当%遇到字符串
--字符串格式化符号含义
%c-----------------------格式化字符及其ASCII码
>>> '%c' % 97 #97对应的ASCII码就是a
'a'
>>>'%c %c %c' % (97,98,99) #97,98,99要用元组括起来
'a b c'
%s-----------------------格式化字符串
>>>'%s' % 'I Love FishC'
'I Love FishC'
%d-----------------------格式化整数
>>>'%d + %d = %d' % (4,5,4+5)
'4 + 5 = 9'
%o-----------------------格式化无符号八进制数
>>>'%o' % 10
'12'
%x-----------------------格式化无符号十六进制数
>>>'%x' % 160
'a0'
%X-----------------------格式化无符号十六进制数(大写)
>>>'%X' % 160
'A0'
%f------------------------格式化定点数,可指定小数点后的精度
>>>'%f' % 27.658 #默认精确到小数点后6位
'27.658000'
%e------------------------用科学计数法格式化定点数
>>>'%e' % 27.658
'2.765800e+01'
%E------------------------作用同%e,用科学计数法格式化定点数
>>>'%E' % 27.658
'2.765800E+01'
%g------------------------根据值的大小决定使用%f或%e
>>>'%g' % 27.6587564
'27.6588'
%G------------------------作用同%g,根据值的大小决定使用%f或%E
--格式化操作符辅助指令
m.n------------------------m是显示的最小总宽度,n是小数点后的位数
>>>'%5.1f' % 27.658
' 27.7' #返回的字符串的长度要等于5,所以前面要加空格
>>>'%.2e' % 27.658
'2.77e+01'
- -----------------------用于左对齐
>>>'%-10d' % 5
'5 '
+ -----------------------在正数前面显示加号(+)
>>>'%+d' % 5
'+5'
>>>'%+d' % -5
'-5' #如果是负数的话,则不会显示-
# -----------------------在八进制数前面显示零(‘0o’),十六进制数前面显示‘0x’或‘0X’
>>>'%#o' % 10
'0o12' #八进制
>>>'%#x' % 10
'0xa' #十六进制
0 -----------------------显示的数字前面填充‘0’取代空格
>>>'%010d' % 5
'0000000005'
>>>'%-010d' % 5 #当有-时,返回结果中的空格不会被0填充,因为会变成5000000000
'5 '
第十六课、
*序列
tuple( )-------------------------把一个可迭代对象转换为元组
sum( )--------------------- >>>num = [1,38,14,2,59,82,11,64] #要判断的类型必须是int或者float类型
>>>sum(num)
271
>>>sum(num,9)
280
max( )---------------------->>>str1 = 'I Love FishC.com'
>>>max(str1) #根据ASCII码的值来判断大小
'v'
>>>tuple1 = (1,38,4,79,52,46,2,3) #注意:要判断的数据必须是同一数据类型的
>>>max(tuple1)
79
min( )----------------------同max( )
list( )----------------------->>>str1 = 'I Love FishC.com'
>>>list(str1)
['I', ' ', 'L', 'o', 'v', 'e', ' ', 'F', 'i', 's', 'h', 'C', '.', 'c', 'o', 'm']
sorted( )------------------->>>num = [1, 38, 14, 2, 59, 82, 11, 64, 3.4]
>>>sorted(num) #默认从小到大排序
[1, 2, 3.4, 11, 14, 38, 59, 64, 82]
reversed( )---------------->>>num = [1, 38, 14, 2, 59, 82, 11, 64, 3.4]
>>>reversed(num) #返回的是一个迭代器对象
<list_reverseiterator object at 0x000002AE3026D130>
>>>list(reversed(num)) #用list的方式将列表翻转
[3.4, 64, 11, 82, 59, 2, 14, 38, 1]
enumerate( )------------->>>num = [1, 38, 14, 2, 59, 82, 11, 64, 3.4]
>>>enumerate(num) #同样也是返回一个迭代器对象
<enumerate object at 0x000002AE2FD2FDC0>
>>>list(enumerate(num)) #列表的每一个元素都变成了一个元组,前面是元素的索引值
[(0, 1), (1, 38), (2, 14), (3, 2), (4, 59), (5, 82), (6, 11), (7, 64), (8, 3.4)]
zip( )---------------------->>>a = [1,2,3,4,5,6,7,8]
>>>b = [4,5,6,7,8]
>>>zip(a,b) #返回一个迭代器对象
<zip object at 0x000002AE30482500>
>>>list(zip(a,b)) #用list的方式将a和b相对应索引值的元素变成元组,由于b只有5个元素,所以只返回前面5个元组
[(1, 4), (2, 5), (3, 6), (4, 7), (5, 8)]
第十七课、
*函数
def ----------------------创建一个函数 #尽量使用有意义的词,函数的第一个单词为大写,并做好注释
>>>def MyFirstFunction(): 如果想调用创建的函数,直接打出来就可以
print('这是我创建的第一个函数!') --> >>>MyFirstFunction( )
print('我表示很激动....') 这是我创建的第一个函数!
print('在此我要感谢TVB,感谢CCAV,感谢小甲鱼...') 我表示很激动....
-----------------------------------------------------------------------------------------------------------------------------
>>>def MySecondFunction(name): #给函数增加参数,参数必须是变量,不能用元组或者列表之类
print(name + '我爱你!')
>>>MySecondFunction('小甲鱼')
小甲鱼我爱你!
-----------------------------------------------------------------------------------------------------------------------------
>>>def add(num1,num2): #给函数增加多个参数,中间用逗号隔开
result = num1 + num2
print(result)
>>>add(1,2)
3
-----------------------------------------------------------------------------------------------------------------------------
>>>def add(num1,num2): #函数的返回值
return (num1 + num2)
>>>print(add(5,6))
11
第十八课、
*参数--------------分为形式参数(形参,parameter)和实际参数(实参,argument)
例子:>>>def MyFun(x,y): #x,y就是形参
result = x + y
return result
>>>MyFun(2,3) #2,3就是实参
----------------------------------------------------------------------------------------------------------------------------
*函数文档
>>>def MyFirstFunction(name):
'函数定义过程中的name叫形参' #注释和函数文档都不会被打印出来
#因为Ta只是一个形式,表示占据一个参数位置
print('传递进来的' + name + '叫做实参,因为Ta是具体的参数值!')
>>>MyFirstFunction('小甲鱼')
传递进来的小甲鱼叫做实参,因为Ta是具体的参数值!
>>>MyFirstFunction.__doc__ #双下横线 _ _
'函数定义过程中的name叫形参' #打印出来该函数的函数文档
>>>help(MyFirstFunction) #也可以用help的方法查看函数文档
Help on function MyFirstFunction in module __main__:
MyFirstFunction(name)
函数定义过程中的name叫形参
----------------------------------------------------------------------------------------------------------------------------
*关键字参数
>>> def SaySome(name,words):
print(name + '->' + words)
>>> SaySome('小甲鱼','让编程改变世界!')
小甲鱼->让编程改变世界!
>>> SaySome('让编程改变世界!','小甲鱼')
让编程改变世界!->小甲鱼
>>> SaySome(words = '让编程改变世界!',name = '小甲鱼') #这里的words和name就是关键字参数
小甲鱼->让编程改变世界!
----------------------------------------------------------------------------------------------------------------------------
*默认参数
>>> def SaySome(name='小甲鱼',words='让编程改变世界!'):
print(name + '->' + words)
>>> SaySome( ) #这里不带参数就会打印出默认参数
小甲鱼->让编程改变世界!
>>> SaySome('CSQ')
CSQ->让编程改变世界!
----------------------------------------------------------------------------------------------------------------------------
*收集参数(可变参数)
>>> def test(*params):
print('参数的长度是',len(params))
print('第二个参数是',params[1])
>>> test(1,'小甲鱼',3.14,5,6,7,8) #1,'小甲鱼',3.14,5,6,7,8这几个都是收集参数
参数的长度是 7
第二个参数是 小甲鱼
>>> def test(*params,exp):
print('参数的长度是',len(params),exp)
print('第二个参数是',params[1])
>>> test(1,'小甲鱼',3.14,5,6,7,8,exp = 8) #如果想要加其他参数,则要用到关键字参数,最好用默认参数
参数的长度是 7 8
第二个参数是 小甲鱼
----------------------------------------------------------------------------------------------------------------------------
第十九课、
*变量的作用域
局部变量:在定义的函数中存在的变量,只在该函数中起作用
全局变量:可以在定义的函数中调用,但不要在函数中修改全局变量
----------------------------------------------------------------------------------------------------------------------------
第二十课、
*global关键字
>>>count = 10
>>> def MyFun():
global count #将全局变量的count改变了
count = 5
print(5)
>>> MyFun()
5
>>> print(count)
5
----------------------------------------------------------------------------------------------------------------------------
*内嵌函数
>>> def fun1():
print('fun1()正在被调用...')
def fun2():
print('fun2()正在被调用...')
fun2()
>>> fun1()
fun1()正在被调用...
fun2()正在被调用...
>>> fun2() #fun2()作为内嵌函数,只能在fun1()中调用
Traceback (most recent call last):
File "<pyshell#94>", line 1, in <module>
fun2()
NameError: name 'fun2' is not defined
----------------------------------------------------------------------------------------------------------------------------
*闭包
>>> def FunX(x):
def FunY(y):
return x*y
return FunY
>>> i = FunX(8)
>>> type(i)
<class 'function'>
>>> i(5)
40
>>> FunX(8)(5)
40
----------------------------------------------------------------------------------------------------------------------------
*nonlocal
>>> def Fun1():
x = 5
def Fun2():
nonlocal x
x *= x
return x
return Fun2()
>>> Fun1()
25
-----------------------------------------------------------------------------------------------------------------------------
第二十一课、
*lambda表达式 >>>def ds(x):
>>> g = lambda x: 2 * x + 1 #这就是个匿名函数,相当于: return 2 * x + 1
>>> g(5)
11 >>>da(5)
11
>>> g = lambda x,y: x + y #多个参数
>>> g(3,4)
7
-----------------------------------------------------------------------------------------------------------------------------
*filter( ):过滤器
>>> list(filter(None,[1,0,False,True]))
[1, True]
>>> def odd(x):
return x%2 >>>list(filter(lambda x: x % 2,range(10)))
>>> temp = range(10) == [1, 3, 5, 7, 9]
>>> show = filter(odd,temp)
>>> list(show)
[1, 3, 5, 7, 9]
-----------------------------------------------------------------------------------------------------------------------------
*map( ):映射
>>> list(map(lambda x: x * 2,range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> list(map(lambda x, y : [x, y], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
-----------------------------------------------------------------------------------------------------------------------------
第二十二课、
*递归------------------在编程上,递归表现为函数调用本身这么一个行为。
注意:递归必须满足的两个条件
1.函数调用自身
2.设置了正确的返回条件
>>>def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
>>>number = int(input('请输入一个正整数:'))
>>>result = factorial(number)
>>>print('%d的阶乘是:%d'%(number,result))
5的阶乘是:120
----------------------------------------------------------------------------------------------------------------------------
第二十三课、
*斐波那契(Fibonacci)数列的递归实现
用迭代求兔子诞生的数量:
def fab(n):
n1 = 1
n2 = 1
n3 = 1
if n < 1:
print('输入有误!')
return -1
while (n - 2) > 0:
n3 = n2 + n1
n1 = n2
n2 = n3
n -= 1
return n3
temp = int(input('请输入繁殖到第几个月了:'))
result = fab(temp)
if result != -1:
print('总共有%d对小兔崽子' % result)
---------------------------------------------------------------------------------------------------------------------------
用递归求兔子诞生的数量:
def fab(n):
if n < 1:
print('输入有误!')
return -1
if n==1 or n==2:
return 1
else:
return fab(n - 1) + fab(n - 2)
temp = int(input('请输入繁殖到第几个月了:'))
result = fab(temp)
if result != -1:
print('总共有%d对小兔崽子' % result)
---------------------------------------------------------------------------------------------------------------------------
第二十四课、
*汉诺塔
def hanoi(n,x,y,z):
if n == 1:
print(x,'-->',z)
else:
hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上
print(x,'-->',z)#将最底下的最后一个盘子从x移动到z上
hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上
n = int(input('请输入汉诺塔的层数:'))
hanoi(n,'X','Y','Z')
---------------------------------------------------------------------------------------------------------------------------
第二十六课、
*字典:当索引不好用时
注意:字符串、列表和元组是序列类型,而字典是映射类型
---------------------------------------------------------------------------------------------------------------------------
*dict----------------工厂函数(类型)
创建和访问字典:
>>> dict1 = {'李宁':'一切皆有可能','耐克':'Just do it','阿迪达斯':'Impossible is nothing','鱼C工作室':'让编程改变世界'} #创建一个字典
#‘李宁’:Key值; ‘一切皆有可能’:Value值; 中间用‘:’隔开
---------------------------------------------------------------------------------------------------------------------------
>>> print('鱼C工作室的口号是:',dict1['鱼C工作室']) #对字典进行访问
鱼C工作室的口号是: 让编程改变世界
#要用‘[ ]’,里面不是索引值,而是Key值
---------------------------------------------------------------------------------------------------------------------------
>>> dict2 = {1:'one',2:'two',3:'three'}
>>> dict2[2]
---------------------------------------------------------------------------------------------------------------------------
>>> dict3 = dict((('F',70),('i',105),('s',115),('h',104),('C',67)))
>>> dict3
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
---------------------------------------------------------------------------------------------------------------------------
>>> dict4 = dict(小甲鱼='让编程改变世界',苍井空='让AV征服所有宅男')
#Key值不要加引号
>>> dict4
{'小甲鱼': '让编程改变世界', '苍井空': '让AV征服所有宅男'}
>>> dict4['苍井空'] = '所有AV从业者都要通过编程来提高职业技能'
#更改字典里Key的值
>>> dict4
{'小甲鱼': '让编程改变世界', '苍井空': '所有AV从业者都要通过编程来提高职业技能'}
>>> dict4['爱迪生'] = '天才就是99%的汗水+1%的灵感,但这1%的灵感远比99%的汗水更重要'
#增加字典里的Key值,就跟Linux里的vi一样
>>> dict4
{'小甲鱼': '让编程改变世界', '苍井空': '所有AV从业者都要通过编程来提高职业技能', '爱迪生': '天才就是99%的汗水+1%的灵感,但这1%的灵感远比99%的汗水更重要'}
----------------------------------------------------------------------------------------------------------------------------
第二十七课、
*fromkeys( )------------------------dict1.fromkeys( )
>>> dict1 = {}
>>> dict1.fromkeys((1,2,3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1,2,3),'Number')
{1: 'Number', 2: 'Number', 3: 'Number'}
----------------------------------------------------------------------------------------------------------------------------
*keys( )-----------------------------dict1.keys( )
>>> dict1 = dict1.fromkeys(range(32),'赞')
>>> dict1
{0: '赞', 1: '赞', 2: '赞', 3: '赞', 4: '赞', 5: '赞', 6: '赞', 7: '赞', 8: '赞',
9: '赞', 10: '赞', 11: '赞', 12: '赞', 13: '赞', 14: '赞', 15: '赞', 16: '赞',
17: '赞', 18: '赞', 19: '赞', 20: '赞', 21: '赞', 22: '赞', 23: '赞', 24: '赞',
25: '赞', 26: '赞', 27: '赞', 28: '赞', 29: '赞', 30: '赞', 31: '赞'}
>>> for eachKey in dict1.keys():
print(eachKey)
0
1
2 --> 打印出Key值
...
31
----------------------------------------------------------------------------------------------------------------------------
*values( )----------------------------dict1.values( )
>>> for eachValue in dict1.values():
print(eachValue)
赞
赞
赞 --> 打印出value值,32个赞
...
赞
----------------------------------------------------------------------------------------------------------------------------
*items( )-----------------------------dict1.items( )
>>> for eachItem in dict1.items():
print(eachItem)
(0, '赞')
(1, '赞')
(2, '赞') --> 打印出items值
...
(31, '赞')
----------------------------------------------------------------------------------------------------------------------------
*get( )-------------------------------dict1.get( )
>>> dict1.get(32)
>>> print(dict1.get(32))
None
>>> print(dict1.get(32,'木有!'))
木有!
>>> print(dict1.get(31,'木有!'))
赞
-----------------------------------------------------------------------------------------------------------------------------
*成员资格操作符
>>> 32 in dict1
False
>>> 31 in dict1
True
------------------------------------------------------------------------------------------------------------------------------
*clear( )------------------------------dict1.clear( )
>>> dict1
{0: '赞', 1: '赞', 2: '赞', 3: '赞', 4: '赞', 5: '赞', 6: '赞', 7: '赞', 8: '赞',
9: '赞', 10: '赞', 11: '赞', 12: '赞', 13: '赞', 14: '赞', 15: '赞', 16: '赞',
17: '赞', 18: '赞', 19: '赞', 20: '赞', 21: '赞', 22: '赞', 23: '赞', 24: '赞',
25: '赞', 26: '赞', 27: '赞', 28: '赞', 29: '赞', 30: '赞', 31: '赞'}
>>> dict1.clear() #注意:最好不要用dict1 = {}来清空,因为这样的话原字典还会存在于内存中
>>> dict1
{}
------------------------------------------------------------------------------------------------------------------------------
*copy( )------------------------------dict1.copy( )
>>> a = {1:'one',2:'two',3:'three'} #copy与赋值不一样,要注意!
>>> b = a.copy() #前拷贝
>>> c = a
>>> c
{1: 'one', 2: 'two', 3: 'three'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
>>> a
{1: 'one', 2: 'two', 3: 'three'}
>>> id(a)
2538548069760
>>> id(c)
2538548069760
>>> id(b)
2538548070400
>>> c[4] = 'four'
>>> c
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}
-------------------------------------------------------------------------------------------------------------------------------
*pop( )与popitem( )
>>> a = {1:'one',2:'two',3:'three',4:'four'}
>>> a.pop(2)
'two'
>>>a
{1:'one',3:'three',4:'four'}
>>> a.popitem() #注意,这里是随机返回,因为在里没有顺序一说的
(4, 'four')
>>>a
{1: 'one', 3: 'three'}
-------------------------------------------------------------------------------------------------------------------------------
*setdefault( )
>>> a
{1: 'one', 3: 'three'}
>>> a.setdefault('小白')
>>> a
{1: 'one', 3: 'three', '小白': None}
>>> a.setdefault(5,'five')
'five'
>>> a
{1: 'one', 3: 'three', '小白': None, 5: 'five'}
--------------------------------------------------------------------------------------------------------------------------------
*update( )
>>> a
{1: 'one', 3: 'three', '小白': None, 5: 'five'}
>>> b = {'小白':'狗'}
>>> b
{'小白': '狗'}
>>> a.update(b)
>>> a
{1: 'one', 3: 'three', '小白': '狗', 5: 'five'}
---------------------------------------------------------------------------------------------------------------------------------
第二十八课、
*集合(set)--------------------------当元素用大括号括起来但没有映射关系时,就成为集合
>>> num2 = {1,2,3,4,5}
>>> type(num2)
<class 'set'>
---------------------------------------------------------------------------------------------------------------------------------
>>> num2 = {1,2,3,4,5,5,4,3,2}
>>> num2
{1, 2, 3, 4, 5} #集合当中的元素都具有唯一性,会自动将重复的元素剔除
---------------------------------------------------------------------------------------------------------------------------------
>>> num2 = {1,2,3,4,5}
>>> num2[2] #集合当中的元素是无序的,不能被索引到,会报错
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
num2[2]
TypeError: 'set' object is not subscriptable
---------------------------------------------------------------------------------------------------------------------------------
*使用set( )工厂函数创建一个集合
>>> set1 = set([1,2,3,4,5,5])
>>> set1
{1, 2, 3, 4, 5}
---------------------------------------------------------------------------------------------------------------------------------
例子:将num1中的重复项去除
(1)
>>> num1 = [1,2,3,4,5,5,3,1,0]
>>> temp = []
>>> for each in num1:
if each not in temp:
temp.append(each)
>>> temp
[1, 2, 3, 4, 5, 0]
(2)
>>> num1 = [1,2,3,4,5,5,3,1,0]
>>> num1 = list(set(num1))
>>> num1
[0, 1, 2, 3, 4, 5]
----------------------------------------------------------------------------------------------------------------------------------
*访问集合中的值
>>> num1
[0, 1, 2, 3, 4, 5]
>>> 1 in num1
True
>>> '1' in num1
False
-----------------------------------------------------------------------------------------------------------------------------------
*增加,删除集合中的元素
>>> num2
{1, 2, 3, 4, 5}
>>> num2.add(6) #增加元素
>>> num2
{1, 2, 3, 4, 5, 6}
>>> num2.remove(5) #删除元素
>>> num2
{1, 2, 3, 4, 6}
-----------------------------------------------------------------------------------------------------------------------------------
*不可变集合(frozenset)
>>> num3 = frozenset([1,2,3,4,5])
>>> num3
frozenset({1, 2, 3, 4, 5})
>>> num3.add(0) #不可变集合不能增加元素
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
num3.add(0)
AttributeError: 'frozenset' object has no attribute 'add'
------------------------------------------------------------------------------------------------------------------------------------
第二十九课、
*文件
文件打开模式:
'r'------------------以只读方式打开文件(默认)
'w'-----------------以写入的方式打开文件,会覆盖已存在的文件(之前的文件内容就没有了)
'x'------------------如果文件已经存在,使用此模式打开将发生异常
'a'------------------以写入模式打开,如果文件存在,则在末尾追加写入
'b'------------------以二进制模式打开文件
't'------------------以文本模式打开(默认)
'+'-----------------可读写模式(可添加到其他模式中使用)
'U'-----------------通用换行符支持
-------------------------------------------------------------------------------------------------------------------------------------
文件对象方法:
f.close( )----------------关闭文件
f.read(size=-1)---------从文件读取size个字符,当未给定size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回
f.readline( )-------------以写入模式打开,如果文件已经存在,则在末尾追加写入
f.write(str)--------------将字符串str写入文件
f.writelines(seq)--------向文件写入字符串序列seq,seq应该是一个返回字符串的可迭代对象
f.seek(offset,from)-----在文件中移动文件指针,从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)偏移offset个字节
f.tell( )------------------返回当前在文件中的位置
--------------------------------------------------------------------------------------------------------------------------------------
第三十课、
*模块-------------------是一个包含你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能
>>> import random
>>> secret = random.randint(1,10)
>>> secret #随机数
7
-------------------------------------------------------------------------------------------------------------------------------------
*os模块
os模块中关于文件/目录常用的函数方法
getcwd( )---------------------------------返回当前工作目录
>>> import os
>>> os.getcwd()
'D:\\应用MAX\\python'
chdir(path)-------------------------------改变工作目录
>>> os.chdir('D:\\')
>>> os.getcwd()
'D:\\
listdir(path = ' ')--------------------------列举指定目录中的文件名('.'表示当前目录,'..'表示上级目录)
>>> os.listdir('D:\\')
['$RECYCLE.BIN', '360base.dll', '360downloads', 'MyDrivers', 'Program Files', 'start', 'System Volume Information', 'test.txt',
'winrar-x64-580scp.exe', 'winwar', 'WLLOS', '应用MAX', '电视剧', '虚拟定位', '虚拟定位.zip']
mkdir(path)------------------------------创建单层目录,如该目录已存在抛出异常
>>> os.mkdir('D:\\A\\B') #在D盘创建A文件夹,在A文件夹下创建B文件夹,注意:必须先创建A,才能创建B
makedirs(path)---------------------------递归创建多层目录,如该目录已存在抛出异常,注意:'E:\\a\\b'和'E:\\a\\c'并不会冲突
>>> os.makedirs('D:\\test\\B') #在D盘递归的创建test文件及其子文件夹B
remove(path)----------------------------删除文件
>>> os.remove('D:\\A\\B\\test.txt ')
rmdir(path)-------------------------------删除单层目录,如该目录非空则抛出异常
>>> os.rmdir('D:\\A\\B') #只删除B文件夹
removedirs(path)-------------------------递归删除目录,从子目录到父目录逐层尝试删除,遇到非空目录则抛出异常
>>> os.removedirs('D:\\A\\B')
rename(old,new)-------------------------将文件old重命名为new
>>> os.rename('D:\\A','D:\\B')
system(command)-----------------------运行系统的shell命令
>>> os.system('cmd')
os.curdir---------------------------------指代当前目录('.')
os.pardir---------------------------------指代上一级目录('..')
os.sep------------------------------------输出操作系统特定的路径分隔符(Win下为'\\',Linux下 为'/')
os.linesep--------------------------------当前平台使用的行终止符(Win下为'\r\n',Linux下为'\n')
os.name---------------------------------指代当前使用的操作系统(包括:'posix','nt','mac','os2','ce','java')
-----------------------------------------------------------------------------------------------------------------------------------
*os.path模块中关于路径常用的函数使用方法
basename(path)------------------------去掉目录路径,单独返回文件名
>>> os.path.basename('D:\\A\\B\\test.txt')
'test.txt'
dirname(path)--------------------------去掉文件名,单独返回目录路径
>>> os.path.dirname('D:\\A\\B\\test.txt')
'D:\\A\\B'
join(path1[,path2[,..]])-------------------将path1,path2各部分组合成一个路径名
>>> os.path.join('C:\\','A','B','C')
'C:\\A\\B\\C'
split(path)-------------------------------分割文件名与路径,返回(f_path,f_name)元组,如果完全使用目录,它将会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在
>>> os.path.split('D:\\A\\test.txt')
('D:\\A', 'test.txt') #注意,如果没有给定文件名而都是路径的话,系统会默认最后一个路径为文件
splitext(path)---------------------------分离文件名与扩展名,返回(f_name,f_extension)元组
>>> os.path.splitext('D:\\A\\test.txt')
('D:\\A\\test', '.txt')
getsize(file)-----------------------------返回指定文件的尺寸,单位是字节
getatime(file)---------------------------返回指定文件最近的访问时间(浮点型秒数,可用time模块的gmtime( )或localtime( )函数换算)
>>> os.path.getatime('D:\\A\\B\\test.txt')
1597549869.2617092
>>> import time
>>> time.gmtime(os.path.getatime('D:\\A\\B\\test.txt'))
time.struct_time(tm_year=2020, tm_mon=8, tm_mday=16, tm_hour=3, tm_min=51, tm_sec=9, tm_wday=6, tm_yday=229, tm_isdst=0)
>>> time.localtime(os.path.getatime('D:\\A\\B\\test.txt'))
time.struct_time(tm_year=2020, tm_mon=8, tm_mday=16, tm_hour=11, tm_min=51, tm_sec=9, tm_wday=6, tm_yday=229, tm_isdst=0)
getctime(file)---------------------------返回指定文件的创建时间(浮点型秒数,可用time模块的gmtime( )或localtime( )函数换算)
getmtime(file)--------------------------返回指定文件最近的修改时间(浮点型秒数,可用time模块的gmtime( )或localtime( )函数换算)
以下为函数返回True或False
exists(path)-----------------------------判断指定路径(目录或文件)是否存在
isabs(path)-----------------------------判断指定路径是否为绝对路径
isdir(path)------------------------------判断指定路径是否存在且是一个目录
isfile(path)------------------------------判断指定路径是否存在且是一个文件
islink(path)-----------------------------判断指定路径是否存在且是一个符号链接
ismount(path)--------------------------判断指定路径是否存在且是一个挂载点
samefile(path1,path2)-----------------判断path1和path2两个路径是否指向同一个文件
------------------------------------------------------------------------------------------------------------------------------------------
第三十一课、
*pickle模块
pickle的实质---利用一些算法将你的数据对象“腌制”成二进制文件,存储在磁盘上,当然也可以放在数据库或者通过网络传输到另一台计算机上
pickle.dump(data, file) # 第一个参数是待存储的数据对象,第二个参数是目标存储的文件对象,注意要先使用'wb'的模式open文件
pickle.load(file) # 参数是目标存储的文件对象,注意要先使用'rb'的模式open文件
>>> import pickle
>>> my_list = [123,3.14,'小甲鱼',['another list']]
>>> pickle_file = open('D:\my_list.pkl','wb')
>>> pickle.dump(my_list,pickle_file) #将my_list列表以二进制的形式保存到pickle_file中
>>> pickle_file.close()
>>> pickle_file = open('D:\my_list.pkl','rb')
>>> my_list2 = pickle.load(pickle_file) #将数据导出
>>> my_list2
[123, 3.14, '小甲鱼', ['another list']]
>>> pickle_file.close()
---------------------------------------------------------------------------------------------------------------------------------------------
第三十二课、
*python标准异常总结:
AssertionError-----------------------------------断言语句(assert)失败(经常应用于测试)
>>> my_list = ['小甲鱼是帅哥']
>>> assert len(my_list) > 0
>>> my_list.pop()
'小甲鱼是帅哥'
>>> assert len(my_list) > 0
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
assert len(my_list) > 0
AssertionError
AttributeError-----------------------------------尝试访问未知的对象属性
>>> my_list.fishc
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
my_list.fishc
AttributeError: 'list' object has no attribute 'fishc'
EOFError----------------------------------------用户输入文件末尾标志EOF(Ctrl+d)
FloatingPointError------------------------------浮点计算错误
GeneratorExit-----------------------------------generator.close()方法被调用的时候
ImportError-------------------------------------导入模块失败的时候
IndexError---------------------------------------索引超出序列的范围
>>> my_list = [1,2,3]
>>> my_list[3]
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
my_list[3]
IndexError: list index out of range
KeyError-----------------------------------------字典中查找一个不存在的关键字
>>> my_dict = {'one':1,'two':2,'three':3} #可以用 my_dict.get('four') 来避免出错,因为这样即使字典中没有'four'也只是什么都不返回
>>> my_dict['four']
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
my_dict['four']
KeyError: 'four'
KeyboardInterrupt------------------------------用户输入中断键(Ctrl+c)
MemoryError------------------------------------内存溢出(可通过删除对象释放内存)
NameError--------------------------------------尝试访问一个不存在的变量
>>> fishc
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
fishc
NameError: name 'fishc' is not defined
NotImplementedError--------------------------尚未实现的方法
OSError------------------------------------------操作系统产生的异常(例如打开一个不存在的文件)
请输入需要打开的文件名:D:\test #D盘没有test这个文件
Traceback (most recent call last):
File "D:/test.py", line 2, in <module>
f = open(file_name)
FileNotFoundError: [Errno 2] No such file or directory: 'D:\\test'
OverflowError-----------------------------------数值运算超出最大限制
ReferenceError----------------------------------弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
RuntimeError------------------------------------一般的运行时错误
StopIteration------------------------------------迭代器没有更多的值
SyntaxError--------------------------------------Python的语法错误
>>> print 'I Love Fishc.com'
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('I Love Fishc.com')?
IndentationError --------------------------------缩进错误
TabError-----------------------------------------Tab和空格混合使用
SystemError-------------------------------------Python编译器系统错误
SystemExit---------------------------------------Python编译器进程被关闭
TypeError----------------------------------------不同类型间的无效操作
>>> 1 + '2'
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
1 + '2'
TypeError: unsupported operand type(s) for +: 'int' and 'str'
UnboundLocalError-----------------------------访问一个未初始化的本地变量(NameError的子类)
UnicodeError------------------------------------Unicode相关的错误(ValueError的子类)
UnicodeEncodeError----------------------------Unicode编码时的错误(UnicodeError的子类)
UnicodeDecodeError----------------------------Unicode解码时的错误(UnicodeError的子类)
UnicodeTranslateError--------------------------Unicode转换时的错误(UnicodeError的子类)
ValueError---------------------------------------传入无效的参数
ZeroDivisionError--------------------------------除数为零
>>> 5 / 0
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
5 / 0
ZeroDivisionError: division by zero
----------------------------------------------------------------------------------------------------------------
第三十三课、
*try-except语句
try:
检测范围
except Exception[as reason]:
出现异常(Exception)后的处理代码
例子1(以下代码在py文件中):
try:
f = open('D:\\我为什么是一个文件.txt') #D盘中并没有该txt文件
print(f.read())
f.close()
except OSError:
print('文件出错啦T_T')
#执行该py文件:
文件出错啦T_T
错误的原因是:[Errno 2] No such file or directory: 'D:\\我为什么是一个文件.txt'
例子2(以下代码在py文件中):
try:
sum = 1 + '1' #注意:try语句执行时发现异常,剩下的代码将不会执行
except TypeError as reason:
print('文件出错啦T_T\n错误的原因是:' + str(reason))
#执行该py文件:
文件出错啦T_T
错误的原因是:unsupported operand type(s) for +: 'int' and 'str'
例子3(以下代码在py文件中):
try:
sum = 1 + '1'
f = open('D:\\我为什么是一个文件.txt')
print(f.read())
f.close()
except (OSError,TypeError): #这样无论是OSError或者TypeError都能捕获到
print('文件出错啦T_T')
#执行该py文件:
文件出错啦T_T
------------------------------------------------------------------------------------------------------------------
*try-finally语句
try:
检测范围
except Exception[as reason]:
出现异常(Exception)后的处理代码
finally:
无论如何都会被执行的代码
例子(以下代码在py文件中):
try:
f = open('D:\\我为什么是个文件.txt','w')
print(f.write('我存在了!'))
sum = 1 + '1' #try会检测到这里出错,如果不加finally,那么写入文件的文字也就无法被保存了
except (OSError,TypeError):
print('出错啦T_T')
finally:
f.close()
-------------------------------------------------------------------------------------------------------------------
*raise语句--------------------------可以自己引发出一个异常
>>> raise #可以直接raise,但一般不这么用
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
raise
RuntimeError: No active exception to reraise
>>> raise ZeroDivisionError #引发'ZeroDivisionError'异常
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
raise ZeroDivisionError
ZeroDivisionError
>>> raise ZeroDivisionError('除数为零的异常') #对异常内容的解释
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
raise ZeroDivisionError('除数为零的异常')
ZeroDivisionError: 除数为零的异常
----------------------------------------------------------------------------------------------------------------------
第三十四课、
*丰富的else语句
while-else-----------------干完了能怎样,干不完就别想怎样
以下代码在py文件中实现:
def showMaxFactor(num):
count = num // 2
while count > 1:
if num % count == 8:
print('%d最大的约数是%d' % (num,count))
break #这里的break会跳过else语句,因为如果将 else 语句与循环语句(while 和 for 语句)进行搭配,那么只有在循环正常执行完成后才会执行 else 语句块的内容
count -= 1
else:
print('%d是素数' % num)
num = int(input('请输入一个整数:'))
showMaxFactor(num)
执行文件:
请输入一个整数:4
4是素数
请输入一个整数:25
25是素数
-----------------------------------------------------------------------------------------------------------------------------------------
try-else-------------------没有问题,那就干吧
(1).以下代码在py文件中实现:
try:
print(int('abc'))
except ValueError as reason:
print('出错啦:' + str(reason))
else:
print('没有任何异常!')
执行文件:
出错啦:invalid literal for int() with base 10: 'abc'
(2).以下代码在py文件中实现:
try:
print(int('123'))
except ValueError as reason:
print('出错啦:' + str(reason))
else:
print('没有任何异常!')
执行文件:
123
没有任何异常!
-----------------------------------------------------------------------------------------------------------------------------------------
*with语句----------------with 语句会自动处理文件的打开和关闭,如果中途出现异常,会执行清理代码,然后确保文件自动关闭
(1)以下代码在py文件中实现:
try:
with open('D:\\data.txt','w') as f: #不用写f.close( ),因为with语句会自动执行
for each_line in f:
print(each_line)
except OSError as reason:
print('出错啦:' + str(reason))
执行文件:
出错啦:not readable
(2)
with A() as a: with A( ) as a,B( ) as b:
with B() as b: = suite
suite
-----------------------------------------------------------------------------------------------------------------------------------------
第三十五课、
*easy-gui超详细中文教程
https://www.cnblogs.com/hcxy2007107708/articles/10091466.html
-----------------------------------------------------------------------------------------------------------------------------------------
*官网:http://easygui.sourceforge.net
-----------------------------------------------------------------------------------------------------------------------------------------
*标准安装方法:
使用命令窗口切换到easygui-docs-0.96的目录下
【Windows下】执行C:\Python33\python.exe setup.py install
【Linux或Mac下】sudo /usr/bin/python33 setup.py install
-----------------------------------------------------------------------------------------------------------------------------------------
*注意:建议不要在 IDLE 上运行 EasyGui
EasyGui 是运行在 Tkinter 上并拥有自身的事件循环,而 IDLE 也是 Tkinter 写的一个应用程序并也拥有自身的事件循环。
因此当两者同时运行的时候,有可能会发生冲突,且带来不可预测的结果。因此如果你发现你的 EasyGui 程序有这样的问题,
请尝试在 IDLE 外去运行你的程序。
-----------------------------------------------------------------------------------------------------------------------------------------
*一个简单的例子:
以下代码在py文件中实现:
import easygui as g
import sys
while 1:
g.msgbox("嗨,欢迎进入第一个界面小游戏")
msg = "请问你希望在鱼C工作室学习到什么知识呢"
title="小游戏互动"
choices=["谈恋爱","编程","OOXX","琴棋书画"]
choice=g.choicebox(msg,title,choices)
#note that we convert choice to string,in case
#the user cancelled the choice,and we got None
g.msgbox("你的选择是:"+str(choice),"结果")
msg="你希望重新开始小游戏吗?"
title=" 请选择"
if g.ccbox(msg,title): #show a Contiue/Cancel dialog
pass #user chose Contonue
else:
sys.exit(0) #user chose Cancel
------------------------------------------------------------------------------------------------------------------------------------------
*EasyGui 的各种功能演示
Windows命令行调用:
C:\Python33\python.exe easygui.py
IDE(例如 IDLE, PythonWin, Wing, 等等)调用:
>>> import easygui as g
>>> g.egdemo()
------------------------------------------------------------------------------------------------------------------------------------------
*导入easy-gui的三种方式
1.
>>> import easygui
>>> easygui.msgbox('嗨,小甲鱼!')
'OK'
2.
>>> from easygui import *
>>> msgbox('嗨,小美女!')
'OK'
3.
>>> import easygui as g
>>> g.msgbox('嗨,CSQ')
'OK'
------------------------------------------------------------------------------------------------------------------------------------------
*使用 EasyGui:
import easygui as g
g.msgbox("Hello, world!")
------------------------------------------------------------------------------------------------------------------------------------------
*EasyGui 函数的默认参数:
绝大部分的 EasyGui 函数都有默认参数,几乎所有的组件都会显示一个消息和标题。标题默认是空字符串,信息通常有一个简单的默认值。
调用 msgbox() 的时候可以只指定一个消息参数:
>>> msgbox('我爱小甲鱼^_^')
也可以指定标题参数和消息参数:
>>> msgbox('我爱小甲鱼^_^', '鱼油心声')
*使用关键字参数调用 EasyGui 的函数
以下代码在py文件中实现:
import easygui as g
choices = ['愿意','不愿意','有钱的时候愿意']
reply = g.choicebox('你愿意购买资源打包支持小甲鱼吗?',choices = choices)
------------------------------------------------------------------------------------------------------------------------------------------
*使用按钮组件
1.msgbox()
msgbox(msg='(Your message goes here)', title=' ', ok_button='OK', image=None, root=None)
msgbox() 显示一个消息和提供一个"OK"按钮,你可以指定任意的消息和标题,你甚至可以重写"OK"按钮的内容。
>>>import easygui as g
>>>g.msgbox("我一定要学会编程!", ok_button="加油!")
2.ccbox()
ccbox(msg='Shall I continue?', title=' ', choices=('C[o]ntinue', 'C[a]ncel'), image=None, default_choice='C[o]ntinue', cancel_choice='C[a]ncel')
ccbox() 提供一个选择:“C[o]ntinue” 或者 “C[a]ncel”,并相应的返回 True 或者 False。
注意:“C[o]ntinue” 中的 [o] 表示快捷键,也就是说当用户在键盘上敲一下 o 字符,就相当于点击了 “C[o]ntinue” 按键。
以下代码在py文件中实现:
import easygui as g
import sys
if ccbox('要再来一次吗?', choices=('要啊要啊^_^', '算了吧T_T')):
msgbox('不给玩了,再玩就玩坏了......')
else:
sys.exit(0)
3.ynbox()
ynbox(msg='Shall I continue?', title=' ', choices=('Yes', 'No'), image=None)
同ccbox()
4.buttonbox()
buttonbox(msg='', title=' ', choices=('Button[1]', 'Button[2]', 'Button[3]'), image=None, images=None, default_choice=None, cancel_choice=None, callback=None, run=True)
可以使用 buttonbox() 定义自己的一组按钮,buttonbox() 会显示一组由你自定义的按钮。
当用户点击任意一个按钮的时候,buttonbox() 返回按钮的文本内容。如果用户点击取消或者关闭窗口,那么会返回默认选项(第一个选项)。
>>>import easygui as g
>>>g.buttonbox('你喜欢以下哪种水果?','随便写',choices = ('草莓','西瓜','芒果'))
5.indexbox()
indexbox(msg='Shall I continue?', title=' ', choices=('Yes', 'No'), image=None, default_choice='Yes', cancel_choice='No')
基本跟 buttonbox() 一样,区别就是当用户选择第一个按钮的时候返回序号 0, 选择第二个按钮的时候返回序号 1。
6.boolbox()
boolbox(msg='Shall I continue?', title=' ', choices=('[Y]es', '[N]o'), image=None, default_choice='Yes', cancel_choice='No')
如果第一个按钮被选中则返回 True,否则返回 False。
------------------------------------------------------------------------------------------------------------------------------------------
*如何在 buttonbox 里边显示图片
当你调用一个 buttonbox 函数(例如 msgbox(), ynbox(), indexbox() 等等)的时候,你还可以为关键字参数 image 赋值,可以设置一个
.gif 格式的图像(PNG 格式的图像也是支持的哦^_^)
>>>buttonbox('大家说我长得帅吗?', image='turtle.gif', choices=('帅', '不帅', '!@#$%'))
------------------------------------------------------------------------------------------------------------------------------------------
*为用户提供一系列选项
1.choicebox()
choicebox() 为用户提供了一个可选择的列表,使用序列(元祖或列表)作为选项,这些选项会按照字母进行排序
choicebox(msg='Pick an item', title='', choices=[], preselect=0, callback=None, run=True)
>>>choicebox('请选择要进入的文件夹','搜索结果',choices = ['D:\\应用MAX','D:\\电视剧','D:\\虚拟定位'])
2.multchoicebox()
multchoicebox() 函数也是提供一个可选择的列表,与 choicebox() 不同的是,multchoicebox() 支持用户选择 0 个,1 个或者同时选择多个选项
multchoicebox() 函数也是使用序列(元祖或列表)作为选项,这些选项显示前会按照不区分大小写的方法排好序
multchoicebox(msg='Pick an item', title='', choices=[], preselect=0, callback=None, run=True)
>>> multchoicebox('请选择要进入的文件夹','搜索结果',choices = ['D:\\应用MAX','D:\\电视剧','D:\\虚拟定位'])
------------------------------------------------------------------------------------------------------------------------------------------
*让用户输入消息
1.enterbox()
enterbox() 为用户提供一个最简单的输入框,返回值为用户输入的字符串
默认返回的值会自动去除首尾的空格,如果需要保留首尾空格的话请设置参数 strip=False
enterbox(msg='Enter something.', title=' ', default='', strip=True, image=None, root=None)
>>>enterbox('请输入一句你最想对小甲鱼说的话','真心话')
2.integerbox()
integerbox() 为用户提供一个简单的输入框,用户只能输入范围内(lowerbound 参数设置最小值,upperbound 参数设置最大值)的整型数值,否则会要求用户重新输入
integerbox(msg='', title=' ', default=None, lowerbound=0, upperbound=99, image=None, root=None)
>>>integerbox('猜猜我现在想的数字是几?',lowerbound = 1,upperbound = 10)
3.multenterbox()
multenterbox() 为用户提供多个简单的输入框,要注意以下几点:
#如果用户输入的值比选项少的话,则返回列表中的值用空字符串填充用户为输入的选项。
#如果用户输入的值比选项多的话,则返回的列表中的值将截断为选项的数量。
#如果用户取消操作,则返回域中的列表的值或者 None 值。
multenterbox(msg='Fill in values for the fields.', title=' ', fields=[], values=[], callback=None, run=True)
>>> multenterbox('【*真实姓名】为必填项。','账号中心',fields=['用户名','*真实姓名','固定电话'],values=[])
--------------------------------------------------------------------------------------------------------------------------------------------
*让用户输入密码
有时候可能需要让用户输入密码等敏感信息,那么界面看上去应该是这样的:*******
1.passwordbox()
passwordbox() 跟 enterbox() 样式一样,不同的是用户输入的内容用星号(*)显示出来,该函数返回用户输入的字符串
passwordbox(msg='Enter your password.', title=' ', default='', image=None, root=None)
>>>passwordbox('请输入您的密码')
2.multpasswordbox()
multpasswordbox() 跟 multenterbox() 使用相同的接口,但当它显示的时候,最后一个输入框显示为密码的形式(*)
multpasswordbox(msg='Fill in values for the fields.', title=' ', fields=(), values=(), callback=None, run=True)
>>>multpasswordbox('请输入用户名和密码:','登录',fields=['用户名:','密码:'],values=[])
--------------------------------------------------------------------------------------------------------------------------------------------
*显示文本
1. textbox()
textbox() 函数默认会以比例字体(参数 codebox=True 设置为等宽字体)来显示文本内容(自动换行),这个函数适合用于显示一般的书面文字
注:text 参数设置可编辑文本区域的内容,可以是字符串、列表或者元祖类型
textbox(msg='', title=' ', text='', codebox=False, callback=None, run=True)
>>>textbox('文件【record.txt】的内容如下:','显示文件内容',codebox = True,text = '文本内容')
2.codebox()
codebox() 以等宽字体显示文本内容(不自动换行),相当于 textbox(codebox=True)
codebox(msg='', title=' ', text='')
>>>codebox('文件【record.txt】内容如下:','显示文本内容',text = '文本内容'
--------------------------------------------------------------------------------------------------------------------------------------------
*目录与文件
GUI 编程中一个常见的场景是要求用户输入目录及文件名,EasyGUI 提供了一些基本函数让用户来浏览文件系统,选择一个目录或文件
1.diropenbox()
diropenbox() 函数用于提供一个对话框,返回用户选择的目录名(带完整路径哦),如果用户选择 “Cancel” 则返回 None
default 参数用于设置默认的打开目录(请确保设置的目录已存在)
diropenbox(msg=None, title=None, default=None)
>>>diropenbox('请选择一个文件夹','浏览文件夹',default = 'D:\\')
2. fileopenbox()
fileopenbox() 函数用于提供一个对话框,返回用户选择的文件名(带完整路径哦),如果用户选择 “Cancel” 则返回 None
(1)关于 default 参数的设置方法:
#default 参数指定一个默认路径,通常包含一个或多个通配符。
#如果设置了 default 参数,fileopenbox() 显示默认的文件路径和格式。
#default 默认的参数是 '*',即匹配所有格式的文件。
(2)关于 filetypes 参数的设置方法:
#可以是包含文件掩码的字符串列表,例如:filetypes = ["*.txt"]
#可以是字符串列表,列表的最后一项字符串是文件类型的描述,例如:filetypes = ["*.css", ["*.htm", "*.html", "HTML files"]]
(3)multiple 参数,如果为 True 则表示可以同时选择多个文件。
fileopenbox(msg=None, title=None, default='*', filetypes=None, multiple=False)
>>>fileopenbox('请选择一个文件','浏览文件',default = 'D:\\',filetypes = ['*.txt'])
3.filesavebox()
filesavebox() 函数提供一个对话框,让用于选择文件需要保存的路径(带完整路径哦),如果用户选择 “Cancel” 则返回 None
default 参数应该包含一个文件名(例如当前需要保存的文件名),当然也可以设置为空的,或者包含一个文件格式掩码的通配符
filetypes 参数的设置方法请参考 fileopenbox() 函数
filesavebox(msg=None, title=None, default='', filetypes=None)
>>>filesavebox('请选择要保存的文件','另存为',default = 'D:\\test.txt',filetypes = '*.txt')
----------------------------------------------------------------------------------------------------------------------------------------------
*记住用户的设置
1.EgStore
GUI 编程中一个常见的场景就是要求用户设置一下参数,然后保存下来,以便下次用户使用你的程序的时候可以记住他的设置。
为了实现对用户的设置进行存储和恢复这一过程,EasyGUI 提供了一个叫做 EgStore 的类。
为了记住某些设置,你的应用程序必须定义一个类(下面案例中的 “Settings”)继承自 EgStore 类。
然后你的应用程序必须创建一个该类的实例化对象(下面案例中的 “settings”)。
设置类的构造函数(__init__ 方法)必须初始化所有的你想要它所记住的那些值。
一旦你这样做了,你就可以在 settings 对象中通过设定值去实例化变量,从而很简单地记住设置。
之后使用 settings.store() 方法在硬盘上持久化保存。
下面创建一个叫做 “Settings” 的类:
from easygui import EgStore
# 定义一个叫做“Settings”的类,继承自EgStore类
class Settings(EgStore):
def __init__(self, filename): # 需要指定文件名
# 指定要记住的属性名称
self.author = ""
self.book = ""
# 必须执行下面两个语句
self.filename = filename
self.restore()
# 创建“Settings”的实例化对象“settings”
settingsFilename = "settings.txt"
settings = Settings(settingsFilename)
author = "小甲鱼"
book = "《零基础入门学习Pyhon》"
# 将上面两个变量的值保存到“settings”对象中
settings.author = author
settings.book = book
settings.store()
print("\n保存完毕\n")
-------------------------------------------------------------------------------------------------------------------------------------------------------
*捕获异常
exceptionbox()
使用 EasyGUI 编写 GUI 程序,有时候难免会产生异常。当然这取决于你如何运行你的应用程序,当你的应用程序崩溃的时候,堆栈追踪可能会被抛出,或者被写入到 stdout 标准输出函数中。
EasyGUI 通过 exceptionbox() 函数提供了更好的方式去处理异常。
当异常出现的时候,exceptionbox() 会将堆栈追踪显示在一个 codebox() 中,并且允许你做进一步的处理。
exceptionbox() 很容易使用,下面举个例子:
try:
print('I Love FishC.com!')
int('FISHC') # 这里会产生异常
except:
exceptionbox()
-------------------------------------------------------------------------------------------------------------------------------------------------------
第三十六课、
*对象------------------对象 = 属性(变量) + 方法(函数)
类,类对象,实例对象:
我们常说的类指的是类定义,由于“Python无处不对象”,所以当类定义完之后,自然就是类对象。在这个时候,你可以对类的属性(变量)进行直接访问(MyClass.name)
一个类可以实例化出无数的对象(实例对象),Python 为了区分是哪个实例对象调用了方法,于是要求方法必须绑定(通过 self 参数)才能调用。
而未实例化的类对象直接调用方法,因为缺少 self 参数,所以就会报错
--------------------------------------------------------------------------------------------------------------------------------------------------------
类:
例子:以下代码在py文件中实现
class Turtle: #Python中的类名约定以大写字母开头
'''关于类的一个简单例子'''
#属性
color = 'green'
weight = 10
legs = 4
shell = True
mouth = '大嘴'
#方法
def climb(self):
print('我正在努力的向前爬。。。')
def run(self):
print('我正在飞快的向前跑。。。')
def bite(self):
print('咬死你咬死你!!!')
def eat(self):
print('有的吃,真满足!')
def sleep(self):
print('困了,睡了,晚安!')
类的实例化:
>>> t = Turtle()
>>> type(t)
<class '__main__.Turtle'>
>>> t.climb()
我正在努力的向前爬。。。
>>> t.bite()
咬死你咬死你!!!
>>> t.sleep()
困了,睡了,晚安!
--------------------------------------------------------------------------------------------------------------------------------------------------------
*类和对象的关系:就如同模具和用这个模具制作出的物品之间的关系。一个类为它的全部对象给出了一个统一的定义,
而他的每个对象则是符合这种定义的一个实体,因此类和对象的关系就是抽象和具体的关系。
--------------------------------------------------------------------------------------------------------------------------------------------------------
*OO = Object Oriented(面向对象)的特征
1.封装:将一系列方法集合起来,可以直接调用方法不必知道方法的具体实现
2.继承:子类自动共享父类之间数据和方法的机制
例子:
>>> class My_list(list):
pass
>>> list2 = My_list()
>>> list2.append(5)
>>> list2.append(2)
>>> list2.append(7)
>>> list2
[5, 2, 7]
3.多态:不同对象对同一方法响应不同的行动
例子:
>>> class A:
def fun(self):
print('我是小A...')
>>> class B:
def fun(self):
print('我是小B...')
>>> a = A()
>>> b = B()
>>> a.fun()
我是小A...
>>> b.fun()
我是小B...
---------------------------------------------------------------------------------------------------------------------------------------------------------
第三十七课、
*self是什么?
self的作用:绑定方法,有了self,python可以分清是哪个对象在调用方法,可以认为方法中的 self 其实就是实例对象的唯一标志。
例子:
>>> class Ball:
def setName(self,name):
self.name = name
def kick(self):
print('我叫%s,该死的,谁踢我...'% self.name)
>>> a = Ball()
>>> a.setName('球A')
>>> b = Ball()
>>> b.setName('球B')
>>> c = Ball()
>>> c.setName('土豆')
>>> a.kick()
我叫球A,该死的,谁踢我...
>>> c.kick()
我叫土豆,该死的,谁踢我...
---------------------------------------------------------------------------------------------------------------------------------------------------------
*__init__(self,parm1,parm2,...)------构造方法
__init__方法会在类实例化时被自动调用,我们称之为魔法方法。你可以重写这个方法,为对象定制初始化方案
例子:
>>> class Ball:
def __init__(self,name):
self.name = name
def kick(self):
print('我叫%s,该死的,谁踢我...' % self.name)
>>> b = Ball('土豆')
>>> b.kick()
我叫土豆,该死的,谁踢我...
>>> c = Ball() #这里需要传入一个参数,否则就会报错
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
c = Ball()
TypeError: __init__() missing 1 required positional argument: 'name'
---------------------------------------------------------------------------------------------------------------------------------------------------------
*公有和私有
在python中定义私有变量只需要在变量名或函数名前加上'_ _'两个下划线,那么这个函数或变量就会称为私有的了
例子:
>>> class Person:
name = '小甲鱼'
>>> p = Person()
>>> p.name #正常增加属性,可以在外部调用该变量
'小甲鱼'
------------------------------------------------
>>> class Person:
__name = '小甲鱼'
>>> p = Person()
>>> p.__name #将变量变为私有,在外部就访问不了了
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
p.__name
AttributeError: 'Person' object has no attribute '__name'
>>> p.name
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
p.name
AttributeError: 'Person' object has no attribute 'name'
-----------------------------------------------
>>> class Person:
__name = '小甲鱼'
def getName(self): #getName方法称之为“访问器”。Python事实上是采用一种叫“name mangling”技术
return self.__name
>>> p = Person()
>>> p.getName() #需要在定义的类中加入方法才能从内部访问到私有变量
'小甲鱼'
----------------------------------------------
>>> class Person:
__name = '小甲鱼'
>>> p = Person()
>>> p._Person__name #可以通过'_类名_ _变量名'访问私有变量
'小甲鱼'
------------------------------------------------------------------------------------------------------------------------------------------------------------
第三十八课、
*继承---class DerivedClassName(BaseClassName):
例子:
>>> class Parent:
def hello(self):
print('正在调用父类的方法...')
>>> class Child(Parent):
pass
>>> p = Parent()
>>> p.hello()
正在调用父类的方法...
>>> c = Child()
>>> c.hello()
正在调用父类的方法...
---------------------------------------------------------
>>> class Child(Parent):
def hello(self):
print('正在调用子类的方法...')
>>> c = Child()
>>> c.hello() #如果在子类中定义了与父类一样的方法,会返回子类的方法
正在调用子类的方法...
-------------------------------------------------------------------------------------------------------------------------------------------------------------
*调用未绑定的父类方法
import random as r
class Fish:
def __init__(self):
self.x = r.randint(0,10)
self.y = r.randint(0,10)
def move(self):
self.x -= 1
print('我的位置是:',self.x,self.y)
class Shark(Fish):
def __init__(self):
Fish.__init__(self) #这里的self是子类shark的实例对象
self.hungry = True
def eat(self):
if self.hungry:
print('吃货的梦想就是天天有吃的...')
self.hungry = False
else:
print('太撑了,吃不下了!')
>>> shark = Shark()
>>> shark.move()
我的位置是: 9 8
>>> Fish.__init__(shark) #也可以直接这样用
>>> shark.move()
我的位置是: 3 8
---------------------------------------------------------------------------------------------------------------------------------------------------------------
*super方法
import random as r
class Fish:
def __init__(self):
self.x = r.randint(0,10)
self.y = r.randint(0,10)
def move(self):
self.x -= 1
print('我的位置是:',self.x,self.y)
class Shark(Fish):
def __init__(self):
super().__init__() #使用super()函数不用给定父类的名字,只需要‘class Shark()’括号里是父类就行
self.hungry = True
def eat(self):
if self.hungry:
print('吃货的梦想就是天天有吃的...')
self.hungry = False
else:
print('太撑了,吃不下了!')
>>> shark = Shark()
>>> shark.move()
我的位置是: 6 2
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
*多重继承
>>> class Base1:
def foo1(self):
print('我是foo1,我为Base1代言...')
>>> class Base2:
def foo2(self):
print('我是foo2,我为Base2代言...')
>>> class C(Base1,Base2):
pass
>>> c = C()
>>> c.foo1()
我是foo1,我为Base1代言...
>>> c.foo2()
我是foo2,我为Base2代言...
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
第三十九课、
*组合---在类定义中把需要的类放进去实例化
例子:
以下代码在py文件中实现
class Turtle:
def __init__(self,x):
self.num = x
class Fish:
def __init__(self,x):
self.num = x
class Pool:
def __init__(self,x,y):
self.turtle = Turtle(x)
self.fish = Fish(y)
def print_num(self):
print('水池里总共有乌龟%d只,鱼%d条!' % (self.turtle.num,self.fish.num)
>>> pool = Pool(5,10)
>>> pool.print_num()
水池里总共有乌龟5只,鱼10条!
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
*类,类对象和实例对象
| ---a
C(类定义)---C*(类对象)---实例对象-- | ---b
| ---c
>>> class C:
count = 0
>>> a = C()
>>> b = C()
>>> a.count
0
>>> b.count
0
>>> a.count += 10
>>> a.count
10
>>> b.count
0
>>> C.count += 100
>>> a.count
10
>>> b.count
100
------------------------------------------------------------
如果属性和方法相同:
>>> class C:
def x(self):
print('X-man!')
>>> c = C()
>>> c.x()
X-man!
>>> c.x = 1 #实例对象c增加的一个属性x与类对象C的方法x()名字相同,属性会覆盖方法
>>> c.x()
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
c.x()
TypeError: 'int' object is not callable
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
*绑定
Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念
>>> class BB:
def print_BB():
print('no zuo no die')
>>> BB.print_BB()
no zuo no die
>>> bb = BB()
>>> bb.print_BB() #需要在定义类的时候加入self参数才能被实例对象调用
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
bb.print_BB()
TypeError: print_BB() takes 0 positional arguments but 1 was given
-------------------------------------------------------------------------
*删除类对象后实例对象的状态:
>>> class CC:
def setXY(self,x,y):
self.x = x
self.y = y
def printXY(self):
print(self.x,self.y)
>>> cc = CC()
>>> cc.__dict__
{}
>>> CC.__dict__
mappingproxy({'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000025643D24CA0>,
'printXY': <function CC.printXY at 0x0000025643D24EE0>, '__dict__': <attribute '__dict__' of 'CC' objects>,
'__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None})
>>> cc.setXY(4,5)
>>> cc.__dict__
{'x': 4, 'y': 5}
>>> CC.__dict__
mappingproxy({'__module__': '__main__', 'setXY': <function CC.setXY at 0x0000025643D24CA0>,
'printXY': <function CC.printXY at 0x0000025643D24EE0>, '__dict__': <attribute '__dict__' of 'CC' objects>,
'__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None})
>>> del CC
>>> cc.printXY() #删除类对象CC后实例对象cc仍然可以调用CC的方法
4 5
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
第四十课、
*类与对象相关的BIF
1.issubclass(class,classinfo)---检查一个类是否是另一个类的子类
class是子类,classinfo是父类
(1)一个类被认为是其自身的子类
(2)classinfo 可以是类对象组成的元祖,只要 class 与其中任何一个候选类的子类,则返回 True
(3)在其他情况下,会抛出一个 TypeError 异常
例子:
>>> class A:
pass
>>> class B(A):
pass
>>> issubclass(B,A)
True
>>> issubclass(B,B)
True
>>> issubclass(A,A)
True
>>> issubclass(B,object) #object是所有类的基类
True
>>> class C:
pass
>>> issubclass(B,(A,C))
True
------------------------------------------------------------------------------------------------
2.isinstance(object,classinfo)---检查一个实例对象是否属于一个类
object是实例对象,classinfo是一个类对象
(1)如果 objec t是 classinfo 的子类的一个实例,也符合条件
(2)如果第一个参数不是对象,则永远返回False
(3)classinfo 可以是类对象组成的元祖,只要class与其中任何一个候选类的子类,则返回 True
(4)如果第二个参数不是类或者由类对象组成的元祖,会抛出一个 TypeError 异常
例子:
>>> class A:
pass
>>> class B(A):
pass
>>> class C:
pass
>>> b1 = B()
>>> isinstance(b1,B)
True
>>> isinstance(b1,A) #这里因为B是A的子类,所以b1也是A的实例对象
True
>>> isinstance(b1,C)
False
>>> isinstance(b1,(A,B,C))
True
------------------------------------------------------------------------------------------------
3.hasattr(object,name)---测试一个对象里面是否有指定的属性
object是对象,name是属性名
(1).参数name要用‘’括起来:‘name’
例子:
>>> class C:
def __init__(self,x=0):
self.x = x
>>> c1 = C()
>>> hasattr(c1,'x')
True
------------------------------------------------------------------------------------------------
4.getattr(object,name[,default])---返回对象指定的属性值,如果指定的属性不存在且设定了default,则会打印default参数,否则抛出AttributeError异常
例子:
>>> class C:
def __init__(self,x=0):
self.x = x
>>> getattr(c1,'x')
0
>>> getattr(c1,'y')
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
getattr(c1,'y')
AttributeError: 'C' object has no attribute 'y'
>>> getattr(c1,'y','您所访问的属性不存在...')
'您所访问的属性不存在...'
------------------------------------------------------------------------------------------------
5.setattr(object,name,value)---设置对象中指定属性的值,如果指定的属性不存在,则会新建该属性
例子:
>>> class C:
def __init__(self,x=0):
self.x = x
>>> getattr(c1,'y','您所访问的属性不存在...')
'您所访问的属性不存在...'
>>> setattr(c1,'y','FishC')
>>> getattr(c1,'y')
'FishC'
------------------------------------------------------------------------------------------------
6.delattr(object,name)---删除对象中指定的属性,如果该属性不存在,则抛出AttributeError异常
例子:
>>> class C:
def __init__(self,x=0):
self.x = x
>>> delattr(c1,'y')
>>> delattr(c1,'z')
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
delattr(c1,'z')
AttributeError: z
-------------------------------------------------------------------------------------------------
7.property(fget=None, fset=None, fdel=None, doc=None)---设置一个属性,该属性包含定义类时的各种方法
(1).fget是获取属性的方法,
(2).fset是设置属性的方法,
(3).fdel是删除属性的方法.
例子:
>>> class C:
def __init__(self,size=10):
self.size = size
def getSize(self):
return self.size
def setSize(self,value):
self.size = value
def delSize(self):
del self.size
x = property(getSize,setSize,delSize)
>>> c1 = C()
>>> c1.getSize()
10
>>> c1.x
10
>>> c1.x = 18
>>> c1.x
18
>>> c1.delSize()
>>> c1.x
Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
c1.x
File "<pyshell#49>", line 5, in getSize
return self.size
AttributeError: 'C' object has no attribute 'size'
------------------------------------------------------
*函数修饰符@
作用:为现有函数增加额外的功能,常用于插入日志、性能测试、事务处理等等
创建函数修饰符的规则:
(1)修饰符是一个函数
(2)修饰符取被修饰函数为参数
(3)修饰符返回一个新函数
(4)修饰符维护被维护函数的签名
例子:
def log(func):
def wrapper():
print('log开始 ...')
func()
print('log结束 ...')
return wrapper
@log
def test():
print('test ..')
test()
----------------------------------------------------
*Python内置的修饰符
@staticmethod:把类中定义的实例方法变成静态方法
@classmethod:把类中定义的实例方法变成类方法
@property:把类中定义的实例方法变成类属性
----------------------------------------------------
*实例方法,类方法,静态方法
实例方法:
定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
调用:只能由实例对象调用。
类方法:
定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
调用:类和实例对象都可以调用。
class CodeB:
@classmethod
def fool(cls):
print('调用类方法foo()')
静态方法:
定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
调用:类和实例对象都可以调用。
class CodeA:
@staticmethod
def foo():
print('调用静态方法foo()')
--------------------------------------------------------------------------------------------------------------------------------------------------------
第四十一课、
*__init__(self[, ...])---构造方法
(1)当我们的实例对象需要有明确的初始化步骤的时候,你可以在 __init__ 方法中部署初始化的代码
(2)--我们定义一个矩形类,需要长和宽两个参数,拥有计算周长和面积两个方法。
--我们需要对象在初始化的时候拥有“长”和“宽”两个参数,因此我们需要重写__init__方法
--因为我们说过,__init__方法是类在实例化成对象的时候首先会调用的一个方法
例子:
>>> class Rectangle:
def __init__(self,x,y):
self.x = x #这里的self.x是实例对象的局部变量,x是传入的参数
self.y = y
def getPeri(self):
return (self.x + self.y) * 2
def getArea(self):
return self.x * self.y
>>> rect = Rectangle(3,4)
>>> rect.getPeri()
14
>>> rect.getArea()
12
-------------------------------------------------------------
*__new__(cls[, ...])---用作初始化一个继承自不可变类型的类对象(也是构造方法)
(1)__new__ 是在一个对象实例化的时候所调用的第一个方法。它跟其他魔法方法不同,它的第一个参数不是 self 而是这个类(cls),而其他的参数会直接传递给 __init__ 方法的
(2)__new__ 方法主要任务时返回一个实例对象,通常是参数 cls 这个类的实例化对象
例子:
>>> class CapStr(str):
def __new__(cls,string): #这里不能用__init__()方法,因为是继承自str,不可改变的字符串
string = string.upper()
return str.__new__(cls,string)
>>> a = CapStr('I Love FishC.com!')
>>> a
'I LOVE FISHC.COM!'
--------------------------------------------------------------
*__del__(self)---析构方法
例子:
>>> class C:
def __init__(self):
print(1)
def __del__(self):
print(2)
>>> c1 = C()
1
>>> c2 = c1
>>> c3 = c2
>>> del c3
>>> del c2
>>> del c1 #当c3,c2,c1都被del的时候才会触发垃圾回收机制
2
-----------------------------------------------------------------------------------------------------------------------------------------------------------
第四十二课、
*工厂函数(int,float,long,bool,str,tuple,list.......等等都是)
#工厂函数看上去有点像函数,实质上他们是类,当你调用它们时,实际上是生成了该类型的一个实例
>>> type(len)
<class 'builtin_function_or_method'>
>>> type(int)
<class 'type'>
>>> class C:
pass
>>> type(C)
<class 'type'>
-------------------------------------------------------------------
>>> a = int('123') #a是int的实例对象
>>> b = int('456')
对象之间可以计算
>>> a + b
579
------------------------------------------------------------------
*魔法方法提供了让你自定义对象的数值处理
#通过对魔法方法的重写,可以自定义任何对象之间的数值运算
魔法方法的算数运算符:
__add__(self, other)------------------定义加法的行为:+
例子:
>>> class new_int(int):
def __add__(self,other):
return int.__sub__(self,other)
def __sub__(self,other):
return int.__add__(self,other)
>>> a = new_int(3)
>>> b = new_int(5)
>>> a + b
-2
>>> a - b
8
__sub__(self, other)------------------定义减法的行为:-
__mul__(self, other)------------------定义乘法的行为:*
__truediv__(self, other)---------------定义真除法的行为:/
__floordiv__(self, other)--------------定义整数除法的行为://
__mod__(self, other)-----------------定义取模算法的行为:%
__divmod__(self, other)--------------定义当被 divmod() 调用时的行为
#divmod(a,b)用法:a//b 得1余2,返回(1,2)元组
>>> divmod(5,3)
(1, 2)
__pow__(self, other[, modulo]) ------定义当被 power() 调用或 ** 运算时的行为
__lshift__(self, other)-----------------定义按位左移位的行为:<<
__rshift__(self, other)-----------------定义按位右移位的行为:>>
__and__(self, other)-------------------定义按位与操作的行为:&
__xor__(self, other)--------------------定义按位异或操作的行为:^
__or__(self, other)---------------------定义按位或操作的行为:|
---------------------------------------------------------------------------------------------------------------------------------------------------
第四十三课、
*基本的魔法方法
----------------------1. __new__ 是在一个对象实例化的时候所调用的第一个方法
----------------------2. 它的第一个参数是这个类,其他的参数是用来直接传递给 __init__ 方法
__new__(cls[, ...])----------------------3. __new__ 决定是否要使用该 __init__ 方法,因为 __new__ 可以调用其他类的
构造方法或者直接返回别的实例对象来作为本类的实例,如果 __new__ 没有返回实例对象,则 __init__ 不会被调用
----------------------4. __new__ 主要是用于继承一个不可变的类型比如一个 tuple 或者 string
__init__(self[, ...])-----------------------构造器,当一个实例被创建的时候调用的初始化方法
__del__(self)----------------------------析构器,当一个实例被销毁的时候调用的方法
__call__(self[, args...])------------------允许一个类的实例像函数一样被调用:x(a, b) 调用 x.__call__(a, b)
__len__(self)----------------------------定义当被 len() 调用时的行为
__repr__(self)--------------------------定义当被 repr() 调用时的行为
__str__(self)----------------------------定义当被 str() 调用时的行为
__bytes__(self)-------------------------定义当被 bytes() 调用时的行为
__hash__(self)-------------------------定义当被 hash() 调用时的行为
__bool__(self)--------------------------定义当被 bool() 调用时的行为,应该返回 True 或 False
__format__(self, format_spec)---------定义当被 format() 调用时的行为
---------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的比较操作符
__lt__(self, other)--------------------定义小于号的行为:x < y 调用 x.__lt__(y)
__le__(self, other)-------------------定义小于等于号的行为:x <= y 调用 x.__le__(y)
__eq__(self, other)------------------定义等于号的行为:x == y 调用 x.__eq__(y)
__ne__(self, other)------------------定义不等号的行为:x != y 调用 x.__ne__(y)
__gt__(self, other)-------------------定义大于号的行为:x > y 调用 x.__gt__(y)
__ge__(self, other)------------------定义大于等于号的行为:x >= y 调用 x.__ge__(y)
---------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的有关属性
__getattr__(self, name)-------------定义当用户试图获取一个不存在的属性时的行为
__getattribute__(self, name)--------定义当该类的属性被访问时的行为
__setattr__(self, name, value)-------定义当一个属性被设置时的行为
__delattr__(self, name)--------------定义当一个属性被删除时的行为
__dir__(self)-------------------------定义当 dir() 被调用时的行为
__get__(self, instance, owner)------定义当描述符的值被取得时的行为
__set__(self, instance, value)--------定义当描述符的值被改变时的行为
__delete__(self, instance)-----------定义当描述符的值被删除时的行为
---------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的反运算
__radd__(self, other)-----------------(与上方相同,当左操作数不支持相应的操作时被调用)
例子:
>>> class Nint(int):
def __radd__(self,other):
return int.__sub__(self,other)
>>> a = Nint(5)
>>> b = Nint(3)
>>> a + b
8
>>> 1 + b #这里因为1找不到它的__add__()方法,所以b执行了它的__radd__()方法
2
__rsub__(self, other)-----------------(与上方相同,当左操作数不支持相应的操作时被调用)
例子:
>>> class Nint(int):
def __rsub__(self,other):
return int.__sub__(self,other)
>>> a = Nint(5)
>>> 3 - a #这里因为3找不到它的__sub__()方法,所以self是a,other是3
2
__rmul__(self, other)-----------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rtruediv__(self, other)-------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rfloordiv__(self, other)-------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rmod__(self, other)----------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rdivmod__(self, other)-------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rpow__(self, other)----------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rlshift__(self, other)---------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rrshift__(self, other)---------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rand__(self, other)----------------(与上方相同,当左操作数不支持相应的操作时被调用)
__rxor__(self, other)-----------------(与上方相同,当左操作数不支持相应的操作时被调用)
__ror__(self, other)------------------(与上方相同,当左操作数不支持相应的操作时被调用)
-------------------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的增量赋值运算
__iadd__(self, other)----------------定义赋值加法的行为:+=
__isub__(self, other)----------------定义赋值减法的行为:-=
__imul__(self, other)----------------定义赋值乘法的行为:*=
__itruediv__(self, other)------------定义赋值真除法的行为:/=
__ifloordiv__(self, other)------------定义赋值整数除法的行为://=
__imod__(self, other)---------------定义赋值取模算法的行为:%=
__ipow__(self, other[, modulo])----定义赋值幂运算的行为:**=
__ilshift__(self, other)---------------定义赋值按位左移位的行为:<<=
__irshift__(self, other)--------------定义赋值按位右移位的行为:>>=
__iand__(self, other)----------------定义赋值按位与操作的行为:&=
__ixor__(self, other)----------------定义赋值按位异或操作的行为:^=
__ior__(self, other)-----------------定义赋值按位或操作的行为:|=
--------------------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的一元操作符
__pos__(self)-----------------------定义正号的行为:+x
__neg__(self)-----------------------定义负号的行为:-x
__abs__(self)-----------------------定义当被 abs() 调用时的行为(取绝对值)
__invert__(self)---------------------定义按位求反的行为:~x(按位取反,0的变成1,1的变成0)
--------------------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的类型转换
__complex__(self)------------------定义当被 complex() 调用时的行为(需要返回恰当的值)
__int__(self)------------------------定义当被 int() 调用时的行为(需要返回恰当的值)
__float__(self)----------------------定义当被 float() 调用时的行为(需要返回恰当的值)
__round__(self[, n])----------------定义当被 round() 调用时的行为(需要返回恰当的值)
--------------------- 1. 当对象是被应用在切片表达式中时,实现整形强制转换
__index__(self)--------------------- 2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 __index__
--------------------- 3. 如果 __index__ 被定义,则 __int__ 也需要被定义,且返回相同的值
--------------------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的上下文管理
__enter__(self)---------------------------------------------1. 定义当使用 with 语句时的初始化行为
---------------------------------------------2. __enter__ 的返回值被 with 语句的目标或者 as 后的名字绑定
__exit__(self, exc_type, exc_value, traceback)-------------1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么
-------------2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作
--------------------------------------------------------------------------------------------------------------------------------------------------------------
*魔法方法的容器类型
__len__(self)-------------------------定义当被 len() 调用时的行为(返回容器中元素的个数)
__getitem__(self, key)---------------定义获取容器中指定元素的行为,相当于 self[key]
__setitem__(self, key, value)--------定义设置容器中指定元素的行为,相当于 self[key] = value
__delitem__(self, key)---------------定义删除容器中指定元素的行为,相当于 del self[key]
__iter__(self)-------------------------定义当迭代容器中的元素的行为
__reversed__(self)-------------------定义当被 reversed() 调用时的行为
__contains__(self, item)-------------定义当使用成员测试运算符(in 或 not in)时的行为
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
*在继承的类中调用基类的方法
>>> class A:
def getst(self):
return 111
>>> class B(A):
def getnum(self):
self.x = super(B,self).getst()
return self.x + 1
>>> b = B()
>>> b.getnum()
112
------------------------------------------------------------------------------------------------
*当要继承的基类是动态的(有时候是 A,有时候是 B)
>>> class A:
def getst(self):
return 111
>>> a = A
>>> class B(A):
def getnum(self):
self.x = a.getst(self)
return self.x + 1
>>> b = B()
>>> b.getnum()
112
>>> b.getst()
111
------------------------------------------------------------------------------------------------
*类的静态属性
#在类中直接定义的变量(没有 self.)就是静态属性。引用类的静态属性使用”类名.属性名”的形式
>>> class C:
count = 0 #静态属性
def __init__(self):
C.count += 1 #类名.属性名的形式引用
def getCount(self):
return C.count
------------------------------------------------------------------------------------------------
*类的静态方法
1.静态方法是类的特殊方法,静态方法只需要在普通方法的前边加上 @staticmethod 修饰符即可
2.静态方法最大的优点是:不会绑定到实例对象上,换而言之就是节省开销
>>> class C:
@staticmethod
def static(arg1,arg2,arg3):
print(arg1, arg2, arg3, arg1 + arg2 + arg3)
def nostatic(self):
print('Im the f**king normal method!')
>>> C.static(1,2,3)
1 2 3 6
>>> C.nostatic()
Traceback (most recent call last):
File "<pyshell#122>", line 1, in <module>
C.nostatic()
TypeError: nostatic() missing 1 required positional argument: 'self'
>>> c1 = C()
>>> c2 = C()
# 静态方法只在内存中生成一个,节省开销
>>> c1.static is C.static
True
>>> c1.nostatic is C.nostatic
False
>>> c1.static
<function C.static at 0x03001420>
>>> c2.static
<function C.static at 0x03001420>
>>> C.static
<function C.static at 0x03001420>
# 普通方法每个实例对象都拥有独立的一个,开销较大
>>> c1.nostatic
<bound method C.nostatic of <__main__.C object at 0x03010590>>
>>> c2.nostatic
<bound method C.nostatic of <__main__.C object at 0x032809D0>>
>>> C.nostatic
<function C.nostatic at 0x0328D2B8>
---------------------------------------------------------------------------------------------------------------------------------------------------------------
第四十四课、
*简单定制
基本要求:
---定制一个计时器的类
---start和 stop方法代表启动计时和停止计时
---假设计时器对象t1,print(t1)和直接调用t1均显示结果
---当计时器未启动或已经停止计时时,调用stop方法会给予温馨的提示
---两个计时器对象可以进行相加:t1 + t2
---只能使用提供的有限资源完成:
1.使用 time模块的localtime方法获取时间
2.time.localtime返回struct_time的时间格式
3.表现你的类:__str和__repr__
---------------------------------------------------------------------------------------------------------------------------------------------------------------
第四十五课、
*魔法方法的访问属性
例子:
>>> class C:
def __getattribute__(self,name):
print('getattribute')
return super().__getattribute__(name)
def __getattr__(self,name): #super对象没有__getattr__
print('getattr')
def __setattr__(self,name,value):
print('setattr')
super().__setattr__(name,value)
def __delattr__(self,name):
print('delattr')
super().__delattr__(name)
>>> c = C()
>>> c.x
getattribute
getattr
>>> c.x = 1
setattr
>>> c.x
getattribute
1
>>> del c.x
delattr
---------------------------------------------------------------------------------
*练习要求:
1.写一个矩形类,默认有宽和高两个属性
2.如果为一个叫square的属性赋值,那么说明这是一个正方形,值就是正方形的边长,
此时宽和高都应该等于边长
#第一种写法:
>>>class Rectangle:
def __init__(self,width=0,height=0):
self.width = width
self.height = height
def __setattr__(self,name,value):
if name == 'square':
self.width = value
self.height = value
else:
super().__setattr__(name,value)------------也可以改成:self.__dict__[name]=value
>>> r1 = Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square = 10
>>> r1.width
10
>>> r1.height
10
>>> r1.getArea()
100
---------------------------------------------------------------------------------
*课后习题
1.在不上机验证的情况下,你能推断以下代码分别会显示什么吗?
>>> class C:
def __getattr__(self, name):
print(1)
def __getattribute__(self, name):
print(2)
def __setattr__(self, name, value):
print(3)
def __delattr__(self, name):
print(4)
>>> c = C()
>>> c.x = 1
# 位置一,请问这里会显示什么?
>>> print(c.x)
# 位置二,请问这里会显示什么?
答:位置一会显示 3,因为 c.x = 1 是赋值操作,所以会访问 __setattr__() 魔法方法;位置二会显示 2 和 None,因为 x 是属于实例对象 c 的属性,所以 c.x 是访问一个存在的属性,因此会访问 __getattribute__() 魔法方法,但我们重写了这个方法,使得它不能按照正常的逻辑返回属性值,而是打印一个 2 代替,由于我们没有写返回值,所以紧接着返回 None 并被 print() 打印出来
-----------------------------------------------------------------------------------
2.在不上机验证的情况下,你能推断以下代码分别会显示什么吗?
>>> class C:
def __getattr__(self, name):
print(1)
return super().__getattr__(name)
def __getattribute__(self, name):
print(2)
return super().__getattribute__(name)
def __setattr__(self, name, value):
print(3)
super().__setattr__(name, value)
def __delattr__(self, name):
print(4)
super().__delattr__(name)
>>> c = C()
>>> c.x
答:
>>> c = C()
>>> c.x
2
1
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
c.x
File "<pyshell#29>", line 4, in __getattr__
return super().__getattr__(name)
AttributeError: 'super' object has no attribute '__getattr__'
首先 c.x 会先调用 __getattribute__() 魔法方法,打印 2;然后调用 super().__getattribute__(),找不到属性名 x,因此会紧接着调用 __getattr__() ,于是打印 1;但是你猜到了开头没猜到结局……当你希望最后以 super().__getattr__() 终了的时候,Python 竟然告诉你 AttributeError,super 对象木有 __getattr__
--------------------------------------------------------------------------------------
3.请指出以下代码的问题所在:
class Counter:
def __init__(self):
self.counter = 0 # 这里会触发 __setattr__ 调用
def __setattr__(self, name, value):
self.counter += 1
“””既然需要 __setattr__ 调用后才能真正设置 self.counter 的值,所以这时候 self.counter 还没有定义,所以没法 += 1,错误的根源。”””
super().__setattr__(name, value)
def __delattr__(self, name):
self.counter -= 1
super().__delattr__(name)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第四十六课、
*魔法方法:描述符(Property)的原理
1.描述符就是将某种特殊类型的类的实例指派给另一个类的属性
特殊类型:至少实现以下3个方法中的其中一个
__get__(self,instance,owner)----------------用于访问属性,它返回属性的值
__set__(self,instance,value)-----------------将在属性分配操作中调用,不返回任何内容
__delete__(self,instance)---------------------控制删除操作,不返回任何内容
例子:
1.
>>> class MyDecriptor: #描述符类
def __get__(self,instance,owner):
print('getting...',self,instance,owner)
def __set__(self,instance,value):
print('setting...',self,instance,value)
def __delete__(self,instance):
print('deleting...',self,instance)
>>> class Test:
x = MyDecriptor()
>>> test = Test()
>>> test.x
getting... <__main__.MyDecriptor object at 0x000001E5364A83D0> <__main__.Test object at 0x000001E5364911F0> <class '__main__.Test'>
>>> test
<__main__.Test object at 0x000001E5364911F0>
>>> Test
<class '__main__.Test'>
>>> test.x = 'X-man'
setting... <__main__.MyDecriptor object at 0x000001E5364A83D0> <__main__.Test object at 0x000001E5364911F0> X-man
>>> del test.x
deleting... <__main__.MyDecriptor object at 0x000001E5364A83D0> <__main__.Test object at 0x000001E5364911F0>
-----------------------------------------------------------------------------------------------------
2.
>>> class MyProperty:
def __init__(self,fget=None,fset=None,fdel=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
def __get__(self,instance,owner):
return self.fget(instance)
def __set__(self,instance,value):
self.fset(instance,value)
def __delete__(self,instance):
self.fdel(instance)
>>> class C:
def __init__(self):
self._x = None
def getX(self):
return self._x
def setX(self,value):
self._x = value
def delX(self):
del self._x
x = MyProperty(getX,setX,delX)
>>> c = C()
>>> c.x = 'X-man'
>>> c.x
'X-man'
>>> c._x
'X-man'
>>> del c.x
-------------------------------------------------------------------------------------------------------
3.练习要求:
#先定义一个温度类,然后定义两个描述符类用于描述摄氏度和华氏度两个属性
#要求两个属性会自动进行转换
class Celsius:
def __init__(self,value = 26.0):
self.value = float(value)
def __get__(self,instance,owner):
return self.value
def __set__(self,instance,value):
self.value = float(value)
class Fahrenleit:
def __get__(self,instance,owner):
return instance.cel * 1.8 + 32
def __set__(self,instance,value):
instance.cel = (float(value)-32) / 1.8
class Temperature:
cel = Celsius()
fah = Fahrenleit()
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------