函数
if __name__=='__main__'的简单理解
if __name__ == '__main__' 我们简单的理解就是: 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。(不运行被导入模块里面的函数)
一、语法定义:
def sayhi( ): #()函数名
逻辑值
返回值
sayhi() #(调用函数名)
二、参数
def calc (x,y) #(x,y为形参)
c = calc(5,6) #(5,6传入函数内的就是实参)
( 1)默认参数:
def calc(name,age,course,country = 'CN')
#(在不输入国籍的时候默认都为CN,如果输入则为其他的。默认参数都放在最后,如果以前不在最后变陈默认参数 后也在最后)
(2)关键参数:
给函数传参数要按照顺序,不想按照顺序就可以传参数就可以用关键参数,在调用的时候指定参数名
def calc(name,age,course,country = 'CN')
calc ("yisa',course='py',age = 22) (在没有标明是哪一个的参数名的时候不能改变顺序,且,关键参数必须放在最后的位置)
最后的结果还是按照函数只管参数顺序出来的
(3)非固定参数:
不确定用户有多少个参数要传入的时候
def calc (name,age,*arges) #(多传入的参数会变成一个元祖) (*arges 一般放在最后因为会把后面所用的值默认组成一个元祖)
print( name,age,arges)
1)、calc ('yisa',22,'CN','py')
输出 yisa 22 ('CN','py')
2)、calc ('yisa',22,['CN','py']) calc ('yisa',22,*['CN','py']) (加*号去掉元祖符号)
输出 yisa 22 (['CN','py']) 输出 yisa 22 ['CN','py']
3)、 def calc (name,age,*arges,**kwargs) **kwarge (把传入的参数默认组成一个字典)
calc ('yisa',22,'CN','py',sex='male',province = 'sichuan')
yisa 22 ('CN','py') {'sex':'male','province' :'sichuan'}
三、返回值:
1.return的作用:结束一个函数的执行
2.首先返回值可以是任意的数据类型。
3.函数可以有返回值:如果有返回值,必须要用变量接收才有效果
4.也可以没有返回值:没有返回值,函数返回为None
1 def calc(x): 2 3 a=111 4 b=[1,2,3] 5 c={'a':15,'b':6} 8 if ------ #(函数在执行过程中遇到return语句,就会停止执行并返回结果,后面的语句都不执行) 9 10 return a #(未在函数中指定return,函数返回值为None) 11 else ----- 12 13 return a,b,c #(返回多个值,变量之间按照逗号隔开,以元祖的形式返回)
四、 全局与局部变量
name = 'Alex li'
def c_name():
global name (定义了全局变量)
name = ''alex'
print(name)
五、 嵌套函数
就是函数里面套函数
def name () name=‘Alex’ def age() age= 22 print(age) age() name() 变量要由里往外找
六、匿名函数
calc = lambda x,y:x**y (声明一个函数)
map( func,data) (函数,数据) 就是把data里面的数都付给函数,取算值
res = map(lambda x:x**2,[1,2,3,4,5]
七、高阶函数
一个函数可以接受另外一个函数作为参数
def add(x,y,f)
return f(x)+f(y) returen 是返回另外一个函数
res = add(3,-6,abs) abs(是绝对值的意思)
八、递归
如果一个函数在内部调用函数本身,这个函数就是递归函数
必须有一个明确的结束条件
def calc(n): v = int(n/2) print(v) if v ==0 renturn'done' calc(v) print(v) 输出 5 2 1 0 1 2 5 10
九、内置函数
只写一个不容易记得
zip a=[1,2,3,4]
b=['a','b','c'] list(zip(a,b)) [(1,'a'),(2,’b'),(3,'c')] 一一对应多余的丢弃
函数进阶
一、名称空间
x=1 (名称空间就是存放名字x与1绑定关系的地方)
locals :是函数内的名称空间,包括局部变量和形参
globals: 全局变量
buitins:内置模块的名字空间
二、闭包
1.闭 :内部的函数
2.包 :包含了对外部函数作用域中变量的引用
两个原则,开放封闭原则
对扩展是开放的
对修改是封闭的
1 def outer(): 2 name='alex' #(这里定义是给让内层函数一起使用) 3 def inner(): 4 name='yisa' #(如果这里再定义name,那么就不是一个闭包,只是嵌套函数) 5 print("在inner里打印外层函数变量;name) 6 return inner (这里只是返回inner 的内存地址) 7 f= outer() 8 f()( 执行inner())
三、装饰器
装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展
装饰器的本质:就是一个闭包函数
1 def login(auth_type): 2 user_name = 'yisa' 3 password = 'a123' 4 global user_status 5 if user_status == False: 6 _user_name = input('Name:') 7 _password = input('Password:') 8 if _user_name == user_name and _password == password: 9 print("登陆成功") 10 user_status = True 11 else: 12 print("wrong name or password") 13 if user_status ==True: 14 func() #(这里通过了验证,就调用相应功能) 15 16 @login 17 def home(): #(原函数不带参数的类型) 18 print("------首页--------") 19 def america(): 20 print("-------欧美专区----") 21 22 def japan(): 23 print("--------日本专区-----") 24 25 @login 26 def henan(style): #(原函数第一个参数的类型) 27 print("--------河南专区------",style) 28 29 30 (1) home() 31 #henan() 32 login(henan) (用户之前只需要调用henan() 这里相当于改变了调用方式)这种方法不可取,因为每一个的调用方式都会改变
在调用前进行认证(qq\weixin) 那就只能在外面多定义一层函数
1 user_status = False 2 def login(auth_type): 3 def outer(func): 4 def inner(*arge,**kwargs): 5 if auth_type=="weixin" #(这里还要验证一次登录方式) 6 user_name = 'yisa' 7 password = 'a123' 8 global user_status 9 if user_status == False: 10 _user_name = input('Name:') 11 _password = input('Password:') 12 if _user_name == user_name and _password == password: 13 print("登陆成功") 14 user_status = True 15 else: 16 print("wrong name or password") 17 if user_status ==True: 18 func(*arge,**kwargs) 19 else: 20 print('只能使用微信登录‘) 21 return inner 22 return outer 23 def home(): 24 print("------首页--------") 25 def america(): 26 print("-------欧美专区----") 27 @login('weixin') 28 def japan(): 29 print("--------日本专区-----") 30 # @login #(这个功能和henan = login(henan)一样)这个就是装饰器 加了之后自动进入函数第一层 31 #@login('qq') #相当于退两层,先是login('qq'),然后是out('henan). 加了参数又自己进去下一层 32 # 一个login不加括号是return一层,带一个参数是两个return, 就是要定义三次去调用 33 def henan(style): 34 print("--------河南专区------",style) 35 # henan = login(henan) 36 henan('aaa') 37 japan()
3.2 带参数的装饰
带参数的装饰器:就是给装饰器传参
用处:就是当加了很多装饰器的时候,现在忽然又不想加装饰器了,想把装饰器给去掉了,但是那么多的代码,一个一个的去闲的麻烦,那么,我们可以利用带参数的装饰器去装饰它,这就他就像一个开关一样,要的时候就调用了,不用的时候就去掉了。
1 带参数的装饰器:(相当于开关)为了给装饰器传参 2 # F=True#为True时就把装饰器给加上了 3 F=False#为False时就把装饰器给去掉了 4 def outer(flag): 5 def wrapper(func): 6 def inner(*args,**kwargs): 7 if flag: 8 print('before') 9 ret=func(*args,**kwargs) 10 print('after') 11 else: 12 ret = func(*args, **kwargs) 13 return ret 14 return inner 15 return wrapper 16 17 @outer(F)#@wrapper 18 def hahaha(): 19 print('hahaha') 20 21 @outer(F) 22 def shuangwaiwai(): 23 print('shuangwaiwai') 24 25 hahaha() 26 shuangwaiwai()
3.3多个装饰器装饰一个函数
1 def qqqxing(fun): 2 def inner(*args,**kwargs): 3 print('in qqxing: before') #第一个执行 4 ret = fun(*args,**kwargs) 5 print('in qqxing: after') #第五个执行 6 return ret 7 return inner 8 9 def pipixia(fun): 10 def inner(*args,**kwargs): 11 print('in qqxing: before') #第二个执行 12 ret = fun(*args,**kwargs) #第三个执行 13 print('in qqxing: after') #第四个执行 14 return ret 15 return inner 16 @qqqxing 17 @pipixia 18 def dapangxie(): 19 print('饿了吗') 20 dapangxie() 21 22 ''' 23 @qqqxing和@pipixia的执行顺序:先执行qqqxing里面的 print('in qqxing: before'),然后跳到了pipixia里面的 24 print('in qqxing: before') 25 ret = fun(*args,**kwargs) 26 print('in qqxing: after'),完了又回到了qqqxing里面的 print('in qqxing: after')。所以就如下面的运行结果截图一样 27 ''' 28 29 多个装饰器装饰一个函数
四、生成器和迭代器
4.1列表生成器:( 只能写到列表、元祖,但不能是字典)
a = [i+1 for i in range(10)] 把后面的 i 值赋给前面 (列表生成式)
a = [i if i <5 else i*i for i iin b] 这里的b 是字典、列表、字符串
生成器:generator
a = [i+1 for i in range(10)]
g = ( i+1 for i in range(10))把[ ] 改为( )就创建了一个生成器
可以通过next( )获得generator的一个返回值
next() >>> 1 next() >>> 2 next() 因为太麻烦了,所以我么基本不用next()来调用函数 >>>3
因为一般用 for 循环
如果推算的算法比较复杂,用for 循环不能实现时,还可以用函数来实现
Fibonacci 函数 除了第一个和第二个数外,任意一个数可由前两个数相加的到。
def fib(max): (max 表示多少位) n, a,b = 0,0,1 while n <max : print(b) a,b= b,a+b n = n+1
fib 函数和generator 仅一步之遥 要把 fib 变成generator 只需要把print(b) 改为 yieldb
1 def fib(max): (max 表示多少位) 2 n, a,b = 0,0,1 3 while n <max : 4 #print(b) 5 yield b (相当于函数停在了这里,程序也停在了这里(把函数的执行过程冻结在这一步,并且把b的值返回给外面的 next(), 6 next()唤醒冻结的函数,直到遇到下一个yield ) 7 a,b= b,a+b 8 n = n+1 9 return 'done' 10 11 (1) print( ) 12 yield b (第一次到这里就停止了) 13 (2) print( ) 14 15 第二次输出(2)的内容再输出(1)的内容 然后遇到yield 就再一次停止 16 send 的作用 17 1、唤醒函数并继续进行(如果函数有被yield 中止了,可以继续进行) 18 2、发送一个信息到生成器内部
4.2迭代器
可以用于for 循环的数据类型有以下几种:
1、数据集合:list tuple dict set str
2、一类是生成器generator, 包括生成器带yield 的generator function
可直接用作于for循环额对象统称为可迭代对象:iterable
可以使用isinstance() 判断一个对象是否是interable 对象
生成器不但可以被用作for 循环,还可以被next()函数不断调用把那个返回下一个值,知道最后抛出stopinteration错误表示无法返回下一个值了
可以被next()函数不断调用把那个返回下一个值的对象成为迭代器:interator (生成器是迭代器的一种)
生成器都是可迭代对象, 但list dict str 虽然都是可以迭代(interable)但是却不是迭代器(iterator)
filter 过滤函数的使用
例如:筛选出偶数
date=[1,2,3,4,5,6,7,8]
def calc(n):
if n%2==0:
return True
oushu=filter( calc,data)

浙公网安备 33010602011771号