本节主要内容如下:
1. set集合
2. 函数
-- 自定义函数
-- 内置函数
3. 装饰器
一. set 集合:
一个无序且不重复的序列。
tuple算是list和str的杂合(杂交的都有自己的优势,上一节的末后已经显示了),那么set则可以堪称是list和dict的杂合.
set拥有类似dict的特点:可以用{}花括号来定义;其中的元素没有序列,也就是是非序列类型的数据;而且,set中的元素不可重复,这就类似dict的键.
set也有继承了一点list的特点:如可以原处修改(事实上是一种类别的set可以原处修改,另外一种不可以).
1.2 集合的创建:
1 s1 = {11,22,11,33,22} #第一种创建方法 2 print(s1) 3 4 {33, 11, 22}
1 s2 = set([11,22,11,33,22]) #第二种创建方法 2 print(s2) 3 4 {33, 11, 22}
1 s3 = set() #创建一个空的集合
例子:
1 s4 = set('chooses') 2 print(s4) 3 print(type(s4)) 4 5 {'s', 'c', 'e', 'o', 'h'} 6 <class 'set'>
注: 由于集合中元素是没有序列的,并且是不重复的,所以以上创建的集合输出时都是单一的。
1.3 集合的操作:
# add(增加), clear(清除)
1 s = set() #创建一个空集合 2 print(s) 3 s.add(123) #集合添加元素,多次添加相同一个元素时,集合中只会添加一个 4 s.add(123) # 不重复的 5 print(s) 6 s.clear() #清除 7 print(s) 8 9 set() 10 {123} 11 set()
#difference() #指AB两个集合,A中存在,B中不存在。
#symmetric_difference # 指除去AB交集的元素外的其他元素。
1 s1 = {11,22,33} 2 s2 = {22,33,44} 3 s3 = s1.difference(s2) #s1中存在,s2中不存在 4 print(s3) 5 s4 = s2.difference(s1) #s2中存在,s1中不存在 6 print(s4) 7 8 {11} 9 {44}
1 s1 = {11,22,33} 2 s2 = {22,33,44} 3 s3 = s1.symmetric_difference(s2) #s1和s2交集外的其他元素集合 4 print(s3) 5 6 {11, 44}
#difference_update #AB两个集合,A中有B中没有的元素更新到A集合
1 #s1.difference_update(s2) 2 #print(s1) 3 4 {11}
#symmetric_difference_update #同上,A和B交集外的其他元素更新到A集合
1 s1.symmetric_difference_update(s2) 2 print(s1) 3 4 {11, 44}
#discard,remove #移除集合中某个元素
#pop #移除一个随机的元素
1 s1 = {11,22,33} 2 s1.discard(11) #移除11元素,最好用 3 s1.discard(1111) #移除1111不存在的元素时,不会报错 4 s1.remove(11) #与discard相同,移除一个元素 5 s1.remove(1111) #移除一个不存在的元素时会报错 6 s1.pop() #移除一个随机的元素,可以通过赋值查看移除的元素 7 s2 = s1.pop() 8 print(s2) 9 10 11
#intersection #取AB集合的交集
#intersection_update#取AB集合的交集并更新到A集合
1 s1 = {11,22,33} 2 s2 = {22,33,44} 3 s3 = s1.intersection(s2) #取s1和s2的交集 4 print(s3) 5 s1.intersection_update(s2) #取交集并更新到s1集合中 6 print(s1) 7 8 {33, 22} 9 {33, 22}
#union #取AB集合的并集
1 s1 = {11,22,33} 2 s2 = {22,33,44} 3 s3 = s1.union(s2) 4 print(s3) 5 6 {33, 22, 11, 44}
#update #接受一个可以被迭代的对象,例如for循环每一个元素更新到集合
1 s1 = {11,22,33} 2 s2 = [11,22,3,34,55]或者 s2 = (11,22,3,34,55)或者 s2 = "hongfei"3 s1.update(s2) 4 print(s1) 5 6 {33, 34, 3, 11, 22, 55}
注: 迭代可以为一个列表,元组,字符串。
1 class set(object): 2 """ 3 set() -> new empty set object 4 set(iterable) -> new set object 5 6 Build an unordered collection of unique elements. 7 """ 8 def add(self, *args, **kwargs): # real signature unknown 9 """ 10 Add an element to a set,添加元素 11 12 This has no effect if the element is already present. 13 """ 14 pass 15 16 def clear(self, *args, **kwargs): # real signature unknown 17 """ Remove all elements from this set. 清除内容""" 18 pass 19 20 def copy(self, *args, **kwargs): # real signature unknown 21 """ Return a shallow copy of a set. 浅拷贝 """ 22 pass 23 24 def difference(self, *args, **kwargs): # real signature unknown 25 """ 26 Return the difference of two or more sets as a new set. A中存在,B中不存在 27 28 (i.e. all elements that are in this set but not the others.) 29 """ 30 pass 31 32 def difference_update(self, *args, **kwargs): # real signature unknown 33 """ Remove all elements of another set from this set. 从当前集合中删除和B中相同的元素""" 34 pass 35 36 def discard(self, *args, **kwargs): # real signature unknown 37 """ 38 Remove an element from a set if it is a member. 39 40 If the element is not a member, do nothing. 移除指定元素,不存在不保错 41 """ 42 pass 43 44 def intersection(self, *args, **kwargs): # real signature unknown 45 """ 46 Return the intersection of two sets as a new set. 交集 47 48 (i.e. all elements that are in both sets.) 49 """ 50 pass 51 52 def intersection_update(self, *args, **kwargs): # real signature unknown 53 """ Update a set with the intersection of itself and another. 取交集并更更新到A中 """ 54 pass 55 56 def isdisjoint(self, *args, **kwargs): # real signature unknown 57 """ Return True if two sets have a null intersection. 如果没有交集,返回True,否则返回False""" 58 pass 59 60 def issubset(self, *args, **kwargs): # real signature unknown 61 """ Report whether another set contains this set. 是否是子序列""" 62 pass 63 64 def issuperset(self, *args, **kwargs): # real signature unknown 65 """ Report whether this set contains another set. 是否是父序列""" 66 pass 67 68 def pop(self, *args, **kwargs): # real signature unknown 69 """ 70 Remove and return an arbitrary set element. 71 Raises KeyError if the set is empty. 移除元素 72 """ 73 pass 74 75 def remove(self, *args, **kwargs): # real signature unknown 76 """ 77 Remove an element from a set; it must be a member. 78 79 If the element is not a member, raise a KeyError. 移除指定元素,不存在保错 80 """ 81 pass 82 83 def symmetric_difference(self, *args, **kwargs): # real signature unknown 84 """ 85 Return the symmetric difference of two sets as a new set. 对称差集 86 87 (i.e. all elements that are in exactly one of the sets.) 88 """ 89 pass 90 91 def symmetric_difference_update(self, *args, **kwargs): # real signature unknown 92 """ Update a set with the symmetric difference of itself and another. 对称差集,并更新到a中 """ 93 pass 94 95 def union(self, *args, **kwargs): # real signature unknown 96 """ 97 Return the union of sets as a new set. 并集 98 99 (i.e. all elements that are in either set.) 100 """ 101 pass 102 103 def update(self, *args, **kwargs): # real signature unknown 104 """ Update a set with the union of itself and others. 更新 """ 105 pass
练习:
将原来的内存插槽更新为新的内存插槽
1 old_dict = { #旧内存插槽 2 "#1":8, 3 "#2":4, 4 "#3":2, 5 } 6 7 new_dict = { #新内存插槽 8 "#1":4, 9 "#2":4, 10 "#3":2, 11 } 12 13 #将原来的旧插槽更新为新的内存插槽
需求分析:
1.应该删除哪几个插槽
2.应该添加哪几个插槽
3.应该更新哪几个插槽
1 #old_keys = old_dict.keys() 2 #new_keys = new_dict.keys() 3 4 old_set = set(old_dict.keys()) 5 new_set = set(new_dict.keys()) 6 7 remove_set = old_set.difference(new_set) 8 add_set = new_set.difference(old_set) 9 update_set = old_set.intersection(new_set) 10 print(new_set) 11 print(old_set) 12 13 {'#2', '#3', '#1'} 14 {'#2', '#3', '#1'}
二. 函数:
对程序逻辑进行结构化或过程化的一种编程方法。将整块代码分隔为多个小块,重复代码可以单独放入函数中而不用大量的去拷贝,既节省了空间,又有助于保持一致性。
(一).函数的结构:
1. def : 函数关键字,用来创建函数
2. 函数名:函数的名称,以后调用时使用函数名。
3. () : 函数参数,为函数体提供数据
4. 函数体 :函数中进行一系列逻辑计算
5. 返回值:当函数执行完毕后,给调用者返回数据
1 def 函数名(参数): 2 3 ... 4 函数体 5 ... 6 返回值
1 # ######### 定义函数 ######### 2 3 # name 叫做函数func的形式参数,简称:形参 4 def func(name): 5 print name 6 7 # ######### 执行函数 ######### 8 # 'hongfei' 叫做函数func的实际参数,简称:实参 9 func('hongfei') 10 11 普通参数
案例: 发邮件
1 def sendmail(): 2 try: 3 import smtplib 4 from email.mime.text import MIMEText 5 from email.utils import formataddr 6 7 8 msg = MIMEText('邮件内容', 'plain', 'utf-8') 9 msg['From'] = formataddr(["hongfei",'邮箱名']) 10 msg['To'] = formataddr(["走人",'12345677@qq.com']) 11 msg['Subject'] = "主题" 12 13 server = smtplib.SMTP("smtp.163.com", 25) #163邮箱为例,SMTP地址 14 server.login("邮箱名", "密码",) #登陆邮箱用户名,密码 15 server.sendmail('发送邮箱', ['接收邮箱',], msg.as_string()) 16 server.quit() 17 except: 18 return False #发送失败 19 else: 20 return True #发送成功 21 22 ret =sendmail() 23 print(set) 24 if ret == True: 25 print('发送成功') 26 else: 27 print('发送失败')
1 def f1(): 2 print(123) 3 return '111' #在函数中,一旦执行return,函数执行过程立即终止 4 print(456) #所以不会执行此print 5 6 r = f1() #函数输出值赋值给r 7 print(r) 8 9 123 10 111
注:1. 在函数中,一旦执行return,函数执行过程立即终止,后面的函数将不会再执行。
2. 在函数中,当没有指定return返回值行,默认将返回None
3. 定义函数时,函数体不执行,只有引用函数时才会执行。
(二). 函数的参数:
1. 位置参数(普通参数):
位置参数(普通参数)必须在被调用函数中定义的准确顺序来传递参数。传入函数(调用)的参数的精确的数目必须和声明的数字一致。
1 def send(who, content,judge ): #定义三个参数 2 print(who, content, judge) 3 return True 4 5 while True: 6 em = input("请输入邮箱地址:") #提示输入,邮箱为例 7 result = send(em ,"SB","ok")#参数必须与上边定义参数顺序和数目一致 8 if result == True: 9 print("发送成功") 10 break
2. 默认参数:
在函数调用时没有为参数提供值则默认使用预先定义好的默认值。
1 def send(who, content,judge='OK' ): #judge为默认参数 2 print(who, content, judge) 3 # print(who,content) 4 return True 5 send('zhao','pythoner') #这里没有制定则输出默认参数 6 send('zhao','pythoner','NO')#指定后judge默认值就变为NO
注: 指定默认参数时,默认参数必须放置在参数列表的最后,否则会报错。
def send(who, judge='OK' , content) ##如上这样没有放置在后边指定默认参数的话,程序会报错,必须放置于后边
3. 指定参数:
将实际参数赋值给指定的形式参数。
1 def send(who,content): 2 print(who,content) 3 return True 4 send("hong",'pythoner') 5 send(content='hong',who='pythoner')#当你传参的时候,直接制定对应参数值即可。
4. 动态参数 *,**
传入多个参数时使用*,**
1 def f1(*args): #普通*的用法 2 print(args,type(args)) 3 4 f1('hong','fei',123,456) #把指定元组的所有定义的参数传入arges 5 li = ['hong','fei',123,456] #定义一个列表 6 f1(li) #输出时定义的列表以元组的一个元素存在 7 f1(li,'789') #789同样当作元组的元素添加进来 8 print('------------------------一颗*----------------------------') 9 #还有一种特殊*的用法如下: 10 f1(li) #普通输出为定义的列表 11 f1(*li) #加*以后输出则列表当中的所有元素当作元组的每一个元素存在 12 li1 = 'hongfei' #当传入的为一个字符串的时候,原理为for循环每一个元素 13 f1(li1) 14 f1(*li1) 15 print('------------------------二颗*---------------------------------') 16 ##两颗**用法如下: 17 18 def f1(**arges): 19 print(arges, type(arges)) 20 f1(n1 ='hong',n2 = 20) #两颗星输出为字典 21 dic = {'k1':'v1','k2':'v2'} 22 f1(kk = dic) #定义字典时必须添加一个变量否则报错 23 f1(**dic) 24 print("------------------------两颗*与三颗*混用-------------------------------------") 25 26 def f1(*args, **kwargs): 27 print(args) 28 print(kwargs) 29 30 f1(11,22,33,44,k1 ='v1',k2 ='v2') #自动分别以元组和字典输出 31 32 33 #以下为输出信息 34 ('hong', 'fei', 123, 456) <class 'tuple'> 35 (['hong', 'fei', 123, 456],) <class 'tuple'> 36 (['hong', 'fei', 123, 456], '789') <class 'tuple'> 37 ------------------------一颗*---------------------------- 38 (['hong', 'fei', 123, 456],) <class 'tuple'> 39 ('hong', 'fei', 123, 456) <class 'tuple'> 40 ('hongfei',) <class 'tuple'> 41 ('h', 'o', 'n', 'g', 'f', 'e', 'i') <class 'tuple'> 42 ------------------------二颗*--------------------------------- 43 {'n2': 20, 'n1': 'hong'} <class 'dict'> 44 {'kk': {'k2': 'v2', 'k1': 'v1'}} <class 'dict'> 45 {'k1': 'v1', 'k2': 'v2'} <class 'dict'> 46 ------------------------两颗*与三颗*混用------------------------------------- 47 (11, 22, 33, 44) 48 {'k2': 'v2', 'k1': 'v1'}
format *号的使用:
1 s1 = 'i am {0}, age {1}'.format('hong',20) 2 print(s1) 3 s2 = 'i am {0}, age {1}'.format(*['alex',20]) 4 print(s2) 5 6 s1 = 'i am {name}, age {age}'.format(name='hong',age=20) 7 print(s1) 8 9 dic = {'name':'hong','age':18} 10 s2 = 'i am {name}, age {age}'.format(**dic) 11 print(s2) 12 13 i am hong, age 20 14 i am alex, age 20 15 i am hong, age 20 16 i am hong, age 18
补充内容:
5. 函数定义的顺序:
1 ##函数定义顺序: 2 3 def f1(s1,a2): 4 return a1 + a2 5 6 def f1(a1,a2): 7 return a1 * a2 #以第二次为实际参数输入 8 9 ret = f1(8,8) 10 print(ret) 11 12 64 #输出的为64而不是16
6. 函数引用
1 def f1(a1): 2 a1.append(999) #函数引用,追加时不会重新赋值而是追加到列表元素的后边。 3 4 li = [11,22,33,44] 5 f1(li) 6 print(li) 7 8 9 [11, 22, 33, 44, 999]
7. 全局变量:
1 #全局变量,所有作用域都可读 2 #对全局变量进行重新赋值,需要global 3 #特殊:列表字典,可修改,不可重新赋值 4 NAME = 'hong' #全局变量的定义全部为大写。 5 def f1(): 6 age = 20 7 global NAME #表示name是全局变量 8 NAME = '123' 9 print(age,NAME) 10 def f2(): 11 age = 22 12 print(age,NAME) 13 f1() 14 f2() 15 16 20 123 17 22 123
以上内容总结:
1. 普通参数(位置参数): 严格按照顺序,将实际函数赋值给形式参数。
2. 默认参数:指定默认参数值,默认参数必须放置于参数列表的最后。
3. 指定参数:将实际参数赋值给指定的形式参数。
4. 动态参数:
*: 默认将传入的参数全部放置于元组中, f1([11,22,33,44])
**: 默认将传入的参数全部放置于字典中, f2(**{'k1':'v1','k2':'v2'})
5. 万能参数: (*args,**kwargs)
6. 补充内容:
a.
def f1()
def f2() #定义两个函数时,以第二天定义函数为准,则实际定义为f2()函数
b. 引用
c. 全局变量:
读: 所有均可以读
赋值:必须由全局global定义
字典,列表: 可以修改
定义全局变量时,默认都为大写
***用函数实现用户登录和注册接口***
1 ef login(username,password): 2 """ 3 用于用户登录 4 :param username: 用户输入的用户名 5 :param password: 用户输入的密码 6 :return: true,表示登陆成功,false表示登陆失败 7 """ 8 f = open('db','r') 9 for line in f: 10 line_list = line.strip().split('|') 11 if line_list[0] ==username and line_list[1] == password: 12 return True 13 14 return False 15 16 def register(username,password): 17 """ 18 用于用户注册 19 :param username: 输入用户名 20 :param password: 输入密码 21 :return: 没有指定返回值,默认为None 22 """ 23 f = open('db','a') 24 temp = '\n' + username + '|' + password 25 f.write(temp) 26 f.close() 27 28 def main(): 29 t = input('1:登陆'+'\n'+ '2:注册'+'\n') 30 if t == '1': 31 user = input('请输入用户名:') 32 passwd = input('请输入密码:') 33 r = login(user,passwd) 34 if r: 35 print('登陆成功') 36 else: 37 print('登陆失败') 38 elif t == '2': 39 user = input('请输入用户名:') 40 passwd = input('请输入密码:') 41 register(user,passwd) 42 print("注册成功") 43 44 main()
用户名密码文件:
db文本文件内容
admin|123
zhao|123
hong|123
####三元运算#####
只需要一行即完成条件判断和赋值操作
1 ##三元运算 2 3 if 1 == 1: 4 name = 'hong' 5 else: 6 name = 'fei' 7 8 name = 'hong' if 1 == 1 else 'fei' 9 10 print(name) 11 12 hong
lambda 表达式的使用:
1 ef f1(a1): 2 return a1 + 100 #普通函数写法 3 f2 = lambda a1: a1 + 100 #lambda写法 4 5 ret1 = f1(10) 6 print(ret1) 7 8 ret2 = f2(20) 9 print(ret2) 10 print('**********************************') 11 12 f3 = lambda a1,a2: a1 + a2 + 100 #可以传入两个或多个值 13 ret3 = f3(10,20) 14 print(ret3) 15 print("**********************************") 16 17 f4 = lambda a1,a2=30: a1 + a2 + 100 #将a2指定默认值 18 ret4 = f4(10) #传入时不指定默认值,自动输出 19 print(ret4) 20 21 110 22 120 23 ********************************** 24 130 25 ********************************** 26 140
常用的内置函数:
abs() , all() , any() , ascii() , (bin(),oct(),hex()), bytes(), open(),chr(),ord()
1 abs #绝对值 2 n = abs(-1) 3 print(n) 4 5 #0, None, "", [], () #都为False 6 print(bool()) #布尔值 7 8 all() #所有为真才为真 9 n = all([1,2,3,None]) 10 print(n) 11 12 any() #只要有真,即为真。 13 ascii() #自动执行对象的__repr__方式 14 15 bin, oct, hex #进制转换 16 print(bin(5)) #二进制 17 print(oct(9)) #八进制 18 print(hex(15)) #十六进制 19 20 bytes 21 #字符串转换字节类型 22 #格式:bytes(只要转换的字符串,按照什么编码) 23 s = '鸿飞' 24 n1 = bytes(s,encoding='utf-8') 25 print(n1) 26 n2 = bytes(s,encoding='gbk') 27 print(n2) 28 29 ##字节转换成字符串 30 31 new_str = str(bytes(s,encoding='utf-8'),encoding='utf-8') 32 print(new_str) 33 34 #open 35 36 #打开文件 37 f = open('db','r') #只读打开 38 f = open('db','w') #只写,打开前会把文件清空 39 f = open('db','x') #文件存在,报错,不存在,创建并写内容。3.0版本新加 40 f= open('db','a') #追加 41 42 f = open('db','r') 43 data = f.read() 44 print(data,type(data)) #data类型为字符串 45 46 f = open('db','rb') #以二进制的方式读取 47 data = f.read() 48 print(data,type(data)) 49 50 f = open('db','a') #追加内容到文件里 51 f.write('hongfei') 52 f.close()
1 文件句柄 = open('文件路径', '模式') 2 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。 3 4 打开文件的模式有: 5 6 r ,只读模式【默认】 7 w,只写模式【不可读;不存在则创建;存在则清空内容;】 8 x, 只写模式【不可读;不存在则创建,存在则报错】 9 a, 追加模式【可读; 不存在则创建;存在则只追加内容;】 10 "+" 表示可以同时读写某个文件 11 12 r+, 读写【可读,可写】 13 w+,写读【可读,可写】 14 x+ ,写读【可读,可写】 15 a+, 写读【可读,可写】 16 "b"表示以字节的方式操作 17 18 rb 或 r+b 19 wb 或 w+b 20 xb 或 w+b 21 ab 或 a+b 22 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型
##最常用的 r+ :
1 ### r+ #最常用 2 f = open('db','r+', encoding='utf-8') 3 #如果打开模式无b,则read,按照字符读取 4 data = f.read(1) 5 #tell当前指针所在的位置(字节) 6 print(f.tell()) 7 #调整当前指针的位置(字节) 8 f.seek(f.tell()) 9 #当前指针位置开始向后覆盖 10 f.write('888') 11 f.close()
来源:https://www.cnblogs.com/python-nameless/p/5522374.html