python函数基础

函数的基本使用

1、什么是函数

ps:函数就是盛放代码的容器
  具备某一功能的工具 ---> 函数
  事先准备工具的过程 ---> 函数的定义
  遇到应用场景拿来就用 ---> 函数的调用
    
       所以函数的使用原则:
     先定义   后调用

2、为何要用函数

解决下述问题:
    1、代码组织结构不清晰,可读性差
    2、可扩展性差

3、如何用函数

定义的语法

def 函数名(参数1,参数2,...):
    """文档描述"""
    函数体
    return 返回值

1、def:定义函数的关键字
2、函数名:函数名指的是函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能
3、括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型
4、冒号:括号后面要加冒号,然后在下一行开始缩进编写函数体的代码
5、''''文档描述''':描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性
6、函数体:由语句和表达式组成
7、return 返回值:定义函数的返回值,return是可有可无的,不一定要加在最后一行

调用的语法

函数的调用
1、先找到名字
2、根据名字调用代

一、定义函数

定义函数发生的事情
1、申请内存空间把函数体代码放进去
2、将函数内存地址绑定给函数名
    强调:定义函数只检测语法,不执行代码
def login():   # login = 函数的内存地址
    print(111)
    print(222)
    print(333)
print(login)
>>>:
<function login at 0x000002193ECEC1F0>

二、调用函数

调用函数发生的事情
1、先通过函数名定位到函数内存地址
2、函数内存地址() ---> 触发函数体代码的运行
    强调:调用函数才会执行函数体代码
login()
# >>>:
# 111
# 222
# 333

三、定义函数的三种形式

无参
def func():
    print('hello world')
有参
def max2(x,y):
    if x > y:
        print(x)
    else:
        print(y)
max2(10,20)   # 20
def login():
    pass   # pass代表什么都不做
    # ...

四、调用函数的三种方式

语句
len('hello')
表达式
res = len('hello') * 10
print(res)  # 50
可以当做一个参数传给另一个参数
print(len('hello'))  # 5

函数的参数

形参

在函数定义阶段括号内指定的参数,称之为形式参数,简称形参

位置形参

在定义函数时,按照从左到右的顺序依次定义的变量名,称之为位置形参
    特点:每次调用,必须被赋值

def func(x,y):
    print(x)
    print(y)
func(1,2)

默认形参

在定义函数时,就已经为某个形参赋值了,称之为默认形参
    特点:调用函数时,可以不用为其赋值
    
def func(name,age=18):
    print(name)
    print(age)
func('egon')
>>>:
egon
18

注意

注意:可以混用位置形参与默认形参,但是:
  1、位置形参必须在前面
  2、默认形参的值,通常应该是不可变类型
  3、默认形参的值是在函数定义阶段赋值的

实参

在函数调用阶段括号内传入的值,称之为实际参数,简称实参

位置实参

在调用函数时,按照从左到右的顺序依次传入的值,称之为位置实参
    特点:按照位置为形参赋值,一一对应
    
func(1,2)  # 1 2
func(2,1)  # 2 1

关键字实参

在调用函数时,按照key=value的形式传值,称之为关键字实参
  特点:可以大乱顺序,但是仍然能够指名道姓的为指定的形参赋值
    
def func(name,age):
    print(name)
    print(age)
func(age=18,name='egon')
>>>:
egon
18

注意

可以混用位置实参与关键字实参,但是:
    1、位置实参必须在关键字实参的前面
    2、不能为同一形参重复赋值

形参与实参的关系

在调用函数时,实参值会绑定给形参名,在函数调用完毕之后解除绑定
# 形参
def func(x,y):
    # x = 111
    # y = 222
    print(x,y)

# 实参
m = 111
n = 222
func(111,222)

可变长系列

详情参见:https://www.cnblogs.com/ZhZhang12138/p/14200978.html#hanshudefanhuizhi


可变长参数指的是在调用函数时,传入的实参个数不固定,对应着必须有特殊形式的形参来接收移除实参

实参无非两种形式

  溢出的位置实参 ---> *

  溢出的位置关键字实参 ---> **

函数的返回值

return详解

1、函数可以有多个return,但只要执行一次return,整个函数就立即结束,并且将return后的值当做本次调用的结果返回
2、return后返回值有三种情况
(1)return 值:返回的就是这一个值
(2)return 值1,值2,值3:返回的是一个元组
(3)函数内可以没有return、或者return None、或者return:默认返回None

函数对象

在python中,函数时第一类对象,函数是第一等公民

本质:函数可以当变量使用
函数对象指的是函数可以被当做’数据’来处理,具体可以分为四个方面的使用,如下

def func():  # func = 函数的内存地址
    print('from func')

# # 1、可以赋值
f = func
print(f)
f()

# 2、可以当做参数传给另外一个函数
def foo(x):
    print(x)
foo(func)   # <function func at 0x000001FF3854C1F0>

# 3、可以当做函数的返回值
def foo(x):
    return x
res = foo(func)
print(res)  # <function func at 0x000001F48080C1F0>

# 4、可以当做容器类型的元素
l = [func,]
print(l)   # [<function func at 0x000001F132A5C1F0>]
l[0]()   # from func

函数的嵌套

函数的嵌套调用

def ma2(x,y):
    if x > y:
        return x
    else:
        return y

def max4(a,b,c,d):
    res1 = ma2(a,b)
    res2 = ma2(res1,c)
    res3 = ma2(res2,d)
    return res3
print(max4(11,99,33,12))  # 99

函数的嵌套定义

def f1():
    x = 10
    def f2():
        print(x)
    print(x)
    print(f2)
f1()
>>>:
10
<function f1.<locals>.f2 at 0x00000255051DA0D0>

名称空间与作用域

名称空间与作用域的关系是在函数定义阶段(扫描语法时)就确立的,与什么时候调用以及调用位置无关

namespace名称空间:存放名字的地方
内置名称空间:存放内置的名字
    生命周期:python解释器启动则产生,关闭则销毁

全局名称空间:存放的是顶级的名字
    生命周期:运行python文件时则产生,python文件运行完毕则销毁

局部名称空间:存放的是函数内的名字
    生命周期:调用函数则产生,函数调用完毕则销毁

核心:名字的访问优先级:
         基于当前所在的位置向外查找
            函数内 ---> 外层函数 ---> ... ---> 全局 ---> 内置

LEGB      
    L:内置       
    E:外层函数       
    G:全局       
    B:内置

作用域

全局作用域:内置名称空间+全局名称空间
    特点:全局存活,全局有效

局部作用域:局部名称空间
    特点:临时存活,局部有效
在函数内,无论嵌套多少层,都可以查看到全局作用域的名字,若要在函数内修改全局名称空间中名字的值,当值为不可变类型时,则需要用到global关键字
# 案例一:
l = []
def func():
    l.append(111)
    # l = [11,22,33]  # 定义了一个新列表,与全局无关
func()
print(l)  # [111]


# 案例二:
x = 111
def func():
    global x
    x = 222
func()
print(x)   # 222
对于嵌套多层的函数,使用nonlocal关键字可以将名字声明为来自外部嵌套函数定义的作用域(非全局)


def f1():
    x = 2
    def f2():
        nonlocal x  # 声明变量名是来自于外层函数的,不是全局
        x = 3
    f2()   # 调用f2(),修改f1作用域中名字x的值
    print(x)  #在f1作用域查看x
f1()
原文地址:https://www.cnblogs.com/ZhZhang12138/p/14867610.html