函数的定义

函数, 在几乎所有语言中, 都是一个主要的代码结构

你可以将函数理解为定义一个代码块来执行特定的操作

一个函数由下面几个部分组成

  1. 函数名
  2. 参数
  3. 返回值
  4. 函数体
def a_test_function(name: str):
  "this is a test function "
  print("hello " + name)

a_test_function("world")
hello world
组成部分含义
def def 为python的关键词, 用于定义一个函数, 所有函数的定义都是通过def关键词来申明
a_test_function申明函数名为a_test_function, 后续函数的调用都通过a_test_function来进行调用
name: str 申明函数的参数名为name, 类型为字符串类型,指定类型是可选的
“this is a test function “函数体的第一行语句为字符串时, 该字符串就是文档字符串,也称为 docstring
print(“hello ” + name)函数体,函数体的定义需要缩进, 也是具体的执行代码, 这边a_test_function函数做的事情就一起, 就是打印hello name

a_test_function("world"), 是函数的调用, “world”用于指定参数name为world

所以函数执行的结果是打印hello world

python支持按参数名指定参数和按位置指定参数, 所以上述代码调用等价于

a_test_function(name="world"), 在这个调用中, 直接显示的指定name参数的值为world

作用域

函数在其函数体内有自己的作用域名, 其中, 参数的作用域只在函数体内, 也就是函数的参数只能在函数体内访问, 在其他地方不能访问

函数在访问一个变量时, 会先在函数局部作用域中查找, 然后在全局作用域中查找, 最后在内置符号表中查找

所以, 函数可以访问和修改函数外部的变量, 但是建议不要直接访问函数外部的变量, 这样会使代码的可读性变得很差, 除非在变量的定义是就定义成了global或者nonlocal变量

global标识函数内的变量为全局变量

x = 10  # 全局变量

def modify_global():
    global x  # 声明使用全局变量 x
    x += 5
    print("Inside function:", x)

modify_global()
print("Outside function:", x)

Inside function: 15
Outside function: 15

nonlocal标识函数内变量为上层函数的变量

def outer():
    x = 10  # 外层函数变量

    def inner():
        nonlocal x  # 声明修改外层函数的 x
        x += 1
        print("Inner x:", x)
    
    inner()
    print("Outer x:", x)

outer()

Inner x: 11
Outer x: 11

函数的返回值

在Python中, 所有的函数都有返回值, 在没有显示的指定返回值时, 也就是没有在函数内部调用return xx 时, python 会隐式的定义函数的返回值为None

函数的参数

默认参数

默认参数是指, 在函数定义的时候给定一些参数以默认值, 当函数调用时没有指定对应参数值, 则使用默认值

def default_arg_function(first_name='dot', last_name = 'k'):
  print(first_name + last_name)

default_arg_function()

输出:
dotk

default_arg_function('hello', 'world')
输出:
helloworld

在定义默认参数时, 需要有一个原则, 就是默认参数都在函数的末尾, 也就是, 所有有默认值的参数都要跟在没有默认值参数的后面

下面这个例子, 就会报语法错误

>>> def default_arg_function(first_name='dot', last_name):
  File "<stdin>", line 1
    def default_arg_function(first_name='dot', last_name):
                                                        ^
SyntaxError: non-default argument follows default argument
>>>
>>> #将默认参数移到末尾则不会报错
>>> def default_arg_function(first_name, last_name='k'):
...     print(first_name + last_name)
...
>>>

关键词参数

python中函数的调用, 除了直接通过位置来确定调用参数以外, 还可以通过关键词的方式确定函数的参数, 也就是以参数名=参数值的方式指定参数值

首先定义一个函数

def test(name, age, gender):
  print(name, age, gender)

可以通过位置指定参数的方式调用: test('点点K', 18, ‘male’)

也可以通过关键词指定的方式进行调用: test(name='点点K', gender=‘male’, age=18), 我们注意到, 在进行关键词指定时, 参数的位置已经不在重要了, 可以跟函数定义的位置不一致

我们也可以通过混合的方式来进行调用: test('点点K', gender=‘male’, age=18), 使用位置参数指定name为点点K, 使用关键词参数指定gender和age分别为male和18

以上三种调用方式都是等价的

特殊参数

在python的函数定义中, 当最后一个参数为**name时, 接收的是所有未定义的关键词参数, 在**name前的*name, 接收的是所有未定义的位置参数

*name 返回一个元组, 元组的内容是调用时指定的未定义的位置参数

**name返回一个字典, 内容时调用时指定的未定义的关键词参数

>>> def test(name, *position_argvs, **keywords_argvs):
...     print(name, position_argvs, keywords_argvs)
...
>>> test('点点K', 'hello', 'tuple', say='hello', hi='world')

点点K ('hello', 'tuple') {'say': 'hello', 'hi': 'world'}

解包调用

可以通过解包tuple或list来指定位置参数完成函数调用

通过*将列表或者元组解包, 从而指定位置参数完成函数调用


>>> def test(say, hi):
...     print(say + " " + hi)
...
>>> args = ('hello', 'world')
>>> test(*args)
hello world

以此类推, 可以解包字典来指定关键词参数完成函数的调用

通过**完成字典的解包, 从而指定关键词参数完成函数的调用

>>> def test(say, hi):
...     print(say + " " + hi)
...
>>> args = {'say': 'hello', 'hi':'world'}
>>> test(**args)
hello world

解包的操作跟好跟特殊参数相呼应

在函数体内是, 使用*name获取未定义的位置参数得到一个元组, 在调用时使用*name解包对应的元组或list完成位置参数的指定

函数体内**name获取未定义的关键词参数得到一个字典, 在调用时使用**name解包对应的字典来完成关键词参数的指定

lambda 表达式

lambda表达式是python中用与定义匿名函数的语法糖, 可以很方便的定义一个简单的函数

具体的使用方式是 lambda arg…: dosomething, :前用于定义参数, 多个参数用,分割, :后用于定义函数体

比如

f = lambda x, y: x+y
f(1, 2)

# 结果
3

By 点点K

Leave a Reply

Your email address will not be published. Required fields are marked *