函数前戏

name_list = ['jason', 'kevin', 'oscar', 'jerry']
# print(len(name_list))
'''突然len不准用了'''
# count = 0
# for i in name_list:
# count += 1
# print(count)
'''统计列表内数据值个数的代码需要在很多地方使用'''
# 相同的代码需要在不同的地方反复执行
"""
循环
相同的代码在相同的位置反复执行
函数
相同的代码在不同的位置反复执行
ps:相同的代码不是真正一模一样而是可以通过传入的数据不同而做出不同的改变
""" def num():
count= 0
for i in name_list:
count += 1
print(count)
num()
"""
函数相当于工具(具有一定功能)
不用函数
修理工需要修理器件要用锤子 原地打造 每次用完就扔掉 下次用继续原地打造
用函数
修理工提前准备好工具 什么时候想用就直接拿出来使用
"""

函数的语法结构

def 函数名(参数):
'''函数注释'''
函数体代码
return返回值
1.def
定义函数的关键字
2.函数名
命名等同于变量名
3.参数
可有可无 主要是在使用函数的时候规定要不要外界传数据进来
4.函数注释
类似于工具说明书
5.函数体代码
是整个函数的核心 主要取决于程序员的编号
6.return
使用函数之后可以返回给使用者的数据 可有可无

函数的定义与调用

1.函数在定义阶段只检测语法 不执行代码
def func():
pass
2.函数在调用阶段才会执行函数体代码
func()
3.函数必须先定义后调用
4.函数定义使用关键字def函数调用使用>>>:函数名加括号
如果有参数则需要在括号内按照相应的规则传递参数(后续详细讲解)

函数的分类

1.空函数
函数体代码为空 使用的pass或者...补全的
空函数主要用于项目前期的功能框架
def register():
"""注册功能"""
pass
def login():
"""登陆功能"""
pass
def choice_course():
"""选课功能"""
pass
2.无参函数
定义函数的时候括号内没有参数
def index():
print('from index function')
3.有参函数
定义函数的时候括号内写参数 调用函数的时候括号传参数
def func(a):
print(a)

函数的返回值

1.什么是返回值
调用函数之后返回给调用者的结果
2.如何获取返回值
变量名 赋值符号 函数的调用
res = func() # 先执行func函数 然后将返回值赋值给变量res
3.函数返回值的多种情况
3.1函数体代码种没有return关键字 默认返回None
3.2函数体代码有return 如果后面没有写任何东西还是返回None
3.3函数体代码有return 后面写什么就返回什么
3.4函数体代码有return并且后面有多个数据值 则自动组织成元组返回
3.5函数体代码遇到return会立刻结束

函数的参数

形式参数
在函数定义阶段括号内填写的参数 简称'形参'
实际参数
在函数调用阶段括号内填写的参数 简称'实参'
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
"""
形参与实参的关系
形参类似于变量名 在函数定义阶段可以随便写 最好见名知意
def refister(name,pwd):
pass
实参类似于数据值 在函数调用阶段与形参临时绑定 函数运行结束立刻断开
register('jason',123) 形参name与jason绑定 形参pwd与123绑定
"""
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

函数参数之位置参数

"""
补充:当子代码只有一行并且很简单的情况下 可以直接在冒号后编写 不用换行
"""
位置形参
函数定义阶段括号内从左往右依次填写的变量名
def func1(a, b, c):pass
位置实参
函数调用阶段括号内从左往右依次填写的数据值
func1(1, 2, 3) def func1(a, b):
print(a, b) # func1(1, 2) # 按照位置意义对应传值
# func1(1) # 少一个不行
# func1(1,2,3) # 多一个也不行
# func1(b=1,a=2) # 关键字传参(指名道姓的传)
# func1(b=1, 2) # 关键字传参一定要跟在位置传参的后面 报错
# func1(2, b=1) # 可以
# func1(1,a=2,b=3) # 同一个形参在调用的时候不能多次赋值
name = 'jason'
pwd = 123
# func1(name, pwd) # 实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名
func1(a=name, b=pwd) # 实参没有固定的定义 可以传数据值 也可以传绑定了数据值的变量名

"""

越短的越简单的越靠前

越长的越复杂的越靠后

但是遇到下列的情况除外

同一个形参在调用的时候不能多次赋值

"""

默认参数

本质其实就是关键字形参(关键字实参上述内容已经讲了)
别名叫默认参数:提前就已经给了 用户可以不传 也可以传 '''默认参数的定义也遵循短的简单的靠前 长的复杂的靠后'''
def register(name, age, gender='male'):
print(f"""
--------学员信息----------
姓名:{name}
年龄:{age}
性别:{gender}
-------------------------
""")
register('jason', 18)
register('kevin', 28)
register('lili', 28, 'female')
register('lili', 28, gender='female') # register('jason', 18, 'male')
# register('tony', 28, 'male')
# register('kevin', 38, 'male')

可变长形参

# def func1(*a):
# print(a)
# func1() # ()
# func1(1) # (1,)
# func1(1,2) # (1, 2) # def func2(b, *a):
# print(a, b)
# func2() # 函数至少需要一个参数给到b
# func2(1) # () 1
# func2(1, 2, 3, 4) # (2, 3, 4) 1
"""
*号在形参中
用于接收多余的位置参数 组织成元组赋值给*号后面的变量名
"""
# def func3(**k):
# print(k)
# func3() # {}
# func3(a=1) # {'a': 1}
# func3(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3} # def func4(a, **k):
# print(a, k) # func4() # 函数至少需要一个参数给到a
# func4(a=1) # 1 {}
# func4(a=1, b=2, c=3) # 1 {'b': 2, 'c': 3}
# func4(a=1, b=2, c=3, x='jason', y='kevin') # 1 {'b': 2, 'c': 3, 'x': 'jason', 'y': 'kevin'}
"""
**号在形参中
用于接收多余的关键字参数 组织成字典的形式赋值给**号后面的变量名
"""
# def func5(*a, **k):
# print(a, k)
# func5() # () {}
# func5(1, 2, 3) # (1, 2, 3) {}
# func5(a=1, b=2, c=3) # () {'a': 1, 'b': 2, 'c': 3}
# func5(1, 2, 3, a=1, b=2, c=3) # (1, 2, 3) {'a': 1, 'b': 2, 'c': 3} # def func5(n, *a, **k):
# print(a, k) # func5() # 函数至少需要一个参数给到n
# func5(1, 2, 3) # (2, 3) {}
# func5(111,a=1, b=2, c=3) # () {'a': 1, 'b': 2, 'c': 3}
# func5(n=111,a=1, b=2, c=3) # () {'a': 1, 'b': 2, 'c': 3}
# func5(a=1, b=2, c=3, n=111) # () {'a': 1, 'b': 2, 'c': 3}
# func5(1, 2, 3, a=1, b=2, c=3) # (2, 3) {'a': 1, 'b': 2, 'c': 3}
"""
由于*和**在函数的形参中使用频率很高 后面跟的变量名推荐使用
*args
**kwargs
def index(*args, **kwargs):pass
"""

可变长实参

# def index(a, b, c):
# print(a, b, c)
# l1 = [11, 22, 33]
# t1 = (33, 22, 11)
# s1 = 'tom'
# se = {123, 321, 222}
# d1 = {'username': 'jason', 'pwd': 123, 'age': 18}
'''将列表中三个数据值取处理传给函数的三个形参'''
# index(l1[0],l1[1],l1[2])
# index(*l1) # index(11,22,33)
# index(*t1) # index(33,22,11)
# index(*s1) # index('t','o','m')
# index(*se) # index(321,123,222)
# index(*d1) # index('username', 'pwd','age')
"""
*在实参中
类似于for循环 将所有循环遍历出来的数据按照位置参数一次性传给函数
""" # def index(username, pwd, age):
# print(username, pwd, age)
# d1 = {'username':'jason','pwd':123,'age':18}
# index(username= d1.get('username'),pwd=d1.get('pwd'),age=d1.get('age'))
# index(**d1) # index(username='jason',pwd=123,age=18)
"""
**在实参中
将字典打散成关键字参数的形式传递给函数
""" def index(*args,**kwargs):
print(args) # (11,22,33,44)
print(kwargs) # {}
# index(*[11,22,33,44]) # index(11,22,33,44)
index(*11,22,33,44) # index(11,22,33,44)

命名关键字参数(了解)

'''形参必须按照关键字参数传值>>>:命名关键字参数'''

def index(name,*args,gender='male',**kwargs):
print(name,args,gender,kwargs) # index('jason',1,2,3,4,a=1,b=2)
index('jason', 1, 2, 3, 4, 'female', b=2)

名称空间

"""
name = 'jason'
1.申请内存空间存储jason
2.给jason绑定一个变量名name
3.后续通过变量名name就可以访问到jason
"""
名称空间就是用来存储变量名与数据值绑定关系的地方(我们也可以简单的理解为就是存储变量名的地方) 1.内置名称空间
解释器运行自动产生 里面包含了很多名字
eg:len print input
2.全局名称空间
py文件运行产生 里面存放文件级别的名字
name = 'jason' if name:
age = 18
while True:
gender = 'male' def index():
pass
class MyClass(object):
pass
name\age\gender\index\MyClass 3.局部名称空间
函数体代码运行\类体代码运行 产生的空间

名称空间存活周期及作用范围(域)

存活周期
内置名称空间
python解释器启动则创建 关闭则销毁
全局名称空间
py文件执行则创建 运行结束则销毁
局部名称空间
函数体代码运行创建 函数体代码结束则销毁(类暂且不考虑)
作用域
内置名称空间
解释器级别的全局有效
全局名称空间
py文件级别的全局有效
局部名称空间
函数体代码内有效

名字的查找顺序

涉及到名字的查找 一定要先搞明白自己在哪个空间
1.当我们在局部名称空间中的时候
局部名称空间 >>> 全局名称空间 >>> 内置名称空间
2.当我们在全局名称空间中的时候
全局名称空间 >>> 内置名称空间
ps:其实名字的查找顺序是可以打破的 需要用关键字 global nonlocal

查找顺序案例

1.相互独立的局部名称空间默认不能够互相访问
def func1():
name = 'jason'
print(age)
def func2():
age = 18
print(name)
2.局部名称空间嵌套
先从自己的局部名称空间查找 之后由内而外依次查找
"""
函数体代码中名字的查找顺序在函数定义阶段就已经固定死了
x = '干饭了'
def func1():
x = 1
def func2():
x = 2
def func3():
print(x)
x = 3
func3()
func2() func1()
"""

globaly与nonlocal关键字

globaly

局部名称空间直接修改全局名称空间中的数据

money = 666
def index():
global money
money = 123 index()
print(money)

nonlocal

内层局部名称空间修改外层局部名称空间中的数据

def index():
name = 'jason'
def inner():
nonlocal name
name = 'kevin'
inner()
print(name)
index()

python进阶之路10之函数的更多相关文章

  1. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  2. Python进阶之路---1.2python版本差异

    Python2.*与python3.*版本差异 作为一个初学者,我们应该如何选择python的版本进行学习呢,这两个版本有什么区别呢,接下来让我们简单了解一下,以便我们后续的学习. Python版本差 ...

  3. python进阶之路4.2---装饰器

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  4. python学习之路-10 网络编程之进阶

    本篇介绍内容 作用域 python类的多继承 IO多路复用 socketserver之源码剖析 多线程和多进程 作用域 if 1 == 1: name = "xxx" print( ...

  5. Python学习之路10☞面向对象进阶

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 class Foo(objec ...

  6. Python进阶之路---1.5python数据类型-字符串

    字符串 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; ...

  7. Python进阶之路---1.4python数据类型-数字

    python入门基础 声明:以后python代码未注明情况下,默认使用python3.x版本 1.python代码基础:print     print('hello,python')   1.1pyt ...

  8. Python进阶之函数式编程(把函数作为参数)

    什么是函数式编程? 什么是函数式编程? 函数:function 函数式:functional,一种编程范式 函数式编程是一种抽象计算的编程模式 函数≠函数式,比如:计算≠计算机 在计算机当中,计算机硬 ...

  9. python成长之路10

    断点续传   python2.7 多继承  py35多继承   socketserver源码     支持并发处理socket   i/o多路复用   上节回顾     socket          ...

  10. python进阶之路之文件处理

    Python之文件处理 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !imp ...

随机推荐

  1. 华为路由器NAT基本配置命令

    NAT地址转换 静态 [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]nat static global 202.169.10.5 inside 172.16.1.1 ...

  2. JavaScript中通过按回车键进行数据的录入

    1.代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...

  3. 齐博x1云市场注意事项

    安装云市场应用注意事项 大到频道,小到插件甚至钩子及风格都可以在线安装,在线升级. 但是有一个大家务必注意的地方,就是重装系统后,再安装有可能导致重复收费. 这个问题是可以解决的.当然如果不是重装系统 ...

  4. 一、什么是celery

    一.什么是Celery 1.1.celery是什么 celery是一个简单.灵活且可靠的,处理大量消息的分布式系统,专注于是心爱处理的异步任务队列,同事也支持任务调度. Celery的架构由三部分组成 ...

  5. disk磁盘分区软件使用教程,磁盘扩容无损备份

    前几天,因为我的笔记本电脑C盘D盘全红了,趁着双11固态降价,赶紧买了一张三星980 500g 给我的拯救者插上了,加上原来的500g,总共1T,已经够用了. 不得不说拯救者系列预留的1个M.2固态插 ...

  6. clang在编译时指定目标文件所需的最低macOS版本

    调研这个的原因,是因为有个同事在macOS 12.2上打包好的程序,放在macOS 10.15上运行时报错: Dyld Error Message:  Symbol not found: __ZNKS ...

  7. VUE学习2

    目录分析 public目录 index.html是起始的html文件 # 这是关键 <div id="app"></div> src目录 main.js是V ...

  8. 基于socket开发网络调试助手

    1.什么是Socket? 在计算机领域socket被翻译为套接字,它是计算机之间进行通信的一种方式,通过socket这种约定,一台计算机可以向另外一台计算机发送数据和接收数据. 2.Socket的本质 ...

  9. Installing harbor-2.6.2 on openEuler

    一.Installing harbor-2.6.2 on openEuler 1 地址 https://goharbor.io https://github.com/goharbor/harbor 2 ...

  10. Go语言核心36讲16----接口

    你好,我是郝林,今天我们来聊聊接口的相关内容. 前导内容:正确使用接口的基础知识 在Go语言的语境中,当我们在谈论"接口"的时候,一定指的是接口类型.因为接口类型与其他数据类型不同 ...