武道之路,Python全栈开发

By admin in 4858.com on 2019年2月12日

1、函数是逻辑结构化和进度化的一种编程方法

本节内容

  1. 函数基本语法及特点

  2. 参数与局地变量

  3.递归

  4.函数式编程介绍

  5.高阶函数

 

武道之路-炼体期五重天,之路五重

函数:

职能:代码重用性,数据一致性,可移植和伸张。

在python3.x中 进度和函数都以 def 函数名(形参):
如此定义,而差别是函数有return
再次来到值,而经过没有,可是暗许重回None,return
可以回来两个值,用逗号隔开(实际上是一个元组),return
还有截至函数运行的机能。

函数调用:先定义函数,对应传参才能调用(一般定义的形参个数必须超出等于传入的实参个数,因为只怕会有专断认同参数,参数组会除外,即是
*args(元组),**kwargs(字典)),传参有岗位传参和严重性字传参,

参数组:首要用以不确定实参传入个数时,或是间接想传入元组或是字典。

暗中同意参数:形参地方有暗中同意值,不传此地方的参数,会基于暗中同意值统计,否则按传入的持筹握算    

例: def test(x,y,z):

    ”’ 一般那里写注释”’

    print(x,’—‘,y,’—‘,z)

    return ‘test—-‘

地方传参调用: test(2,4,5)->一一对应x,y,z

根本字传参:test(y=2,x=4,z=8),找到相应的形参名并赋值 

当混用二者时,地方传参在面前(必须对应传参才能调用) 如: test(2,z=6,y=3)

*args  如:

def test1(x,*args):

    print(x,’—‘,args)

    return ‘test1—-‘

可test1(2,4,5,6)->x=2 args:(2,4,6); 即是把剩余的地方传参变成元组

还可test1(2)->x=2,args:(),不传为暗许空元组,test1(x=3,*[2])->x=3,args:(3,);test1(6,*(2,5))->x=6,args:(2,5)

**kwargs 如:

  def test3(x,y=6,**kwargs):

    print(x,’—‘,y,’—‘,kwargs)

    return ‘222’

test3(6,name=’ddd’,kk=’gg’)->x=6,y暗中同意为6,kwargs位{‘name’:’dd’,’kk’:’gg’},即是把对应多的要害字传参变成key=>value对应的字典,注意:须求传入字典的key最好永不和任何形参相同名,不然会报多传的荒谬的。

test3(y=3,x=5,mm=’fff’)->x=5,y=3,kwargs:{‘mm’:’fff’};test3(7,1)->x=7,y=1,kwargs:{};test3(x=3,3,**{‘name’:’55’})->x=3,y=3,kwargs:{‘name’:’55’}

 

3.x 全局变量及一些变量:

全局变量:一般在程序一流定义的变量就是全局变量,而在子程序(一般是函数)里定义的变量一般是有的变量,如若同名,在局地成效域里有些变量起效果,反之亦然。

当全局变量是相比较复杂的品种(一般是列表,字典,集合)时,在函数中是可以直接修改了全局变量

当全局变量是纯净类型(字符,数字等)时,在函数中可用 global
重新定义全局变量名
就可修改(一般不提出如此,因为大概不亮堂函数被调用四遍)

在函数内可定义全局变量(间接 global 变量名),一般不提议如此。

 

函数:
功用:代码重用性,数据一致性,可移植和扩张。 在python3.x中
进程和函数都以 def 函数名(形参…

一 怎么要有函数?

python中函数定义使用首要字def来定义

1.函数大旨语法及特色

 三种编程范式:

   1、面向进程:进度——> def

   2、面向对象:类——> class

   3、函数式编程:函数——> def

不加区分地将享有机能的代码垒到一头,难题是:

def test(x):

 

  代码可读性差
  代码冗余
  代码可扩充差

 ”the function definitions”

函数是何等?

函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不一致的,编程中的函数在英文中也有过多不一的叫法。在C中唯有function,在Java里边叫做method。

什么样消除?
  函数即工具,事先准备工具的进度是概念函数,拿来就用指的就是函数调用

     x+=1

概念: 函数是指将一组语句的聚集通过一个名字(函数名)封装起来,要想举行那几个函数,只需调用其函数名即可

采纳函数的补益:

  1. 减掉重复代码
  2. 使程序变的可增加
  3. 使程序变得易维护

  结论:函数使用必须是:先定义,后调用

     return x

语法定义

1
2
3
4
5
def test(x):#函数定义方法、函数名、变量
  '''The function difinition!''' #对该函数的描述  
  x+=1 #函数体
  return x  #返回值
test(1) #调用函数

函数:

  def func1():

    ”’testing1”’

武道之路,Python全栈开发。    print(‘in the func1’)

    return 0

过程: 

  def func2():

    ”’testing2”’

    print(‘in the func2’)

由上得出,进度即使没有重临值的函数。

 

可以带参数

1
2
3
4
5
6
7
8
9
10
11
12
13
#下面这段代码
a,b = 5,8
= a**b
print(c)
 
 
#改成用函数写
def calc(x,y):
    res = x**y
    return res #返回函数执行结果
 
= calc(a,b) #结果赋值给c变量
print(c)

 

return的作用

  1、终止函数的运作,即return前面的代码都将不会被实施

  2、return给调用该函数的岗位,重返一个值。如,x=test1(),x就会接到到return的重临值

  3、后续程序有时要求依照在此之前函数return重回值的例外,举办不一致的判定和运算。

return的再次回到值

  return 1, ‘hello’, [‘alex’,’wupeiqi’], {‘name’:’alex’}

  所以,return的个数没确定,类型没规定。把return前面的故事情节放入元组中全体重回,本质上return仍旧回到了一个值。即使从前有一个函数def
test():, 用return test  时,重临值是test函数的内存地址。

 

python中函数定义方法:

def:定义函数的主要字

2.函数参数与局地变量

调用方法:

  1、test()执行,()表示调用函数test,()可以有参数也可以没有

参数

  1、形参和实参

  形参:形式参数,不是实际存在的,是虚拟变量,在概念函数和函数体的时候利用形参,目标是在函数调用时吸收实参(实参个数、类型应与形参一一对应)

  实参:实际参数,调用函数时传给函数的参数,可以是常量,变量,表明式,函数,传给形参

 

  分歧:形参是编造的,不占用内存空间,形参变量唯有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传送给形参,不可以形参传给实参。

  2、关键字调用,与形参顺序毫无干系;地点调用与形参一一对应。

    【注意】:关键字参数不可能写在义务参数此前

  3、默许参数

    def test(x,y=2):

      print(x,y)

    test(1)

    上述代码在概念函数时对形参赋值的经过叫做设置暗中认可参数,被赋的值叫做对应形参的私行认同参数。

    暗许参数特点:调用函数时,默许参数非必须传递

  4、参数组:

    1)def test(*args):

       print(args)

      test(1,2,3,4,5)  #依然等价于前面那种赋值格局:
test(*[1,2,3,4,5])

      输出:(1,2,3,4,5)

      那时候会把5个岗位实参全体传给形参args,并且以元组的款式保留下来。定义地点调用参数组时,以*起初即可,args的名字可以是随机的。但编制规范就是*args。

    2)def test2(**kwargs):

        print(kwargs)

      test2(name=’gavin’,age=25,sex=’M’) #抑或等价于前边那种赋值情势:
test2(**{‘name’:’gavin’,’age’:25,’sex’:’M’})

      输出:{‘name’:’gavin’,’age’:25,’sex’:’M’}

      那时候会把3个重点字调用的实参全体传递给形参kwargs,并且以字典的形式保留,关键字为key,给关键字赋的值为value。定义关键字调用参数组时,以**千帆竞发,kwargs的名字可以是随便的,可是编写规范就是**kwargs。

    3)小结:

      *args把N个义务参数,转换成元组的措施

      **kwargs把N个根本字参数,转换成字典的格局

      【注意】: 参数组肯定要放在形参的最后面

           地点参数一定要写在重大字参数此前。所以对应的,形参部分先写*args,再写**kwargs。

      

    def test(x):
    ”The function definitions”
    x+=1
    return x

test:函数名称

 局地变量 

1
2
3
4
5
6
7
8
9
10
name = "Alex Li"
 
def change_name(name):
    print("before change:",name)
    name = "金角大王,一个有Tesla的男人"
    print("after change", name)
 
change_name(name)
 
print("在外面看看name改了么?",name)

输出

1
2
3
before change: Alex Li
after change 金角大王,一个有Tesla的男人
在外面看看name改了么? Alex Li

 

大局与一些变量

在子程序中定义的变量称为局地变量,在程序的一开始定义的变量称为全局变量。

全局变量成效域是全体程序(包含拥有函数的中间),局部变量成效域是概念该变量的子程序。

当全局变量与局地变量同名时:

在概念局地变量的子程序内,局地变量起效果;在别的地点全局变量起效果。

 

在函数内修改全局变量

  name=‘gavin

  def change_name(name):

    global name

    name=’Gavin Simons’

    pass

  chang_name(name)

  在上述那种情景下,在函数内部使用global指令,注明了name为全局变量,此时在函数内部再修改name时,修改的是全局变量。同时如果在函数内部宣称全局变量以前,即在文件初步并从未一样名字的全局变量,则函数内的全局变量会被新创立,在函数外部也得以展开调用。可是,即便如此可行,但是永远不要那样干(包罗在函数内修改全局变量和在函数内创建全局变量),因为这么做很难去调节,不明白是相当函数创制或修改了全局变量。

 

有的变量和全局变量的很是意况

   names=[‘Gavin’,’Simons’,’Jack’,’Rain’]

  def chang_name():

    names[0] = ‘詹姆士Symons’

    print(‘inside func’,names)

  change_name()

  print(names)

   输出:inside func [‘JamesSymons’,’Simons’,’杰克’,’Rain’]

     [‘詹姆士Symons’,’Simons’,’杰克’,’Rain’]

  所以唯有像简单的数据类型(比如,字符串和整数)是不可能在函数中修改的。可是复杂的数据类型(比如,列表、字典、集合、类,元组在怎么样时候都不能改)这么些都以在局地里面可以直接改全局的。因为存放格局和简易数据类型差异,后者存放的是位置,而不是切实可行的值。

    

  def:定义函数的关键字
  test:函数名
  ():内可定义形参
  ””:文档描述(非需求,不过强烈提议为您的函数添加描述消息)
  x+=1:泛指代码块或程序处理逻辑
  return:定义再次来到值

():内可以定义形参

3. 递归

在函数内部,可以调用其余函数。假诺一个函数在里边调用自家自个儿,那个函数就是递归函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
def calc(n):
    print(n)
    if int(n/2==0:
        return n
    return calc(int(n/2))
 
calc(10)
 
输出:
10
5
2
1

递归性情:

  1. 必须有一个由此可见的扫尾条件

  2. 历次进入更深一层递归时,难题规模比较上次递归都应有所削减

3.
递归效用不高,递归层次过多会导致栈溢出(在计算机中,函数调用是经过栈(stack)那种数据结构已毕的,每当进入一个函数调用,栈就会加一层栈帧,每当函数重返,栈就会减一层栈帧。由于栈的分寸不是出色的,所以,递归调用的次数过多,会招致栈溢出)

堆栈扫盲 

 

递归函数实际使用案例,二分查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
data = [1367912141617182021222330323335]
 
 
def binary_search(dataset,find_num):
    print(dataset)
 
    if len(dataset) >1:
        mid = int(len(dataset)/2)
        if dataset[mid] == find_num:  #find it
            print("找到数字",dataset[mid])
        elif dataset[mid] > find_num :# 找的数在mid左面
            print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)
        else:# 找的数在mid右面
            print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
            return binary_search(dataset[mid+1:],find_num)
    else:
        if dataset[0== find_num:  #find it
            print("找到数字啦",dataset[0])
        else:
            print("没的分了,要找的数字[%s]不在列表里" % find_num)
 
 
binary_search(data,66)

  

调用运行:可以带参数也可以不带
函数名()

x+=1:代码块或程序处理逻辑

4.函数式编程介绍  

 

函数是Python内建接济的一种包装,大家经过把大段代码拆成函数,通过一层一层的函数调用,就可以把纷纭义务分解成不难的天职,那种解释可以称呼面向进程的程序设计。函数就是面向进度的顺序设计的基本单元。

函数式编程中的函数这一个术语不是指总括机中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的照射。相当于说一个函数的值仅决定于函数参数的值,不借助于其余情形。比如sqrt(x)函数总计x的平方根,只要x不变,不论何时调用,调用一次,值都以不变的。

 

Python对函数式编程提供一些协助。由于Python允许行使变量,由此,Python不是纯函数式编程语言。

一、定义

简言之说,”函数式编程”是一种”编程范式”(programming
paradigm),约等于何等编写程序的方法论。

重点思想是把运算进程尽量写成一五种嵌套的函数调用。举例来说,以后有诸如此类一个数学表明式:

  (1 + 2) * 3 – 4

价值观的进度式编程,只怕那样写:

  var a = 1 + 2;

  var b = a * 3;

  var c = b – 4;

函数式编程须要采用函数,我们得以把运算进程定义为不一样的函数,然后写成上面那样:

  var result = subtract(multiply(add(1,2), 3), 4);

之所以,函数式编程的代码更易于精晓。

要想学好函数式编程,不要玩py,玩Erlang,Haskell。

    

 

return:定义重临值

5.高阶函数

变量可以针对函数,函数的参数能接受变量,那么一个函数就足以选择另一个函数作为参数,那种函数就叫做高阶函数。

即把函数本身作为一个参数,传给另一个函数。

1
2
3
4
5
6
def add(x,y,f): #f为一个函数形参
    return f(x) + f(y)
 
 
res = add(3,-6,abs)#abs是函数实参,其实就是函数abs的内存地址
print(res)

 

二:函数的分类

 

  1.平放函数:built-in
  2.自定义函数:
    def 函数名(参数1,参数2,…):
      ”’注释”’
      函数体

2、函数的性状:

函数的行使:先定义,后调用
如何定义函数之定义函数的二种格局
1
定义无参函数
:函数的履行不正视于调用者传入的参数就能执行时,需求定义为无参函数

1、代码的重用性

def print_tag():
print(‘*************************’)

2、保持一致性

def main():
print_tag(‘*’,20,3)
print_msg(‘hello world’)
print_tag(‘*’,20,3)

3、可增添性

main()

 

2
定义有参数
:函数的实施必要看重于调用者传入的参数才能进行时,须求定义为有参函数

3、函数和进度:

def print_tag(tag,count,line_num):
for i in range(line_num):
print(tag*count)

进程定义:进度就算简单特殊没有重返值的函数

3 定义空函数:函数体为pass

当一个函数、进程并未选择return突显定义重返值时,python解析器会隐式的回到None,所以在python中

def func(x,y,z):
pass

纵使是经过也足以算做是函数

三:函数的应用规则
  函数的采纳必须遵守:先定义后使用的口径
  函数的定义,与变量的概念是形似的,假若没有优先定义函数而直白引用就相当于在引用一个不设有变量名  

 

#概念阶段:只检测语法,不举办代码

4、参数组:

def func():
if 1>2
print(‘hahahahahahah’)
def func():
      #语法没难题,逻辑有标题,引用一个不设有的变量名
asdfasdfasdfasdfasdf

def test(*args):

#调用阶段

*args:表示一个参数组

foo()

在调用在函数的时候,传递有参数能够是1个或三个

重回值:可以回去任意档次

test(1,2,3,4,5,6)

没有return:None
return value: value
return val1,val2,val3 :(val1,val2,val3)

test(*[1,2,3,4,5])

return的效果:只能回到一次值,终止函数的实践

那种方法:*args:接受N个地点参数,转换成元组方式

返回值:

 

   重回值数=0:重返None

def test(**kvargs):

   再次来到值数=1:重临object

test(name=”zhangsan”,age=”20″)

   重临值数>1:重返tuple

那种方法:**kwargs:接受N个关键字参数,转换成字典的措施

四:函数参数

 

4858.com 1

1.形参变量唯有在被调用时才分配内存单元,在调用截止时,即刻释放所分配的内存单元。由此,形参只在函数内部有效。函数调用截至再次来到主调用函数后则不可以再使用该形参变量

2.实参能够是常量、变量、表明式、函数等,无论实参是何连串型的量,在进展函数调用时,它们都必须有规定的值,以便把这几个值传送给形参。因而应事先用赋值,输入等形式使参数得到确定值

3.义务参数和重点字(标准调用:实出席形参地方一一对应;关键字调用:地方无需固定)

4.暗许参数

5.参数组

函数参数分类:

 1、地点参数(形参、实参)

职位参数:依照从左到右的一一依次定义的参数
  def foo(x,y):
  print(x)
  print(y)
按任务定义的形参,必须被传值,多一个格外,少一个也尤其
  foo(1,2,3)===>报错
按职责定义的实参,与形参一一对应
  foo(2,10)

2、关键字参数 (实参)

重大字参数:实参在概念时,根据key=value方式定义
  def foo(x,y):
  print(x)
  print(y)
  # foo(y=10,x=1)
  foo(y=10,x=1)
#关键字参数可以不用像地点实参一样与形参一一对应,指名道姓地传值

  #  foo(1,z=20,10)  
===>报错

  # foo(1,y=2,z=10)
 
===>报错**

只顾的题材一:地点实参必须在首要字实参的眼下
小心的标题二:实参的款型既可以用地方实参又有啥不不过相当主要字实参,但是一个形参不能够再次传值

 3、私行认同参数(形参)

暗中认同参数:在概念函数阶段,就早已为形参赋值,定义阶段有值,调用阶段可以不用传值

定义:

# def func(x,y=10):
# print(x)
# print(y)

调用:

# func(1,20)
# func(1)

# def func(y=10,x):
# print(x)
# print(y)

 形参的行使:值平常变化的急需定义成职分形参,值一大半意况下都同一,须求定义成默许参数

暗中认可参数必要专注的难题一:必须放在地方形参前边
暗许参数须要小心的题材二:暗中同意参数平常要定义成不可变类型
暗许参数必要小心的题材三:暗许参数只在概念阶段被赋值四次

4、可变长参数

可变长参数:可变长指的是实参的个数不定点

按职分定义的非关键字可变长度的实参:*     *args

按主要性字定义的可变长度的实参:**        **kwargs

非关键字可变长度的实参:*

概念一个函数的时候,必须要事先定义这些函数要求多少个参数(可能说能够承受多少个参数)。一般景况下那是没难点的,可是也有在概念函数的时候,无法通晓参数个数的意况(想一想C语言里的printf函数),在Python里,带*的参数就是用来经受可变多少参数的。看一个例证

def funcD(a, b, *c):
  print a
  print b
  print “length of c is: %d ” % len(c)
  print c
调用funcD(1, 2, 3, 4, 5, 6)结果是
1
2
length of c is: 4
(3, 4, 5, 6)

  前面八个参数被a、b接受了,剩下的4个参数,全体被c接受了,c在那里是一个tuple。大家在调用funcD的时候,至少要传递2个参数,2个以上的参数,都放到c里了,假如唯有多个参数,那么c就是一个empty
tuple。

 

 关键字定义的可变长度的实参:**

  假设一个函数定义中的最后一个形参有 **
(双星号)前缀,所有正规形参之外的此外的紧要字参数都将被放置在一个字典中传送给函数,比如:

def funcF(a, **b):
  print a
  for x in b:
    print x + “: ” + str(b[x])
调用funcF(100, c=’你好’, b=200),执行结果
100
c: 你好
b: 200

  大家可以见到,b是一个dict对象实例,它接受了至关首要字参数b和c。

结缘一起使用:

# def wrapper(*args,**kwargs): #可以承受任意情势,任意长度的参数
# print(args)
# print(kwargs)
#
#
# wrapper(1,2,3,3,3,3,3,x=1,y=2,z=3)  
===>(1,2,3,3,3,3,3,)   {‘x’:1,’y’=2,’z’=3}

取名第一字参数:定义在*后的形参,必须被传值,而且须求实参必须是以首要字的花样来传值

即:

  形参:  *args,z=10

或:

  实参:z=10

# def func(x,y=1,*args,z,**kwargs):
# print(x)
# print(y)
# print(args)
# print(z)
# print(kwargs)
#
# func(1,2,3,4,5,z=10,a=1,b=2)

 结果:

4858.com 2

 

# def func(x,*args,z=1,**kwargs):
# print(x)
# print(args)
# print(z)
# print(kwargs)
#
# func(1,2,3,4,5,a=1,b=2,c=3)

 结果:

4858.com 3

 

 总计:形参:地点形参,暗中同意参数,*args,命名第一字参数,**kwargs

 五、函数嵌套

#函数的嵌套调用
#
# def max2(x,y):
# if x > y:
#4858.com, return x
# else:
# return y
#
# def max4(a,b,c,d):
# res1=max2(a,b) #23
# res2=max2(res1,c) #23
# res3=max2(res2,d) #31
# return res3
#
#
# print(max4(11,23,-7,31))

#函数的嵌套定义
def f1():
def f2():
def f3():
print(‘from f3’)
print(‘from f2’)
f3()
print(‘from f1’)
f2()
# print(f1)
f1()

”’
from f1
from f2
from f3

”’

函数对象:

4858.com 4

 

 六、命名空间

名字空间:存放名字与值的绑定关系

名称空间分为二种

  停放名称空间:python解释器自带的名字,python解释器启动就会变动

  全局名称空间:文件级别定义的名字都会存放与大局名称空间,执行python文件时会爆发

  局地名称空间:定义在函数内部的名字,局地名称空间只有在调用函数时才会卓有成效,函数调用甘休则失效

三者的加载顺序:内置名称空间->全局名称空间->局部名称空间

三者的取值顺序:局地名称空间->全局名称空间->内置名称空间

七、作用域

作用域:

效率范围:

大局作用域:内置名称空间与大局名称空间的名字属于全局范围,
        #在全方位文件的即兴地方都能被引述,全局有效
一对成效域:局地名称空间的名字属于有些范围,
        #只在函数内部能够被引述,局地有效

功用域在概念函数时就曾经固定住了,不会随着调用位置的转移而改变

 1 name='alex'
 2 def foo():
 3     name='lhf'
 4     def bar():
 5         name='wupeiqi'
 6         print(name)
 7         def tt():
 8             name='hedeyong'
 9             print(name)
10         return tt
11     return bar
12 
13 func=foo()
14 func()()       #==> bar()() ==>tt()
  '''
  hedeyong
  '''

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有