python函数

函数

概念:功能 (包裹一部分代码 实现某一个功能 达成某一个目的)
特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理

 

1.函数基本格式

 #  定义一个函数 
 def  函数名():
code1
code
# 调用函数 函数名() """ # 定义函数
def func():
print("我是一个函数 ... ")

# 调用函数
func()

 

 

2.函数的命名

字母数字下划线,首字符不能为数字
严格区分大小写,且不能使用关键字
函数命名有意义,且不能使用中文哦

驼峰命名法:
(1) 大驼峰命名法: 每个单词的首字符要大写 (类的命名)
mycar => MyCar
(2) 小驼峰命名法: 除了第一个单词首字符小写外,剩下单词首字符大写 (函数或者变量)
mycar => myCar
(3)_命名法:可以将不同的单词用_拼接在一起
mycar => my_car
symmetric_differencesymmetricDifference SymmetricDifference

 #  函数定义 
 def  cfb_99():  for  i  in  range(1,10 ):  for  j  in  range(1,i+1 ):  print ( "  {:d}*{:d}={:2d}  " .format(i,j,i*j) ,end= ""  )  print  ()  #  调用函数 
 for  i  in  range(5 ):
cfb_99()

 

函数的参数

参数: 函数运算时需要的值

参数种类:
(1)形参: 形式参数,在函数的定义处
(2)实参: 实际参数,在函数的调用处

形参的种类:
1.普通形参(位置形参) 2.默认形参 3普通收集形参 4.命名关键字形参 5.关键字收集形参
实参的种类:
1.普通实参 2.关键字实参

原则:
形参和实参要一一的对应

 

1.普通形参(位置形参)

 #  定义函数 
 """  hang,lie普通形参,在函数定义处  """ 
 def  small_star(hang,lie):
i
= 0 while i < hang:
j
= 0 while j < lie: print ( " * " ,end= "" )
j
+=1 print ()
i
+= 1 # 调用函数 """ 10,10普通实参,在函数的调用处 """ small_star( 10,10 )
small_star(
2,3)

 

2.默认形参

 """  hang,lie默认形参,在函数定义处  """ 
 """  如果给予实参,那么使用实参
如果没有给予实参,那么使用参数身上的默认值
""" def small_star(hang=10,lie=10 ):
i
= 0 while i < hang:
j
= 0 while j < lie: print ( " * " ,end= "" )
j
+=1 print ()
i
+= 1 small_star( 4,8 )
small_star(
8 )
small_star()

 

3.普通形参 + 默认形参

 """  普通形参必须写在默认形参的前面不能调换位置  """ 
 def  small_star(hang,lie=10 ):
i
= 0 while i < hang:
j
= 0 while j < lie: print ( " * " ,end= "" )
j
+=1 print ()
i
+= 1 small_star( 5,7 ) # small_star(5) # small_star() error

 

4.关键字实参


1.如果都是关键字实参,可以任意调整实参的顺序
2.普通实参必须写在关键字实参的前面

 def  small_star(hang,a,b,c,lie=10 ):
i
= 0 while i < hang:
j
= 0 while j < lie: print ( " * " ,end= "" )
j
+=1 print ()
i
+= 1 # hang a ... lie 具体指定参数的值叫做关键字实参,在函数的调用处; # small_star(hang=3,a=4,b=5,c=6,lie=7) # small_star(b=5,c=6,lie=7,a=4,hang=3) small_star(3,4,b=5,c=6,lie=7 )
small_star(
3,4,b=5,lie=7,c=6 ) # small_star(b=5,c=6,lie=7,3,4) error

 

 

 

 

 

 

 收集参数

 

(1) 普通收集形参

专门用来收集那些多余的没人要的普通实参 收集之后,会把多余实参打包成一个元组 参数头上1个星星

def func(*args):
  pass
args => arguments

 def  func(a,b,c,* args):  print (a,b,c)  #  1 2 3 
     print (args)   #  (4,5,6) 
 func( 1,2,3,4,5,6 )  #  任意个数值得累加和 
 def  mysum(* args):
total
= 0 for i in args:
total
+= i print (total)
mysum(
1,2,3,4,4,45,10,100)

 

 

(2) 关键字收集形参

专门用来收集那些多余的没人要的关键字实参收集之后,会把多余关键字实参打包成一个字典,参数头上有2个星星

def func(**kwargs):

  pass
kwargs => keyword arguments

 

 def  func(a,b,c,** kwargs):  print  (a,b,c)  print (kwargs)  #  {'f': 100, 'e': 200, 'z': 12} 
func(c=1,a=3,b=10,f=100,e=200,z=12)

 

 

拼接任意个数值变成字符串

  
"""
班长: 赵万里
班花: 马春陪
划水群众: 赵沈阳,李虎凌,刘子涛
"""
def func(**kwargs):
strvar1 = ""
strvar2 = ""
# 定义职位信息
dic = {"monitor":"班长","classflower":"班花"}
print(kwargs)
# 共5次循环
for k,v in kwargs.items():
if k in dic:
# 将2次循环的结果通过+= 拼接在一起
strvar1 += dic[k] + ":" + v + "\n"
else:
# 将3次循环的结果通过+= 拼接在一起
strvar2 += v + " , "
print(strvar1.strip())
print("划水群众:",strvar2.strip(" , "))

"""
# print(k,v)
k v
monitor 赵万里
classflower 马春陪
water1 赵沈阳
water2 李虎凌
water3 刘子涛
{'monitor': '赵万里', 'classflower': '马春陪', 'water1': '赵沈阳', 'water2': '李虎凌', 'water3': '刘子涛'}
"""

func(monitor="赵万里",classflower="马春陪",water1="赵沈阳",water2="李虎凌",water3="刘子涛")
   

 

 

 

 

 

命名关键字参数

(1) def func(a,b,*,c,d) 跟在*号后面的c和d是命名关键字参数
(2) def func(*args,e,**kwargs) 加在*args和**kwargs之间的参数都是命名关键字参数

命名关键字参数 : 在调用函数时,必须使用关键字实参的形式来进行调用;

定义方法一

 def  func(a,b,* ,c,d):  print  (a,b)  print  (c,d)  #  必须指定关键字实参,才能对命名关键字形参进行赋值 
func(1,2,c=3,d=4)

 

定义方法二

 def  func(*args,e,** kwargs):  print (args)    #  (1, 2, 3, 4) 
     print (e)       #  3 
     print (kwargs)  #  {'a': 1, 'b': 2} 
func(1,2,3,4,a=1,b=2,e=3)

 

星号的使用

* 和 ** 如果在函数的定义处使用:* 把多余的普通实参打包成元组,** 把多余的关键字实参打包成字典


* 和 ** 如果在函数的调用处使用:* 把元组或者列表进行解包,** 把字典进行解包

 def  func(a,b,* ,c,d):  print  (a,b)  print  (c,d)

tup
= (1,2 ) # 函数的调用处 *号用法 func(*tup,c=3,d=4) # func(1,2,c=3,d=4) # 函数的调用处 **号用法 dic={ " c " :3, " d " :4 }
func(
1,2,**dic) # func(1,2,c=3,d=4) # 综合写法 # 函数的调用处 tup = (1,2 )
dic
={ " c " :3, " d " :4 }
func(
*tup,** dic) # 定义成如下形式,可以收集所有的实参 def func(*args,** kwargs): pass

 

总结:

当所有的形参都放在一起的时候,顺序原则:普通形参 -> 默认形参 -> 普通收集形参 -> 命名关键字形参 -> 关键字收集形参

 def  f1(a, b, c=0, *args, ** kw):  print ( '  a =  ' , a,  '  b =  ' , b,  '  c =  ' , c,  '  args =  ' , args,  '  kw =  '  , kw)  def  f2(a, b, c=0, *, d, ** kw):  print ( '  a =  ' , a,  '  b =  ' , b,  '  c =  ' , c,  '  d =  ' , d,  '  kw =  '  , kw)

# 以上两个函数 打印结果 # (一) f1(1, 2) # a =1 b=2 c=0 args=() kw={} f1(1, 2, c=3) # a=1,b=2,c=3,args=() kw={} f1(1, 2, 3, ' a ' , ' b ' ) # a=1 b=2 c=3 args=(a,b) kw={} f1(1, 2, 3, ' a ' , ' b ' , x=99) # a=1 b=2 c=3 args=(a,b) kw={x:99} f2(1, 2, d=99, ext=None) # a=1 b=2 c=0 d=99 kw={ext:None} # (二) args = (1, 2, 3, 4 )
kw
= { ' d ' : 99, ' x ' : ' # ' } # f1(1,2,3,4,d=99,x=#) f1(*args, **kw) # a=1 b=2 c=3 args=(4,) kw={d:99,x:#} # (三) myargs = (1, 2, 3 )
mykw
= { ' d ' : 88, ' x ' : ' # ' } # f2(1,2,3,d=88,x=#) f2(*myargs, **mykw) # a=1,b=2,c=3 d=88 kw={x:#} # (四) def f1(a, b, c=0, *args,d,** kw): print ( ' a = ' , a, ' b = ' , b, ' c = ' , c, ' args = ' , args, ' kw = ' , kw) print (d)

f1(
1,2,3, ' a ' , ' b ' ,d=67, x=99,y=77) # a=1 b=2 c=3 args=(a,b) kw={x:99,y:77} # d=67

 

 



 

 

 

return 自定义函数的返回值

 

概念:return 把函数内部的数据返回到函数的外面,返回到函数的调用处
1.return + 六大标准数据类型 , 除此之外还可以返回函数 或者 是类对象
2.return 在执行时,意味着终止函数,后面的代码不执行.
3.如果不定义return返回值,默认返回None

(1) return + 六大标准数据类型

 def  func():  #  return 111 
     #  return 6.89 
     #  return "你好帅啊,我爱死你乐" 
     #  return [1,2,3] 
     #  return {"a":1,"b":2} 
     return  1,2,3  #  返回元组 
res = func()  print (res)

 

(2) return 在执行时,意味着终止函数,后面的代码不执行.

 def  func():  print (1 )  print (2 )  return  3
     print (4 )
res
= func() print (res) def func(): for i in range(5 ): if i == 3 : return 4 print (i)
res
= func() print (res)

 

(3) 如果不定义return返回值,默认返回None

 def  func():  pass  res = func()  print (res)  #  None 
    
 #  注意点 打印的数据和返回的数据不是等价的,返回的数据是可以自定义的; 
res =  print (1234 )  print (res)   #  None 

 

模拟+-*/计算器

 

 """  功能:   完成计算
参数: 2个数字和运算符
返回值: 计算后的结果
""" def calc(num1,num2,sign): if sign == " + " : return num1 + num2 elif sign == " - " : return num1 - num2 elif sign == " * " : return num1 * num2 elif sign == " / " : if num2 == 0: return " 除数不能为零 " return num1 / num2 else : return " 抱歉,超出了我的运算范围. " res = calc(3,5, " + " )
res
= calc(3,5, " - " )
res
= calc(3,5, " * " )
res
= calc(3,0, " / " )
res
= calc(3,0, " & " ) print (res)

 

全局变量和局部变量

1.概念
局部变量:在函数内部定义的变量就是局部变量
全局变量:在函数外部定义的变量或者在函数内部使用global关键字声明是全局变量

2.作用域:
局部变量的作用范围仅仅在函数的内部
全局变量的作用范围横跨整个文件

3.生命周期:该变量的作用时长
内置命名空间 -> 全局命名空间 -> 局部命名空间 (开辟空间顺序)
内置属性 > 全局属性 > 局部属性 (作用时长:长->短)

 

 

 

1 局部变量

def func():
# 定义一个局部变量
a = 1
# 获取当前的局部变量
print(a)
# 修改一个局部变量
a = 2
print(a)

func()
# print(a) error

 

2.全局变量

 #  定义一个全局变量 
b = 10
 #  获取当前的全局变量 
 print  (b)  #  修改一个全局变量 
b = 20
 print  (b)  def  func():  print  (b)
func()

 

3.函数内部定义全局变量

 def  func():  global  c
c
=30 func() print (c)

 

4.函数内部修改全局变量

d = 50
 def  func():  global  d
d
= 51 func() print (d)

 

总结:

global的使用如果当前 不存在 全局变量,可以在函数内部通过global关键字来定义全局变量,如果当前 存在 全局变量,可以在函数内部通过global关键字来修改全局变量

 

函数名的使用

python中的函数可以像变量一样,动态创建,销毁,当参数传递,作为值返回,叫第一类对象.其他语言功能有限

def func():
  print( "我是func函数")

 

(1)动态创建

a = 1
 print  (a)
a
= func
a()

 

(2)动态销毁

 del  a  #  a()  #  func() 

 

(3)当参数传递

 def  func2():  return   "  我是func2函数  " 

 def  func1(f):  return  f()  #  "我是func2函数" 
 res = func1(func2)  print (res)

 

(4)作为值返回

 def  func3():  print (  "  我是func3函数  "  )  def  func4(f):  return  f
res
= func4(func3) print (res)
res()

 

 

 

(5)函数名可以作为容器类型数据的元素

lst = [func,func3]  for  i  in  lst:
i()

 

__doc__ 或者help查看文档

 def  big_chang_cishen(something):  """  功能: 教你怎么吃大肠
参数: 吃的内容
返回值: 是否满意
""" print ( " 把{}洗一洗 " .format(something)) print ( " 直接找肠子头,放嘴里,吸一下 " ) print ( " 擦擦嘴,满意的放下肠子头 " ) return " 吃完了,真好吃~ " big_chang_cishen( " 生肠子 " ) # 方法一 res = big_chang_cishen. __doc__ print (res) # 方法二 help(big_chang_cishen)

 

函数的嵌套

互相嵌套的两个函数:包裹在外层的叫做外函数,内层的就是内函数

 def  outer():  #  inner() 
     def  inner():  print ( "  我是inner函数  " )


# (1)内部函数可以直接在函数外部调用么 不行
# inner()
# (2)调用外部函数后,内部函数可以在函数外部调用吗 不行
# outer()
# inner()
# (3)内部函数可以在函数内部调用吗 可以
outer()
# (4)内部函数在函数内部调用时,是否有先后顺序 有的
# 先定义在调用
# 在其他语言中有预加载的机制,提前把函数驻留到内存中,然后再去编译脚本内容
# python没有预加载函数的机制,只能先定义在调用;

外函数是outer  中间函数是inner  最里层是smaller ,调用smaller函数

 def  outer():  def  inner():  def  smaller():  print ( "  我是smaller函数  "  )
smaller()
inner()
outer()

 

LEGB 原则

 def  outer():  def  inner():  def  smaller():  print  (a)
smaller()
inner()
outer()

LEGB原则(就近找变量原则)
找寻变量的调用顺序采用LEGB原则(即就近原则)
B —— Builtin(Python);Python内置模块的命名空间 (内建作用域)
G —— Global(module); 函数外部所在的命名空间 (全局作用域)
E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
L —— Local(function);当前函数内的作用域 (局部作用域)
依据就近原则,从下往上 从里向外 依次寻找

 

nonlocal的使用 (用来修改局部变量)

nonlocal遵循LEGB原则
(1) 它会找当前空间上一层的变量进行修改
(2) 如果上一层空间没有,继续向上寻找
(3) 如果最后找不到,直接报错

 

(1)它会找当前空间上一层的变量进行修改

 def  outer():
a
= 10 def inner():
nonlocal a
a
= 20 print (a)
inner()
print (a)
outer()

 

(2)如果上一层空间没有,继续向上寻找

 def  outer():
a
= 20 def inner():
a
= 15 def smaller():
nonlocal a
a
= 30 print (a)
smaller()
print (a)
inner()
print (a)
outer()

 

(3)如果最后找不到,直接报错

'''nonlocal 只能修改局部变量'''

a = 20
 def  outer():  def  inner():  def  smaller():
nonlocal a
a
= 30 print (a)
smaller()
print (a)
inner()
print (a)
outer()
error

 

(4) 不通过nonlocal 是否可以修改局部变量呢?ok

 def  outer():
lst
= [1,2,3 ] def inner():
lst[
-1] = 3000 inner() print (lst)
outer()

 

闭包函数

互相嵌套的两个函数,如果内函数使用了外函数的局部变量,并且外函数把内函数返回出来的过程叫做闭包。

里面的内函数叫做闭包函数

是不是闭包?
1.内函数用了外函数的那个局部变量
2.外函数返回内函数

 

1.基本语法形式

 def  zhaoshenyang_family():
father
= " 马云 " def hobby(): print ( " 我对钱没有一丝丝的兴趣,我不看重钱,这是我爸爸{}说的 " .format(father)) return hobby

func
= zhaoshenyang_family()
func()

 

 

2.闭包的复杂形式

 def  zhaowanli_family():
gege
= " 王思聪 " didi = " 鞋王,高振宁 " money = 1000 def gege_hobby():
nonlocal money
money
-= 500 print ( " 我交朋友不在乎他有没有钱,反正都没有我有钱.我就喜欢交女朋友... 钱物还剩下{} " .format(money)) def didi_hobby():
nonlocal money
money
-= 400 print ( " 家里有鞋柜,各式各样的奢侈鞋,一双大概20~30万,钱物还剩下{} " .format(money)) def big_master(): return [gege_hobby,didi_hobby] return big_master

func
= zhaowanli_family() print (func)
lst
= func() print (lst) # 获取哥哥函数 gege = lst[0]
gege()
# 获取弟弟函数 didi = lst[1 ]
didi()

 

 

 

3.使用 __closure__ , cell_contents 判定闭包

 """  如果返回的元组中有数据说明是闭包,谁的生命周期被延长就打印谁  """  tup = func. __closure__ 
 print  (tup)  #  先获取第一个单元格  cell_contents获取对象中的内容 
func1 = tup[0].cell_contents  print ( "  <11111>  "  )  """  打印闭包函数didi_hobby中,生命周期被延长的属性  """ 
 print (func1. __closure__  [0].cell_contents)
func1()
# 在获取第二个单元格 cell_contents获取对象中的内容 func2 = tup[1 ].cell_contents print ( " <22222> " ) """ 打印闭包函数gege_hobby中,生命周期被延长的属性 """ print (func2. __closure__ [0].cell_contents)
func2()

 

 

闭包特点

特点:在闭包函数中,内函数使用了外函数的局部变量,该变量会与内函数发生绑定,延长该变量的生命周期,持续到脚本执行结束.(生命周期和全局变量一样长,但不是全局变量)

 def  outer(val):  def  inner(num):  return  val + num  return  inner

func
= outer(10 )
res
= func(15 ) print (res)

 

 

 

 

 

闭包的意义

全局变量的作用域大,容易被篡改

num = 0  def  click_num():  global  num
num
+= 1 # num = num + 1 print (num)
click_num()
click_num()
click_num()
num
= 100 click_num()
click_num()

 

改造,用闭包来实现

闭包的意义:闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.

 def  outer():
x
= 0 def click_num():
nonlocal x
x
+= 1 print (x) return click_num

click_num
= outer()
click_num()
click_num()
click_num()
x
= 100 click_num()
click_num()

 

匿名函数 lambda表达式

用一句话来表达只有返回值的函数

语法:   lambda  参数:返回值

特点: 简介,高效

 

(1)无参的lambda表达式

 def  func():  return   "  文哥是个帅哥  " 

改造

func =  lambda  :  "  文哥是个帅哥  " 
 print (  func()  )

(2)有参的lambda表达式

 def  func(n):  return  id(n)

改造

func =  lambda  n : id(n)  print ( func(100) )

 

(3)带有判断条件的lambda表达式

 def  func(n):  if  n % 2 == 0:  return   "  偶数  " 
     else  :  return   "  奇数  " 

改造

func =  lambda  n :  "  偶数  "   if  n % 2 == 0  else   "  奇数  " 
 print ( func(44) )

三元运算符

只能表达双向分支 只有if else 比较固定 不灵活的语法 

语法: 真值 if 条件表达式 else 假值
如果条件表达式成立为True , 返回if前面的真值,反之,返回else后面的假值

n = 13 res =  "  偶数  "   if  n % 2 == 0  else   "  奇数  " 
 print (res)

 

小练习 : 比较两者之间的最大值进行返回

 def  func(x,y):  if  x > y:  return  x  else  :  return  y

改造


func =  lambda  x,y : x  if  x>y  else  y  print (  fu

标签: python

添加新评论