博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 基础(四) 函数
阅读量:5303 次
发布时间:2019-06-14

本文共 8151 字,大约阅读时间需要 27 分钟。

函数

一、什么是函数?

函数是可以实现一些特定功能的 小方法 或者是小程序

 

优点:

  1. 提高 了代码的后期维护

  2. 增加了代码的重复使用率

  3. 减少了代码量 提高了代码可读性

二、函数的定义

使用 def关键+函数名([参数]):

​ 函数体

函数的命名规则:

遵循变量的命名规则

 

三、函数名

(1) 函数的调用

函数名([参数])

(2) 函数名区分大小写

(3) 只能在函数定义的下方来调用

(4) 函数不能重名 会被覆盖

 

四、函数的参数问题

(1) 形参(形式上的参数)

​ 在函数定义处的括号里的变量 称之为 形参

注意:

  1. 函数在定义的时候 存在形参 且没有默认值 则在调用时 必须传实参

    a(1,2) #此刻1和2称之为实参

  2. 函数在定义时 如果没有 形参 则不能传实参

  3. 传入的实参个数 不能大于形参个数

  4. 实参和形参对应

  5. 实参的参数 和 形参一一对应 从左倒右依次赋值

(2) 形参默认值

在函数定义处 给当前形参赋一个默认值 则在调用时 当前有默认值的形参 可传可不传

如果传实参 则当前形参的值为实参的值 否则值为默认值

实例:

def defaultArg(a,b=2):
   print(a,b)
defaultArg(1) #1,2
defaultArg(1,3) #1 3
 

错误写法(没有遵循默认值的规则)

def defaultArg(a=1,b):
   print(a,b)
defaultArg(1,2)
 

在给形参默认值的时候 有默认值放在最后面

(3) 关键字参数

可以做到给指定的形参赋值

def demo(a,b,c):
# def demo(a,b,c):
   print(a,b,c)
# demo(1,2,3)
# demo(c=1,b=2,a=3) #关键字参数 关键字为 形参名
# demo(1,b=2,c=3) #关键字参数  第一个值默认传递给a 从左到右
# demo(a=1,2,c=3) #follows keyword argument
# demo(1,b=2,a=3) #关键字参数 当前参数a 赋值2次
 

 

五、函数的返回值

(1) 没有返回值的情况

实例:

a = 1
def func():
   a = 1+2
print(func())#打印函数调用处   None
 

(2) 有返回值的情况

使用关键字 return

使用 return 可以方便我们对函数值的操作(你能够拿到这个值 并对他操作)

实例:

a = 1
def func():
   a = 1+2
   return a
print(func())#将值返回给函数调用处   3
 

注意事项:

在函数体内使用return时 return下面的代码将不会在执行

(3) 函数返回多个值得情况

实例:

def mySum(a=0,b=0):
   Sum = a + b
   return Sum,a,b  #将a,b,Sum全部返回     以元组的方式
   return (Sum,a,b)  #将a,b,Sum全部返回   以元组的方式
   return [Sum,a,b]  #将a,b,Sum全部返回   以列表的方式
 

 

六、不定长参数

概念:也就是传入得参数得个数 不确定

(1) *args 以元组接收不确定实参得值

def demo(*args): #以元组得形式 接受不确定参数得个数
   print(args)
demo(1,2,3)  #(1,2,3)
demo() #空元组 ()
 

*args和普通形参的搭配使用

A: *args,a
def demo(a,b,*args):
   print(args,a)
 
demo(1,2) #1 2 ()
demo(1,2,3,4,5) #1 2 (3, 4, 5)
demo('x') #('x',) 1
demo('x','y') #('x', 'y') 1
 
B: a,*args
def demo(*args,a=1):
   print(args,a)
demo('x','y',a=2) #('x', 'y') 2
 

(2) **kwargs 以字典得形式接收不确定参数

其中关键字为 字典得键 值为字典得值

def func(**kwargs):
   print(kwargs)
func(a=1,b=2,c=3)
func(a=1,a=2) #SyntaxError: keyword argument repeated
 

注意:

关键字 不能重复

SyntaxError: keyword argument repeated

(3) 在调用处的 **的使用

def func(**kwargs):
   print(kwargs) #{'a':'a','b':'b'}
myDict = {
'a':'a','b':'b'}
func(**myDict) #在调用处    将字典 转换为关键字参数
 

(4) 组合使用

普通参数,*args,**kwargs

def demo(x,*args,**kwargs):
   print('x',x,'*args',args,'**kwargs',kwargs)
demo(1,2,3,4,a=1,y=2)
#demo(x=1,2,3,4,a=1,y=2) #x 1 *args (2, 3, 4) **kwargs {'a': 1, 'y': 2}
 

 

七、递归

概念:自己调用自己

实现累加得普通操作

def mySum(num):
   Sum = 0
   for i in range(1,num+1):
       # print(i)
       Sum += i
   print(Sum)
mySum(5)
 

使用递归实现一个数得累加

def mySum(num):
   if num == 0:
       return False
       # return #int' and 'NoneType'
   return num + mySum(num-1)
 

运行过程

 
mySum(5)
5+mySum(4)
5+(4+mySum(3))
5+(4+(3+mySum(2)))
5+(4+(3+(2+mySum(1))))
5+(4+(3+(2+(1+mySum(0)))))
5+(4+(3+(2+(1+False))))
5+(4+(3+(2+1))))
5+(4+(3+3)))
5+(4+6)
5+10
15
 

 

证明递归原路返回

def demo(n):
   print(n)
   if n>=0:
       demo(n-1)
   print(n)
demo(3)
 

上面代码得分解

def a(n):
   print(n) #4
   b(n-1) #3
   print(n) #4
def b(n): #3
   print(n) #3
   c(n-1) #2
   print(n) #3
def c(n): #2
   print(n) #2
   d(n-1)
   print(n) #2
def d(n): #1
   print(n) #1
   print(n) #1
a(4)
 

 

 

1.定义一个函数 模仿pop

传入一个列表 将最后得值弹出并返回

def myPop(List):
   val = List[-1]
   del List[-1]
   return val
myList = [1,2,3,4]
print(myPop(myList))
 

2.自定义一个函数 实现 字典得键值交换

def dictChange(Dict):
   newDict = {}
   for i in Dict:
       # print(i)
       newDict[Dict[i]] = i
   return newDict
myDict = {
'name':'zs','age':'18'}
print(dictChange(myDict))
 

3.实现一个 类似 popitem()的操作

def myPopitem(Dict):
   keys = list(Dict.keys())[-1]
   val = Dict[keys]
   del Dict[keys]
   return keys,val
myDict = {
'a':'1','b':'2'}
print(myPopitem(myDict))
print(myDict)
 

 

八、可变类型与不可变类型

不可变类型:如整数,字符串,元组...

可变类型: 字典,列表...

不可变类型实例:

def change(var):
   # print(var)
   # print(id(var))
   var = 2
Int = 1
change(Int)
# print(id(Int))
print(Int)
 

有值2 Int变量执行了2 在传递给change函数得时候 按照传值得方式赋值了变量Int Int和var都执行了 2(int对象)

在 var = 2 得时候 创建了一个新的变量

可变类型实例:

def change(List):
   List.append('a')
myList = [1,2,3]
change(myList)
print(myList)
 

理解的代码

a = [1,2,3]
b = a
b = 2
# print(a)
# print(b)
# b.append('a')
print(b)
print(a)s
 

 

九、变量得作用域

在python中 程序得变量 并不是在哪个位置都可以访问得倒 访问权限 取决于变量得定义位置

  • L 局部作用域

  • E 闭包函数外得函数中

  • G 全局作用域

  • B 内建作用域

(1) 在函数外部声明得变量 称之为 全局变量 函数内外都能够获取
num = 1
def func():
   print(num)
 
func()
 

函数内可以获取到全局变量 但是不能进行修改

(2) 在函数内部声明得变量称之为局部变量 只能在函数内部使用 函数外部获取不到
def func():
   num = 2
   print(num)
func()
print(num)
 

在函数内部想用某个变量 那么会先在函数内部查找 如果内部不存在 则取外部查找

(3) global 声明函数内外使用同一个变量
num = 1
def func():
   global num
   num = 2
func()
print(num)
 
(4) 将局部变量 声明为全局变量(函数内外都可以获取到)
def func():
   global x #将局部变量 声明为全局变量
   x = 1
func()
print(x)
 
(5) nonlocal 当函数发生嵌套时(将上层的变量于当前声明内外使用同一个)
num = 1
Str = 'string'
#1 当函数放生嵌套的时候  在使用变量时 去上一层查找
def a():
   # nonlocal num
   # num = 2
   Str = '新的字符串'
   def b():
       # nonlocal num #将外层和当的变量声明统一使用同一个
       # num = 3
       def c():
           # global num
           nonlocal num
           num = 'num'
           print(num)
           # print(Str)
       c()
       print(num)
   b()
   print(num)
a()
 

如果函数上层没有要查找的变量 则去上上层... 直到查到为止

在函数嵌套时 里层函数使用global时 会将全局变量声明使用

是否会引入新的作用域

  1. 在python中 只有模块(module),类(class),函数 会引入新的作用域

  2. if/else try/except for/while 是不会引入新的作用域 也就是说 这些语句内定义的变量 外部也能够访问

十、lambda表达式(匿名函数)

定义: lambda

变量名 = lambda [参数]:函数体

注意:

  1. lambda 只是一个表达式 函数体比def简单很多

  2. lambda 是表达式 不是代码块 只能在lambda中封装有限的逻辑

  3. 调用和函数一样 变量名([参数])

实例:

#第一种方式
func = lambda a,b:a+b #将值进行返回
func = lambda a,b:print(a+b) #将值进行输出
#第二种方式 定义并调用
print((lambda a,b:a+b)(1,2))
#第三种 给默认值
func = lambda a=1,b=1:a+b
print(func())
#第四种 没有形参的情况
a = 1
func = lambda :a
print(func())
#第五种 嵌套
func = lambda :(lambda :print('我是嵌套的表达式'))()
 

 

十一、装饰器

概念: 在代码运行期间 动态的添加功能 称之为装饰器

步骤1

def demo(arg):
   print('我是demo函数')
   # print(arg)
   # func()
   arg()
def func():
   print('我是func函数')
# demo('abc')
demo(func)
 

步骤2

def demo(arg):
   def inner():
       print('当前时间为')
       return arg()
   return inner
def func():
   print('2018/4/5')
def func2():
   print('2018-4-5')
func2 = demo(func2)
func2()
func = demo(func)
func()
 

步骤3

#demo函数 是一个 实现主体功能的函数
def demo(arg):
   def inner(age): #根据 age判断年龄段
       Str = ''
       if age<=10:
           Str = '儿童'
       elif age<=20:
           Str = '少年'
       elif age<=30:
           Str = '青年'
       elif age<=50:
           Str = '中年'
       else:
           Str = '老年'
       return arg(Str)
   return inner
#自己有需求 要添加实现的函数
def func(person):
   print('你已经步入了{}'.format(person))
func = demo(func)
func(60)
 

步骤4

import functools
#demo函数 是一个 实现主体功能的函数
def demo(arg):
   @functools.wraps(arg) #将inner复制给func
   def inner(age): #根据 age判断年龄段
       pass
...
#自己有需求 要添加实现的函数
@demo #==  func = demo(func)
def func(person):
   print('你已经步入了{}'.format(person))
 
给装饰器传参数
import functools
def demo(text):
   def inner(arg):
       @functools.wraps(arg)
       def decorator(*args,**kwargs):
           print(text)
           return arg(*args,**kwargs)
       return decorator
   return inner
@demo('现在的时间为') #demo('现在的时间为')(time)
def time(*args,**kwargs):
   print('2018/4/25',args)
 

 

十二、包和模块

模块(Module): 就是python中的一个 py文件 其中定义的所有 的变量和函数 都属于当前的py文件 Module对于所有函数而言 相当于一个 全局的命名空间(namespace) 而每一个函数又有自己的局部命名空间

包(Package): 所谓的包 就是 一堆module的集合 也就是一堆py文件 包文件总 必须有一个__init__.py文件 作为当前包的初始化

__name__

判断当前文件 是在主文件执行 还是在其他文件导入执行的

在主文件name的值为 main 被其它文件导入 name的值为他自己模块的名称

Module:

里面就是一堆的类,函数,变量

a.py

 
age = 10
def demo():
   return '你调用a.py中的demo函数了'
if __name__ == '__main__':
   print(demo())
 

 

Package:

目录结构:

package

----> __init__.py

----> func.py 包含某些功能的py文件

-----> ...py

 

 

包或者模块的导入

from 包名.模块名 import 属性或者函数

from package.a import demo 导入一个
from package.a import demo,age 导入多个
from package.a import * 导入所有
使用
print(demo())
print(age)
 

from 包名 import 模块名

from package import a   从package包 导入a模块
 

import 包.模块名/模块名

import 包.模块名/模块名 as 别名

import package.a
print(package.a.age)
import package.a as t
print(t.age)
 

包中的初始化操作

__init__.py 通常做一个包被导入时 进行初始化的操作 可以将其他模块module 中的变量,函数 进行导入 在外部导入当前包的时候 不需要指定包下的模块名 而是直接 from 包名 import 函数/变量

实例

package->__init__.py

from package.a import demo
from package.a import *
from package.b import func
from .a import *
def abc():
   print('走我了')
 

在外部的test.py中进行导入使用

from package import demo,func,abc
from package import *  #导入所有
print(demo())
print(func())
abc()
 

转载于:https://www.cnblogs.com/gugubeng/p/9715173.html

你可能感兴趣的文章
[转载] redis 的两种持久化方式及原理
查看>>
C++ 删除字符串的两种实现方式
查看>>
ORA-01502: 索引'P_ABCD.PK_WEB_BASE'或这类索引的分区处于不可用状态
查看>>
Java抽象类和接口的比较
查看>>
开发进度一
查看>>
MyBaits学习
查看>>
管道,数据共享,进程池
查看>>
CSS
查看>>
[LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming
查看>>
[Cypress] Stub a Post Request for Successful Form Submission with Cypress
查看>>
程序集的混淆及签名
查看>>
判断9X9数组是否是数独的java代码
查看>>
00-自测1. 打印沙漏
查看>>
UNITY在VS中调试
查看>>
SDUTOJ3754_黑白棋(纯模拟)
查看>>
Scala入门(1)Linux下Scala(2.12.1)安装
查看>>
如何改善下面的代码 领导说了很耗资源
查看>>
Quartus II 中常见Warning 原因及解决方法
查看>>
php中的isset和empty的用法区别
查看>>
Android ViewPager 动画效果
查看>>