python--函数初识

一,函数的概念、作用

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

 

定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

特性:

1.减少重复代码

2.使程序变的可扩展

3.使程序变得易维护

二,函数的定义  

1.定义       

def mylen():
    '''计算s1的长度'''
    s1 = "hello world"
    length = 0
    for i in s1:
        length+=1
    return length

def my_len():

  def 关键字 定义一个函数
  my_len 函数名书写规则与变量一样。
  def 与函数名中间一个空格。
  函数名():加上冒号
  函数体

注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
调用:就是 函数名() 要记得加上括号。
2.return关键字

1,在函数中,遇到return结束函数。
2,将值返回给函数的调用者。
  无 return
  return None
  return 1个值 该值是什么,就直接返回给函数的调用者,函数名()
  return 多个值 将多个值放到一个元组里,返回给函数的调用者。

三,函数的传参

函数传参:我们给函数传参,告诉函数我们想计算谁的长度
def mylen(s1,):
    '''计算s1的长度'''
    length = 0
    for i in s1:
        length = length+1
    return length   #函数遇到return之后,结束整个函数。
str_len = mylen('qwer')
print('str_len : %s'%str_len)
#参数分为:实参和形参;这里写的'qwer'是要实际交给函数的内容,而s1只是个变量的名字,在定义函数时,只是个形式;所以叫形参。
#参数可以传递多个,多个参数之间用逗号分隔。
def mymax(x,y):
    the_max = x if x>y else y   #三元运算(判断代码简写);lambda表达式,(函数代码简写)
    return the_max
ma = mymax(10,20)
print(ma)
引言

两方面:

实参角度:
  1,位置传参。按顺序,一一对应。(实参和形参的个数是相同的。)

  def func(a,b,c):
   print(a)
   print(b)
   print(c)
  func('fdsafdas',3,4)

  2,关键字传参,不按顺序,一一对应。

  def max_min(a,b):
  return a if a > b else b
  print(max_min(b = 300,a = 200))

  3,混合传参,关键字参数永远在位置参数后面。

  def func1(a,b,c,d,e):

    print(a)

    print(b)
    print(c)
    print(d)
    print(e)
  func1(1,2,d=4,c=3,e=5)

形参角度
  1,位置传参。按顺序,一一对应。

  2,默认参数。传参则覆盖,不传则默认,默认参数永远在位置参数的后面。

    (为什么要有默认参数:将变化比较小的值设置成默认参数)

  def func(a,b=666): 
    print(a,b)
    func(1,2)
    func(1,777)
  func(1,2)

默认参数的陷阱:默认参数是一个可变数据类型,  使用的是同一个参数。

def func(val,list = []):

  list.append(val)

  return list

list1 = func(10)
list2 = func(123,[])
list3 = func('a')

print('list1 =%s'%list1)
print('list2 =%s'%list2)
print('list3 =%s'%list3)

执行的结果是:

  list1 =[10,'a']  #因为是使用同一个参数,之前的10不会去掉。

  list1 =[123]

  list1 =[10,'a']

 3,动态参数(不定长参数)
def trans_para(*args,**kwargs):
print(args,type(args))
print(kwargs,type(kwargs))
trans_para("qwe",12,[]),{'':''}
arges是元组形式,接收去除关键字以外的所有参数,
**kwargs接收的只有关键字参数,并保存在字典中。
形参角度最终顺序:(位置参数,*args,默认参数,**kwargs)  
实参角度(关键字参数在位置参数之后)    

四,*    的应运

在函数调用时:
*可迭代对象,代表打散(list,tuple,str,dict的(键))将元素一一添加到args。
def func(*args):
    print(args)
l1 = [1,2,3,30]
l2 = [1,2,33,21,45,66]
func(*l1,*l2)
func(*{'name':'alex',"age":12})#字典的话,返回的只有keys
**字典,代表打散,将所有键值对放到一个kwargs字典里。
def func(**kwargs):
    print(kwargs)
dic1 = {'name1':'alex','age1':46}
dic2 = {'name':'老男孩','age':56}
func(**dic1,**dic2)
在函数定义时,*args,**kwargs代表的是聚合(将所有实参合成一个传给形参)
def func(*args,**kwargs):
     print(args)
     print(kwargs)

 dic1 = {'name1':'alex','age1':46}
 dic2 = {'name':'老男孩','age':56}
 func(*[1,2,3,4],*'asdfsad',**dic1,**dic2)

五、名称空间

  1.分为全局,临时,内置名称空间。

    全局名称空间:又叫全局命名空间。

    局部名称空间:又叫临时名称空间。

    内置名称空间:所有的内置函数存储的空间。

  2.加载顺序:

    内置名称空间 ---> 全局名称空间--->(函数执行时)局部名称空间。
  3.取值顺序:
    函数执行时:局部名称空间 -->全局名称空间 -->内置名称空间
  

  4.全局作用域,局部作用域。

    全局作用域:全局名称空间,内置名称空间
    局部作用域:局部名称空间

 六,globals、locals 和关键字global、nonlocal

    globals:全局名称空间的所有变量  将变量放在一个字典中。

    locals:局部名称空间的所有变量  将变量放在一个字典中。

a = 2
b = 3
def func():
    c = 5
    d = 6
    print(globals())
    return locals()
print(func)

    关键字global、nonlocal  (适用于str和int  ;list,dic,tuple不用改直接引用)

  1.global :1.在局部空间内,声明一个全局变量;2.在局部空间内改变一个全局变量。

def func():
    global name    #注释掉global,则会报错;
    name = '老男孩'
    print(name)
func()
print(name)    定义global则会创建一个全局name变量;打印两边。

  2.nonlocal:

  1.不能修改全局变量。

a = 4
def func1():
    a = 5
    #nonlocal a
    return a
print(func1())
print(a)

  2.在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,

    并且引用的哪层,从那层(即父层)及以下此变量全部发生改变。

def add_b():
    b = 42
    def do_global():
        b = 10
        print(b)
        def dd_nonlocal():
            nonlocal b
            b = b + 20
            print(b)
        dd_nonlocal()
        print(b)
    do_global()
    print(b)
add_b()

 ps:

b = 4
def func1():
    #global b    #global之后b就是一个全局变量了。(在局部空间内,声明一个全局变量)
    b = 6
    def func2():
        nonlocal b    #不能修改全局变量。
        b = 666
        print(b)
    func2()
    print(b)
print(b)
func1()

七,函数的嵌套

    函数什么时候执行? 函数调用的时候执行。
     代码从上至下依次执行, 调用函数:函数里面从上至下依次执行。

 八,函数名的应用

  1.单独打印函数名,返回的是函数的内存地址。

def func1():
    print(666)
print(func1)

结果是:<function func1 at 0x0000000000937F28>
View Code

  2.函数名的赋值

def func():
    print(777)
f = func
print(f())

结果:666
        None
View Code

  3.函数名可以作为容器类数据的元素。eval函数的功能:

l1 = ['f1', 'f2', 'f3', 'f4']  for i in l1:eval(i)  里面的元素是什么就是什么;(会把‘’去掉)

def f1():
    print(1211)

def f2():
    print(1222)

def f3():
    print(1233)

def f4():
    print(1233)

l1 = [f1, f2, f3, f4]
 for i in l1:
    i()
View Code

  4.函数名作为参数

def f1():
    print(666)
def f2(x):
    x()
f2(f1)
View Code

  5.函数名作为返回值

def f1():
    print(666)
def f2(f1):
    return f1
ret = f2()
ret()
View Code

 

 

 

 

 



posted @ 2018-03-30 21:45  纸上得来终觉浅,  阅读(113)  评论(0)    收藏  举报