python常用函数详解

1.函数的介绍

为什么要有函数?因为在平时写代码时,如果没有函数的话,那么将会出现很多重复的代码,这样代码重用率就比较低。。。并且这样的代码维护起来也是很有难度的,为了解决这些问题,就出现了函数,用来将一些经常出现的代码进行封装,这样就可以在任何需要调用这段代码的地方调用这个函数就行了。

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

特性:

代码重用
保持一致性
可扩展性

2.函数的创建

在python中函数定义的格式如下:

def 函数名(形参):
 函数体内部代码块

函数的调用使用 函数名(实参) 就可以调用函数了。

函数名的命名规则和变量的命名规则一样:

  • 函数名必须以下划线或字母开头,可以包含任意字母、数字或下划线的组合。不能使用任何的标点符号;
  • 函数名是区分大小写的。
  • 函数名不能是保留字。

形参和实参的区别:

函数在定义的时候,函数名后面的括号中可以添加参数,这些参数就叫做形参,形参:顾名思义就是形式参数,只是一个代号。

实参是在调用函数的时候函数名后面的括号中的参数,形参和实参需要一一对应起来,否则调用函数会报错。

3.函数参数及返回值

前面提到函数的形参和实参要一一对应,那么参数对应有如下几种:

  1. 必须参数
  2. 关键字参数
  3. 默认参数
  4. 不定长参数 *args
  5. 不定长参数 **kwargs

1.必须参数:

必须参数必须以对应的关系一个一个传递进入函数,函数调用时传递的实参必须和函数定义时的形参一一对应,不能多也不能少,顺序也得一致。

举个栗子:

 def f(name,age):
   print(name,age)
 f("小明",18)

2.关键字参数

关键字参数是实参里面的概念,在调用函数的时候声明某个参数是属于某个关键字的。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

举个栗子:

 def f(name,age):
   print(name,age)
 f(name="小明",18)

3.默认参数

默认参数是在函数声明的时候,可以给某个参数指定默认值,这样的参数叫做默认值参数。如果在调用函数的时候,默认参数没有接收到对应的实参,那么就会将默认值赋值给这个参数。

举个栗子:

 def f(name,age,sex="male"):
   print(name,age,sex)
 f(name="小明",18)

这样,就会把默认参数male赋值给sex了。

4.不定长参数 *args

在python里面,函数在声明的时候,参数中可以使用(*变量名)的方式来接受不确定长度的参数,但是在python里面大家约定俗成使用*args接受不定长参数,这样在调用函数的时候传递的参数就可以是不定长度的了。args接受了不定长参数之后,将这些参数放到一个tuple里面,可以通过访问args来获取这些不定长参数。

举个栗子:

 def f(*args):
   print(args)
 f("小明",18,"male")

打印出来的是一个tuple,里面存放了(“小明”,18,”male”)这三个元素。

5.不定长参数 **kwargs

但是上面的args只能接收未命名的参数,那假如有类似于关键字参数的不定长参数该怎么办呢?python里面使用(**变量名)来接收不定长的命名变量参数。同样,python里面也约定俗成使用**kwargs接收不定长命名参数。kwargs接收了不定长参数之后,将这些参数放到一个字典里面,可以通过key获取到相应的参数值。

举个栗子:

 def f(**kwargs):
   print(kwargs)
 f(name="小明",age=18,sex="male")

介绍完了这些参数之后,接下来要介绍的是关于这些参数混合使用的情况:

假如一个函数使用了上面所有种类的参数,那该怎么办?为了不产生歧义,python里面规定了假如有多种参数混合的情况下,遵循如下的顺序使用规则:

def f(必须参数,默认参数,*args,**kwargs):
     pass
如果同时存在args和kwargs的话,args在左边

默认参数在必须参数的右边,在*args的左边

关键字参数的位置不固定(ps:关键字参数也不在函数定义的时候确定)

那么,假如有一个列表想要传递进入一个不定长的未命名参数的函数中去,可以在该列表前面加上*实现,同理如果想传递一个字典进入不定长命名参数的函数中去,可以在该字典前面加上**

举个栗子:

 def f(*args,**kwargs):
   print(args)
   for i in kwargs:
     print("%s:%s"%(i,kwargs[i]))

 f(*[1,2,3],**{"a":1,"b":2})

函数的返回值

要想获取函数的执行结果,就可以用return语句把结果返回

注意:

函数在执行过程中只要遇到return语句,就会停止执行并返回结果,也可以理解为 return 语句代表着函数的结束 如果未在函数中指定return,那这个函数的返回值为None
return多个对象,解释器会把这多个对象组装成一个元组作为一个一个整体结果输出。

4.LEGB作用域

python中的作用域分4种情况:

L:local,局部作用域,即函数中定义的变量;

E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;

G:globa,全局变量,就是模块级别定义的变量;

B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。

local和enclosing是相对的,enclosing变量相对上层来说也是local。

在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)不会引入新的作用域。

变量的修改(错误修改,面试题里经常出):

 x=6
 def f2():
   print(x)
   x=5
 f2()

 # 错误的原因在于print(x)时,解释器会在局部作用域找,会找到x=5(函数已经加载到内存),但x使用在声明前了,所以报错:
 # local variable 'x' referenced before assignment.如何证明找到了x=5呢?简单:注释掉x=5,x=6
 # 报错为:name 'x' is not defined
 #同理
 x=6
 def f2():
   x+=1 #local variable 'x' referenced before assignment.
 f2()

global关键字

当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:

 count = 10
 def outer():
   global count
   print(count)
   count = 100
   print(count)
 outer()

nonlocal关键字

global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了

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

小结

  • 变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;
  • 只有模块、类、及函数才能引入新作用域;
  • 对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
  • 内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个 关键字,就能完美的实现闭包了。

5.特殊函数

递归函数定义:递归函数就是在函数内部调用自己

有时候解决某些问题的时候,逻辑比较复杂,这时候可以考虑使用递归,因为使用递归函数的话,逻辑比较清晰,可以解决一些比较复杂的问题。但是递归函数存在一个问题就是假如递归调用自己的次数比较多的话,将会使得计算速度变得很慢,而且在python中默认的递归调用深度是1000层,超过这个层数将会导致“爆栈”。。。所以,在可以不用递归的时候建议尽量不要使用递归。

举个栗子:

 def factorial(n): # 使用循环实现求和
   Sum=1
   for i in range(2,n+1):
     Sum*=i
   return Sum
 print(factorial(7))

 def recursive_factorial(n): # 使用递归实现求和
   return (2 if n==2 else n*recursive_factorial(n-1))

 print(recursive_factorial(7))

 def feibo(n): # 使用递归实现菲波那切数列
   if n==0 or n==1:return n
   else:return feibo(n-1)+feibo(n-2)
 print(feibo(8))

 def feibo2(n): # 使用循环实现菲波那切数列
   before,after=0,1
   for i in range(n):
     before,after=after,before+after
   return before
 print(feibo2(300))

递归函数的优点:定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

递归特性:

  • 必须有一个明确的结束条件
  • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
  • 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返 回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)

6.函数式编程

关于函数式编程,我理解的也不是很深,但是python中有4个比较重要的内置函数,组合起来使用有时候能大大提高编程效率。

1 filter(function, sequence)

 str = ['a', 'b','c', 'd']
 def fun1(s):
   if s != 'a':
     return s
 ret = filter(fun1, str)
print(list(ret))# ret是一个迭代器对象

对sequence中的item依次执行function(item),将执行结果为True的item做成一个filter object的迭代器返回。可以看作是过滤函数。

2 map(function, sequence)

 str = [1, 2,'a', 'b']
 def fun2(s):
   return s + "alvin"
 ret = map(fun2, str)
 print(ret)   # map object的迭代器
 print(list(ret))# ['aalvin', 'balvin', 'calvin', 'dalvin']

对sequence中的item依次执行function(item),将执行结果组成一个map object迭代器返回. map也支持多个sequence,这就要求function也支持相应数量的参数输入:

 def add(x,y):
   return x+y
 print (list(map(add, range(10), range(10))))##[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

3 reduce(function, sequence, starting_value)

 from functools import reduce
 def add1(x,y):
   return x + y

 print (reduce(add1, range(1, 101)))## 4950 (注:1+2+...+99)
 print (reduce(add1, range(1, 101), 20))## 4970 (注:1+2+...+99+20)

对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用.

4 lambda

普通函数与匿名函数的对比:

 #普通函数
 def add(a,b):
   return a + b

 print add(2,3)

 #匿名函数
 add = lambda a,b : a + b
 print add(2,3)

 #========输出===========
 5
 5

匿名函数的命名规则,用lamdba 关键字标识,冒号(:)左侧表示函数接收的参数(a,b) ,冒号(:)右侧表示函数的返回值(a+b)。

因为lamdba在创建时不需要命名,所以,叫匿名函数

(0)

相关推荐

  • Python字符串和文件操作常用函数分析

    本文实例分析了Python字符串和文件操作常用函数.分享给大家供大家参考.具体如下: # -*- coding: UTF-8 -*- ''' Created on 2010-12-27 @author: sumory ''' import itertools def a_containsAnyOf_b(seq,aset): '''判断seq中是否含有aset里的一个或者多个项 seq可以是字符串或者列表 aset应该是字符串或者列表''' for item in itertools.ifilte

  • Python中functools模块的常用函数解析

    1.partial 首先是partial函数,它可以重新绑定函数的可选参数,生成一个callable的partial对象: >>> int('10') # 实际上等同于int('10', base=10)和int('10', 10) 10 >>> int('10', 2) # 实际上是int('10', base=2)的缩写 2 >>> from functools import partial >>> int2 = partial(

  • Python OS模块常用函数说明

    Python的标准库中的os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.即它允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在Linux和Windows下运行. 下面列出了一些在os模块中比较有用的部分.它们中的大多数都简单明了. os.sep可以取代操作系统特定的路径分隔符.windows下为 "\\" os.name字符串指示你正在使用的平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'pos

  • Python学习笔记之常用函数及说明

    基本定制型 复制代码 代码如下: C.__init__(self[, arg1, ...]) 构造器(带一些可选的参数)C.__new__(self[, arg1, ...]) 构造器(带一些可选的参数):通常用在设置不变数据类型的子类.C.__del__(self) 解构器C.__str__(self) 可打印的字符输出:内建str()及print 语句C.__repr__(self) 运行时的字符串输出:内建repr() 和'' 操作符C.__unicode__(self)b Unicode

  • Python time模块详解(常用函数实例讲解,非常好)

    在开始之前,首先要说明这几点: 1.在Python中,通常有这几种方式来表示时间:1)时间戳 2)格式化的时间字符串 3)元组(struct_time)共九个元素.由于Python的time模块实现主要调用C库,所以各个平台可能有所不同.2.UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间.在中国为UTC+8.DST(Daylight Saving Time)即夏令时.3.时间戳(timestamp)的方式:通常来说,时间戳表示的是从1

  • python常用函数详解

    1.函数的介绍 为什么要有函数?因为在平时写代码时,如果没有函数的话,那么将会出现很多重复的代码,这样代码重用率就比较低...并且这样的代码维护起来也是很有难度的,为了解决这些问题,就出现了函数,用来将一些经常出现的代码进行封装,这样就可以在任何需要调用这段代码的地方调用这个函数就行了. 函数的定义:函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 代码重用 保持一致性 可扩展性 2.函数的创建 在python中函数定义的格式如下: def

  • Python pandas常用函数详解

    本文研究的主要是pandas常用函数,具体介绍如下. 1 import语句 import pandas as pd import numpy as np import matplotlib.pyplot as plt import datetime import re 2 文件读取 df = pd.read_csv(path='file.csv') 参数:header=None 用默认列名,0,1,2,3... names=['A', 'B', 'C'...] 自定义列名 index_col='

  • Python Asyncio库之asyncio.task常用函数详解

    目录 前记 0.基础 1.休眠--asyncio.sleep 2.屏蔽取消--asyncio.shield 3.超时--asyncio.wait_for 4.简单的等待--wait 5.迭代可等待对象的完成--asyncio.as_completed 前记 Asyncio在经过一段时间的发展以及获取Curio等第三方库的经验来提供更多的功能,目前高级功能也基本完善,但是相对于其他语言,Python的Asyncio高级功能还是不够的,但好在Asyncio的低级API也比较完善,开发者可以通过参考A

  • Python Asyncio 库之同步原语常用函数详解

    目录 前记 0.基础 1.Lock 2.Event 4.Condition 5.Semaphore 前记 Asyncio的同步原语可以简化我们编写资源竞争的代码和规避资源竞争导致的Bug的出现. 但是由于协程的特性,在大部分业务代码中并不需要去考虑资源竞争的出现,导致Asyncio同步原语被使用的频率比较低,但是如果想基于Asyncio编写框架则需要学习同步原语的使用. 0.基础 同步原语都是适用于某些条件下对某个资源的争夺,在代码中大部分的资源都是属于一个代码块,而Python对于代码块的管理

  • python imread函数详解

    Python 中各种imread函数的区别与联系 最近一直在用python做图像处理相关的东西,被各种imread函数搞得很头疼,因此今天决定将这些imread总结一下,以免以后因此犯些愚蠢的错误.如果你正好也对此感到困惑可以看下这篇总结.当然,要了解具体的细节,还是应该 read the fuck code和API document,但貌似python的很多模块文档都不是很全,所以只能多看代码和注释了. 先来看看常用的读取图片的方式: PIL.Image.open scipy.misc.imr

  • js正则表达式常用函数详解(续)

    正则表达式对象的方法 1.test,返回一个 Boolean 值,它指出在被查找的字符串中是否存在模式.如果存在则返回 true,否则就返回 false. 2.exec,用正则表达式模式在字符串中运行查找,并返回包含该查找结果的一个数组. 3.compile,把正则表达式编译为内部格式,从而执行得更快. 正则表达式对象的属性 1.source,返回正则表达式模式的文本的复本.只读. 2.lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的开始位置. 3.input ($_),返回

  • PHP封装curl的调用接口及常用函数详解

    如下所示: <?php /** * @desc 封装curl的调用接口,post的请求方式 */ function doCurlPostRequest($url, $requestString, $timeout = 5) { if($url == "" || $requestString == "" || $timeout <= 0){ return false; } $con = curl_init((string)$url); curl_setop

  • 上帝为你开了一扇窗之Tkinter常用函数详解

    第一步:导入模块,无需安装 import tkinter 第二步:实现一个窗口 import tkinter tk=tkinter.Tk() tk.mainloop() 这样,我们应该基本的gui窗口就搞定了.接下来,我们给它加点东西,让它看起来更加独特. 第三步:修改窗口名称 tk.title("窗口") 第四步:设置窗口大小 tk.geometry("300x150+700+300") 参数:width x height+x+y, 分别对应,窗口 宽,高,以及窗

  • Python入门教程(十九)python的函数详解

    目录 创建函数 调用函数 参数 默认参数值 以 List 传参 返回值 关键字参数 任意参数 pass 语句 递归 函数是一种仅在调用时运行的代码块. 可以将数据(称为参数)传递到函数中. 函数可以把数据作为结果返回. 创建函数 在 Python 中,使用 def 关键字定义函数: 实例 def my_function(): print("Hello from a function") 调用函数 如需调用函数,请使用函数名称后跟括号: 实例 def my_function(): pri

  • python 字符串常用函数详解

    字符串常用函数: 声明变量 str="Hello World" find() 检测字符串是否包含,返回该字符串位置,如果不包含返回-1 str.find("Hello") # 返回值:0 str.find("W") # 返回值:6, 这里需要注意下:空格也是一个字符.W前面有个空格,所以W位置是6 str.find("R") # 返回值:-1,并不包含在Hello World中,如果不包含返回-1 index() 检测字符串是

随机推荐