Python函数

1、定义函数(def)

      定义函数使用关键字def,后跟函数名与括号内的形参列表。函数语句从下一行开始,并且必须缩进。

def 函数名(参数列表):
    函数体

函数内的第一条语句是字符串时,该字符串就是文档字符串,也称为 docstring,详见 文档字符串。利用文档字符串可以自动生成在线文档或打印版文档,还可以让开发者在浏览代码时直接查阅文档;Python 开发者最好养成在代码中加入文档字符串的好习惯。

       函数在 执行 时使用函数局部变量符号表,所有函数变量赋值都存在局部符号表中;引用变量时,首先,在局部符号表里查找变量,然后,是外层函数局部符号表,再是全局符号表,最后是内置名称符号表。因此,尽管可以引用全局变量和外层函数的变量,但最好不要在函数内直接赋值(除非是 global 语句定义的全局变量,或 nonlocal 语句定义的外层函数变量)。

         在调用函数时会将实际参数(实参)引入到被调用函数的局部符号表中;因此,实参是使用 按值调用 来传递的(其中的  始终是对象的 引用 而不是对象的值)。 当一个函数调用另外一个函数时,会为该调用创建一个新的局部符号表。

特殊用法

函数定义在当前符号表中把函数名与函数对象关联在一起。解释器把函数名指向的对象作为用户自定义函数。还可以使用其他名称指向同一个函数对象,并访问访该函数:

def fib(n):
    a, b = 0, 1
    while i in range(n):
        a = a + b
        b = a
    print(' '.join(a))


f = fib

f(100)
#输出结果:0 1 1 2 3 5 8 13 21 34 55 89

python函数return语句的用法:

       python中的return语句会返回函数的值,如果return后面没有表达式参数则返回None值。函数执行完后返回的值也为None值(就是说如果没有return语句,返回的就是None)

2.函数定义详解

       python的函数在调用时必须接受一个必选参数和(0-n)个可选参数。其中函数第一个参数必须是必选参数(位置参数)

2.1 默认参数 

       在Python中,函数的默认参数允许我们在定义函数时为参数提供默认值。当调用函数时,如果没有为该参数提供值,则使用默认值。默认参数可以有多个,但必须在非默认参数之后。在调用时可以输入比原来定义时更少的参数。

例:

def greet(name, message="Hello"):
    print(message + ", " + name)

greet("Alice")  # 输出:Hello, Alice
greet("Bob", "Hi")  # 输出:Hi, Bob

       在定义函数时,可以使用任何合法的表达式作为默认参数的值,包括其他函数的调用、变量、常量等。

        需要注意的是,默认参数的值在函数定义时计算,并且只计算一次。这意味着如果默认参数是一个可变对象(如列表、字典等),并且在函数中被修改,那么这些修改将在后续函数调用中保持不变。

例:

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

#结果
[1]
[1, 2]
[1, 2, 3]

       不想在后续调用之间共享默认值时,可以在函数内部创建一个新的可变对象。这样,每次调用函数时,都会使用新创建的对象作为默认值。

例:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

2.2 关键字参数

       关键字参数是在调用函数时使用参数名称来指定参数值的一种方式。我们调用函数时提供参数的值不必严格按照原来的定义的顺序,可以通过“参数名=值”的形式以任意顺序提供参数。这使得在函数调用时可以忽略参数的顺序,只需指定参数的名称即可。

注:函数调用时,关键字参数必须跟在位置参数后面。所有传递的关键字参数都必须匹配一个函数接受的参数。关键字参数的顺序并不重要。这也包括必选参数。

例:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "volts through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")


#该函数接受一个必选参数(voltage)和三个可选参数(state, action 和 type)。该函数可用下列方式调用:

parrot(1000)                                          # 1 positional argument
parrot(voltage=1000)                                  # 1 keyword argument
parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments
parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments
parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments
parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword


#以下调用函数的方式都无效:

parrot()                     # required argument missing
parrot(voltage=5.0, 'dead')  # non-keyword argument after a keyword argument
parrot(110, voltage=220)     # duplicate value for the same argument
parrot(actor='John Cleese')  # unknown keyword argument

2.2.1命名关键字参数

      命名关键字参数是在函数定义时,使用关键字来指定参数值,并且这些参数必须在函数调用时显式地指定。与位置参数和关键字参数不同,命名关键字参数必须按照指定的参数顺序提供参数,并且不能省略任何参数。

       命名关键字参数的语法是在函数定义时,在参数列表中使用一个*来分隔位置参数和命名关键字参数。

greet(name="Alice")  # 输出:Hello, Alice
greet(name="Bob", message="Hi")  # 输出:Hi, Bob

命名关键字参数的优点是:

  1. 显式地指定参数名可以提高代码的可读性,使函数调用更加清晰明确。
  2. 在函数定义时,可以为命名关键字参数提供默认值,从而使函数调用更加灵活。
  3. 在函数调用时,可以按照指定的参数顺序提供参数,避免参数顺序错误导致的bug。

2.3 特殊参数

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only

 / 和 * 是可选的。这些符号表明形参如何把参数值传递给函数:位置、位置或关键字、关键字。关键字形参也叫作命名形参。

2.3.1  位置或关键字参数

函数定义中未使用 / 和 * 时,参数可以按位置或关键字传递给函数。

2.3.2  仅位置参数

       此处再介绍一些细节,特定形参可以标记为 仅限位置仅限位置 时,形参的顺序很重要,且这些形参不能用关键字传递。仅限位置形参应放在 / (正斜杠)前。/ 用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有 /,则表示没有仅限位置形参。

   / 后可以是 位置或关键字 或 仅限关键字 形参。

2.3.3 仅限关键字参数

         把形参标记为 仅限关键字,表明必须以关键字参数形式传递该形参,应在参数列表中第一个 仅限关键字 形参前添加 *

2.3.4 小结

可以按照以下的规范定义函数 

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
# 顺序:必选参数、默认参数、可变参数、关键字参数和命名关键字参数

说明:

  • 使用仅限位置形参,可以让用户无法使用形参名。形参名没有实际意义时,强制调用函数的实参顺序时,或同时接收位置形参和关键字时,这种方式很有用。

  • 当形参名有实际意义,且显式名称可以让函数定义更易理解时,阻止用户依赖传递实参的位置时,才使用关键字。

  • 对于 API,使用仅限位置形参,可以防止未来修改形参名时造成破坏性的 API 变动。

2.4 任意实参列表(variadic 参数)

       在Python中,可以使用*args来接收任意数量的位置参数。*args会将传入的位置参数打包成一个元组,可以在函数内部进行处理。

 例:

def print_items(*args):
    for item in args:
        print(item)

print_items("apple", "banana", "orange")

       在本例中,*args将传入的参数打包成为元组("apple", "banana", "orange"),并在函数内部进行迭代。

       另外,如果想要接收任意数量的关键字参数,可以使用**kwargs**kwargs会将传入的关键字参数打包成一个字典,可以在函数内部进行处理。

例:

def print_items(**kwargs):
    for key, value in kwargs.items():
        print(key + ": " + value)

print_items(fruit1="apple", fruit2="banana", fruit3="orange")

2.5 解包实参列表

定义:Python的解包实参列表是指将一个可迭代对象(如列表、元组、集合等)作为函数的参数,并使用 *  运算符将其解包为多个单独的参数传递给函数。

解释:Python函数调用要求独立的位置参数,但实参在列表或元组里时,要将元素进行解包拆分成单个元素例如,内置的 range() 函数要求独立的 start 和 stop 实参。如果这些参数不是独立的,则要在调用函数时,用 * 操作符把实参从列表或元组解包出来

def my_function(a, b, c):
    print(a, b, c)

my_list = [1, 2, 3]
my_function(*my_list)

#输出结果
1 2 3

       在上面的例子中,列表my_list被解包为三个参数1、2和3,并作为实参传递给my_function函数。函数my_function会按照参数的顺序打印出这三个值。

2.6 Lambda表达式 (匿名函数)

格式:

lambda [arg1[,arg2],....argn]]:expression

       在语法上,匿名函数只能是单个表达式。在语义上,它只是常规函数定义的语法糖。与嵌套函数定义一样,lambda 函数可以引用包含作用域中的变量:

def make_incrementor(n):
    return lambda x: x + n

f = make_incrementor(42)


f(0)  #输出42
f(1)  #输出43

2.7 文档字符串

       文档字符串(Docstring)是Python中的一种注释方式,用于描述函数、类、模块等代码元素的用途、功能和使用方法。文档字符串通常被放置在代码元素的定义之后,以三个连续的引号(''')或双引号(""")包围。

       文档字符串可以包含多行文本,用于提供详细的描述和说明。它可以包括函数的参数、返回值、异常处理等信息,以及示例代码和用法示例。

例:

def greet(name):
    """
    打印问候语
    :param name: str,要问候的人的名字
    :return: None
    """
    print(f"Hello, {name}")

在这个示例中,文档字符串描述了函数的功能和参数,使用了参数的类型注解(type hinting)来指定参数的类型,以及返回值的类型。文档字符串还使用了冒号(:)和缩进来表示参数和返回值的说明。

文档字符串可以通过__doc__属性来访问,例如:

print(greet.__doc__)

#输出

打印问候语
:param name: str,要问候的人的名字
:return: None

       以下是文档字符串内容和格式的约定。

       第一行应为对象用途的简短摘要。为保持简洁,不要在这里显式说明对象名或类型,因为可通过其他方式获取这些信息(除非该名称碰巧是描述函数操作的动词)。这一行应以大写字母开头,以句点结尾。

       文档字符串为多行时,第二行应为空白行,在视觉上将摘要与其余描述分开。后面的行可包含若干段落,描述对象的调用约定、副作用等。

       Python 解析器不会删除 Python 中多行字符串字面值的缩进,因此,文档处理工具应在必要时删除缩进。这项操作遵循以下约定:文档字符串第一行 之后 的第一个非空行决定了整个文档字符串的缩进量(第一行通常与字符串开头的引号相邻,其缩进在字符串中并不明显,因此,不能用第一行的缩进),然后,删除字符串中所有行开头处与此缩进“等价”的空白符。不能有比此缩进更少的行,但如果出现了缩进更少的行,应删除这些行的所有前导空白符。转化制表符后(通常为 8 个空格),应测试空白符的等效性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值