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