1、定义函数和调用函数
#定义函数def def greet_user(username): '''简单的问候语''' print('Hello,%s!'%username) greet_user('jack')#调用函数
2、形参和实参,实参的顺序很重要
def describe_flower(flower_type,flower_color='yellow'): print("My favorite flower is %s."%flower_type) print("My favorite %s is %s."%(flower_type,flower_color)) describe_flower('rose','red') describe_flower(flower_type='lily',flower_color='white') describe_flower(flower_type='babysbreath')#没有提供实参的形参将调用默认值 print('----------')
3、定义一个返回字典的函数
#返回字典 def make_album(singer_name,album_name,num_of_songs=''): info_of_album={'singer':singer_name,'album':album_name} if num_of_songs: info_of_album['number']=num_of_songs return info_of_album album1=make_album('周杰伦','十一月的肖邦') album2=make_album('许嵩','寻雾启事','12') print(album1) print(album2)
4、在函数中修改列表
def make_great(magicians): for i in range(len(magicians)): magicians[i] = 'The great ' + magicians[i] print(magicians) def show_magicians(magicians): for magician in magicians: print(magician) mags = ['jack','alex','james'] make_great(mags) show_magicians(mags)
5、[:]切片法创建列表副本,不改变原列表
def make_great(magicians,new_magicians): for i in range(len(magicians)): magicians[i] = 'The great ' + magicians[i] new_magicians.append(magicians[i]) print(new_magicians) def show_magicians(magicians): for magician in magicians: print(magician) mags = ['jack','alex','james'] new_mags = [] make_great(mags[:],new_mags)#函数调用列表副本 show_magicians(mags) show_magicians(new_mags)
6、结合使用位置实参和任意数量实参,Python将先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中;*表示建立一个名为topping的空元组。
#将多余实参全部存放到空元组中 def make_sandwich(size,*toppings): print('I will make a %s-inch sandwich with the following toppings:' %str(size)) for topping in toppings: print('- %s'%topping) make_sandwich(12,'sausages') make_sandwich(16,'sausages','mushrooms')
7、使用任意数量的关键字实参;**表示建立一个名为user_info的空字典
#将收到的所有键-值对都封装到这个字典中 def build_profile(first,last,**user_info): profile = {} profile['first_name'] = first profile['last_name'] = last for key,value in user_info.items(): profile[key] = value return profile user_profile = build_profile('james','lebran', location='shanghai', hobby='football') print(user_profile)
8、import 调用模块中函数的几种方法
#导入整个模块,就可以使用模块中所有的函数 import func func.make_car() #导入特定的函数 from func import make_car make_car() #调用模块中的函数,并指定别名 from func import make_car as mc car=mc('subaru','outback',color='blue',tow_package=True) print(car) #调用模块中所有函数 from func import * make_sandwich(16,'sausages','mushrooms')
9、%运算符,相除返回余数
#--%--运算符 number = 10 print(number%2) print(number%3)
10、运算符**表示乘方;2**3表示2的3次方
#for循环求64是2的几次方 a = 64 i = 0 for i in range(100): a /= 2 i += 1 if a == 1: print(i) break #while循环求64是2的几次方 a = 64 i = 0 while True: a /= 2 i += 1 if a == 1: print(i) break else: continue
11、循环语句中的特殊语句
-
continue :跳出本次循环;
-
break:跳出所有循环;
-
执行return之后,不再执行下面的代码,如果函数中没有return,Python将自动返回一个值None。
12、函数中的默认参数必须放到参数设置的末尾,例如def send(a,b,c="10")
13、元组动态参数*args的两种情况:
-
第一种:实参不带*将实参放到args这个元组中,传递给函数,无论实参是一个列表还是字符串,都将作为元组的一个元素;
-
第二种:实参带*,就把实参列表里的每个元素加入到元组中
def send(*args): print(args,type(args)) a = [11,22,'ddd'] send(a) send(*a) #([11, 22, 'ddd'],) <class 'tuple'> #(11, 22, 'ddd') <class 'tuple'>
14、字典动态参数**args:默认将传入的参数,全部放入字典中。实参中必须包含key和value
def send(**args): print(args,type(args)) send(a=1,b=2) dic = {'a':1,'b':2} send(n=dic) send(**dic) #{'a': 1, 'b': 2} <class 'dict'> #{'n': {'a': 1, 'b': 2}} <class 'dict'> #{'a': 1, 'b': 2} <class 'dict'>
15、万能参数:同时使用*args和**kwargs:顺序不能反,一个*必须放在前面
def send(*args,**kwargs): print(args,type(args)) print(kwargs,type(kwargs)) send(1,2,3,a='1',b='2') #(1, 2, 3) <class 'tuple'> #{'a': '1', 'b': '2'} <class 'dict'>
16、全局变量
-
定义全局变量默认字母全部大写;
-
如果想在函数中对全局变量重新赋值,需要加入global;
-
如果全局变量是列表或字典,函数中可以修改全局变量,比如添加删除元素。
#全局变量,任何作用域都可以读取 NAME = 'alex' def f1(): print(NAME) def f2(): #修改全局变量 global NAME NAME = 'alice' print(NAME) def f3(): print(NAME) f1() f2() f3() #alex #alice #alice
17、两个函数之间加两个空行,函数下面的波浪线就消失了,这样才符合函数的规范操作。
18、练习题:为每个函数添加注释要养成习惯,注释要放在双引号中,单引号会出现波浪线,不规范
def login(username,password): """ 用于用户登陆 :param username: 用户输入的用户名 :param password:用户输入的密码 :return:True表示登陆成功,False表示登陆失败 """ t = open('text_fileKJ', 'r') for line in t: line_list = line.strip().split('|') if username == line_list[0] and password == line_list[1]: return True return False def register(username,password): """ 用于用户注册 :param username: 用户输入的用户名 :param password: 用户输入的密码 :return: 默认返回None """ t = open('text_fileKJ', 'a') user_info = ' ' + username + '|' + password t.write(user_info) t.close() def main(): """ 让用户选择登陆或注册 """ user_input = input('1:登陆;2:注册:') if user_input == '1': user = input('请输入账户名:') pwd = input('请输入密码:') user_login = login(user,pwd) if user_login: print('登陆成功') else: print('登陆失败') elif user_input == '2': user = input('请输入账户名:') pwd = input('请输入密码:') register(user, pwd) main()
19、lambda表达式
-
就是简单函数的另一种表达方式,只能有一行
-
=前面是函数名,:前面是参数
#def函数 def f1(a): return a + 100 #lambda表达式 f2 = lambda a,b:a + b + 100 ret1 = f1(10) print(ret1) ret2 = f2(10,20) print(ret2) #设置默认值 f3 = lambda a,b=10:a + b + 100 ret3 = f3(10) print(ret3)
20、Python内置函数
#abs( )--取绝对值 a = -1 print(abs(a)) #bool( )--返回布尔值(False:0,None,"",[],(),{}) print(bool(None)) #all( )--括号内接受一个可迭代的数据集,数据集中的每个元素都为真,函数的返回值才为True; a = all([0,1,2,3]) print(a) #any( )--括号内也是一个可迭代数据集,任意一个元素为真,就为真; a = any([0,0,0,3]) print(a) #ascii( )自动执行类的__repr__ class Name(): def __repr__(self): return 'abc' n = ascii(Name()) print(n) #bin()接受一个十进制,转换成一个二进制 print(bin(8))#结果为0b1000,0b为二进制标识,8的二进制为1000 #oct()十进制转八进制 print(oct(9))#结果为0o11,0o标识八进制 #hex()十进制转十六进制 print(hex(15))#结果为0xf,0x标识十六进制 #UTF-8 一个汉字,三个字节,一个字节8位; #gbk 一个汉字,两个字节; #bytes(字符串,encoding=编码类型)把字符串转换为一个字节类型 s = "小明" print(bytes(s,encoding='utf-8'))#b'xe5xb0x8fxe6x98x8e' print(bytes(s,encoding='gbk'))#b'xd0xa1xc3xf7' #bytearray()将每个字节存储为一个数组的元素 print(bytearray(s,encoding='utf-8')) #字节类型转字符串,用同样的编码才能往回转换 n = bytes("小芳",encoding='utf-8')#字节类型 print(str(n,encoding='utf-8')) #文件操作 filename = 'text_filecats.txt' with open(filename,'r') as f1:#只读 with open(filename,'w') as f2:#先清空文件,只写 with open(filename,'x') as f3:#文件存在,报错,不存在,创建并只写 with open(filename,'a') as f4:#追加内容 #读取文件时,出现乱码,很可能是编码语言选择错误 with open('text_fileword.txt','r',encoding='gbk') as f5: contents = f5.read() print(contents) #rb,wb,xb,ab,r+b,w+b,x+b,a+b后面带b的,表示直接以字节的方式处理 with open(filename,'rb') as f: data = f.read() print(data,type(data)) #b'xe5xb0x8fxe7xb1xb3 ' <class 'bytes'> #把二进制数据添加到文件,需要bytes先转换为字符串 with open(filename,'ab') as f: data = f.write(bytes('小芳',encoding='utf-8')) #f.seek(n)指针跳转到n指定的位置(字节) #f.write()当前指针位置开始向后覆盖,n代表字节的位置 #f.tell()获取文件当前指针的字节位置 #r+,既能读,又能写;如果打开模式无b,read按照字符读取,有b,按字节 #无b,f.read(1)读取第一个字符,有b,读取第一个字节 with open('text_filecats.txt','r+',encoding='utf-8') as f5: contents = f5.read(1) print(contents)#读取第一个字:小 #a+,无论你怎么调整指针位置,写入时都会写在最后 #w+,先清空内容,再写入,才能读取刚才写入的内容 #使用open,close,打开读写文件 f = open(filename,'r') f.write('111') f.close() # f.flush()强制刷入硬盘 # f.readable()是否可读 # f.readline()只读取一行 # f.seekable()指针是否可操作 # f.truncate()截断:把指针位置后面的数据都清空 # for line in f: 按行循环文件对象 # 同时打开两个文件,最后同时关闭 # 例如:想把一个文件的内容修改一个人名后写入另一个文件 with open('db1','r') as f1,open('db2','a') as f2: for line in f1: new_line = line.replace('alex','alice') f2.write(new_line)
#将ascii码对照表里十进制转换为字母 r = chr(100) print(r)#d #将ascii码对照表里字母转换为十进制 n = ord("d") print(n)#100 #random随机返回一串验证码;ascII码表里65-90为大写字母 import random li = [] for i in range(4): r = random.randrange(0,5) if r == 1 or r == 3: num1 = random.randrange(0,10) li.append(str(num1)) else: num2 = random.randrange(65,91) li.append(chr(num2)) print(li) temp = ''.join(li)#join()把列表拼接成字符串 print(temp) #compile()编译成Python代码 s = "print(123)" r = compile(s,"<string>","exec") #exec()执行Python代码;接受代码或者字符串,没有返回值 exec(r) #eval()将字符串转换成Python代码,并获取结果 #函数只能执行表达式代码 r = "8*8" ret = eval(r) print(ret) #dir()快速查看一个对象提供了哪些功能 print(dir(random)) #help()查看对象提供的详细功能 #divmod()接受两个整数,得到商和余数 #第一种,可以将返回值赋给两个变量 a,b = divmod(97,10) print(a,b) #第二种,可以当成一个元组 n = divmod(98,10) print(n[0]) print(n[1]) #判断对象是否是某个类的实例 r = "abc" print(isinstance(r,str))#True '''filter(函数,可迭代的对象),循环第二个参数, 对参数的每一个元素执行函数,如果函数返回True, 就把这个元素加入结果,否则就舍弃 ''' def f(a): if a >2: return True li = [1,2,3,4] ret = filter(f,li) print(list(ret))#记得要以列表的形式输出 #以lambda表达式实现 ret = filter(lambda a:a>3,li) print(list(ret)) '''map(函数,可迭代的对象),循环第二个参数, 对参数的每一个元素执行函数,将函数返回值存放到结果 ''' li = [1,2,3] ret = map(lambda a:a+100,li) print(list(ret))#[101, 102, 103] #globals()返回所有全局变量 #locals()返回所有局部变量 #hash()返回一个对象的hash值,一般用于存储字典的key #id()查看内存地址 s = "sss" print(id(s))#327689119312 #issubclass()判断一个类是否是另一个类的子类 #Python2中字符长度按字节来算,3中按字符来算 #len('小明')2中返回6,3中返回2 #pow(2,10)求2的10次方 #rount()四舍五入 #slice()切片 #zip()将列表的相同索引的值放到一个元组中 l1 = ['a',1,2] l2 = ['b',1,2] l3 = ['c',1,2] r = zip(l1,l2,l3) ret = list(r)[0] print(' '.join(ret))
21、装饰器:@函数名
- 本质上就是函数,功能是为其他函数添加附加功能,前提是不改变装饰函数的源代码和调用方式;
- 高阶函数+函数嵌套+闭包
- 高阶函数:函数的参数或者返回值是一个函数名
- 函数嵌套:在函数内部定义函数
- 闭包:在一个作用域里放入定义变量,相当于打了一个包
- @函数名 是python的一种语法糖
#函数名可以当做参数传递 def f1(): print(123) def f2(xx): xx() f2(f1)#123 #装饰器@+函数名,有两个功能: #1、自动执行outer函数并将其下面的函数名f1当做参数传递 #2、将outer函数的返回值重新赋值给f1=inner #3、万能参数*args,**kwargs,接受任何数量的参数 def outer(func): def inner(*args,**kwargs): print("before") r = func(*args,**kwargs) print("after") return r return inner @outer #相当于f1=outer(f1),返回的是inner的内存地址f1=inner,然后f1(args)执行inner(args)函数 def f1(args): print(args) return "fff" + args ret = f1("ddd")#其实是在运行inner函数,最终得到inner函数的返回值 print(ret)
22、生成器,有两种表达方式
-
生成器表达式:m=(i for i in range(10)) m.__next__()
-
生成器函数:其实就是由函数改造而来,具有生成能力的函数,标识:函数内部有yield,相当于return,但是可以执行多次
def func(): print(111) yield 1 print(222) yield 2 ret = func()#得到一个生成器 print(ret)#<generator object func at 0x00000061358BA138> #进入函数执行函数,直到遇到yield,获取yield后面的数据,输出 r1 = ret.__next__() print(r1)#111,1 r2 = ret.__next__() print(r2)#222,2
#利用生成器创造一个循环函数 def myrange(arg): start = 0 while True: if start > arg: return yield start start += 1 ret = myrange(3) r = ret.__next__() print(r) r = ret.__next__() print(r)
23、迭代器:就是一个封装了调用函数__next__的循环,让我们不用一步一步调用__next__函数
-
凡是可作用于
for
循环的对象都是Iterable
类型(可迭代对象); -
凡是可作用于
next()
函数的对象都是Iterator
类型(迭代器对象),它们表示一个惰性计算的序列; - 生成器都是
Iterator
对象,生成器不但可以作用于for
循环,还可以被next()
函数不断调用并返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值了 -
集合数据类型如
list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。 -
Python的
for
循环本质上就是通过不断调用next()
函数实现的;
24、递归:自己调用自己
#递归应用于用户重复登录 def login(): inp = input("输入姓名") if inp == "admin": print("success") else: return login() login()
#递归实现从1循环加到7 def add(n): n += 1 if n <7: return add(n) else: return n r = add(1) print(r)#7 #递归实现1*2*3*4*5*6*7=5040 def mul(m,n): n += 1 m *= n if n < 7: return mul(m,n) return m ret = mul(1,1) print(ret)#5040 #另一种方法 def func(num): if num == 1: return 1 return num * func(num-1) ret = func(7) print(ret)
练习:递归实现斐波那契数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done'
25、反射
-
利用字符串的形式去对象(模块)中(寻找/检查/删除/设置)成员
-
getattr()寻找、hasattr()检查、delattr()删除、setattr()设置
-
通过字符串导入模块:
-
obj = __import__("xxx")
-
obj = __import__("file.xxx", fromlist=True)
-
def func(): inp = input("请输入你要访问的URL(模块名/函数名):") #hasattr()检查对象中是否包含该成员,是返回True m, h = inp.split("/") #__import__通过字符串导入模块,obj.func()调用函数 obj = __import__(m) #如果模块在文件夹中,后面加个参数fromlist,意思是按前面的指定路径导入 #obj = __import__("lib." + m, fromlist=True) if hasattr(obj,h): #getattr()获取对象中的成员 func = getattr(obj,h) func() else: print("404")
26、解压序列
a,b,c=(1,2,3) a=1 b=2 c=3 #取开头和结尾的值 l=[1,2,3,4,5] a,*_,b=l a=1 b=5 #*加一个变量,可以是任意字符,表示中间的所有值
27、冒泡算法
需求:请按照从小到大对列表 [13, 22, 6, 99, 11] 进行排序
思路:相邻两个值进行比较,将较大的值放在右侧,依次比较!
li = [13, 22, 6, 99, 11] def func(arg): for i in range(1,len(arg)): for m in range(len(li) - i): if arg[m] > arg[m+1]: arg[m],arg[m+1] = arg[m+1],arg[m] print(arg) func(li)
28、列表转字典
status_choice = [(1, '上线'), (2, '下线')] status_list = list(map(lambda x:{'id':x[0],'name':x[1]},Video.status_choice))