{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 函数的参数\n", "\n", "## 一、基础知识" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Python 没有函数重载" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def ff( x ): return x \n", "def ff( x,y ): return x + y # 同名函数后面的遮挡前面函数\n", "\n", "ff(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 值传递和引用传递" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 值传递 :字符串、数字、元组 [ 不可变 ]\n", "\n", "def ff(x): x += 1 # 不改变调用值 a\n", "a = 5 ; ff(a) ; a" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 引用传递: 列表、字典 [可变]\n", "\n", "def ff(x): x.append(1) # 改变调用值 a\n", "a = [ 0 ] ; ff(a); a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 二、函数参数形式\n", "\n", "Python函数的参数传递非常灵活,支持多种参数形式,使得函数定义和调用更加强大和灵活。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.1 普通参数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 位置参数\n", "\n", "位置参数是最基本的参数形式,按照它们在函数定义中的顺序传递。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Alice, you are 25 years old\n" ] } ], "source": [ "def greet(name, age): # name 和 age 是位置参数\n", " print(f\"Hello {name}, you are {age} years old\")\n", "\n", "# 调用方式\n", "greet(\"Alice\", 25) # 参数按照定义的顺序传入,\"Alice\" 对应 name,30 对应 age" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 默认参数\n", "\n", "为某些参数设置默认值,如果调用时不提供该参数,则使用默认值。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Bob. You are 18 years old.\n", "Hello, Charlie. You are 25 years old.\n" ] } ], "source": [ "def greet(name, age=18):\n", " print(f\"Hello, {name}. You are {age} years old.\")\n", "\n", "greet(\"Bob\") # 使用默认年龄\n", "greet(\"Charlie\", 25) # 提供具体年龄" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 调用函数时指定参数名\n", "\n", "通过参数名进行传递,参数顺序可以任意调整,提高了代码的可读性。" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Charlie 20\n", "Charlie 20\n", "Charlie 20\n", "Charlie 20\n" ] } ], "source": [ "def greet( name,age ): print( name,age) \n", "\n", "greet( name = 'Charlie', age=20 ) # 命名传递参数,更清楚\n", "greet( age = 20,name = 'Charlie' ) # 顺序可以改变\n", "greet( 'Charlie',age = 20 ) # 混合使用,普通调用放前面,命名调用放后面\n", "\n", "name,age = 'Charlie',20 \n", "greet( name = name, age = age ) # 形参、实参数同名的情况" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.2 可变参数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 可变位置参数 \n", "- 使用星号(*)定义可变数量的位置参数,这些参数被存储在一个元组中。" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n", "15\n" ] } ], "source": [ "def sum_numbers(*args):\n", " return sum(args)\n", "\n", "# 调用方式\n", "print(sum_numbers(1, 2, 3)) # 输出: 6\n", "print(sum_numbers(1, 2, 3, 4, 5)) # 输出: 15" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 关键字参数(命名参数、字典参数)\n", "\n", "- 放在可变位置参数后面 \n", "- 调用的时候,必须使用名字赋值形式" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, (2, 3), 2)" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def ff(a,*b,c): return a,b,c\n", "\n", "ff( 1,c = 2 ) \n", "ff( 1,2,c = 2 )\n", "ff( 1,2,3,c = 2 ) " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 没有可变参数,也要用 * 占位\n", "\n", "def ff(a,*,b): return a,b\n", "ff(1,b=2)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 () 0\n", "1 2\n", "1 3\n" ] }, { "data": { "text/plain": [ "(None, None)" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 有默认值的情况\n", "\n", "def ff( a,*b,c = 0 ): print(a,b,c) \n", "ff(1)\n", "\n", "def ff( a = 1,*, b = 2 ): print(a,b) \n", "ff(),ff( b = 3 ) # 前面是带默认值的位置参数" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello Alice, you are 25 years old\n" ] } ], "source": [ "# 函数以空*开头,强制函数用关键字参数,可提升代码可读性\n", "\n", "def greet(*, name, age): # * 之后的参数只能用关键字参数\n", " print(f\"Hello {name}, you are {age} years old\")\n", "\n", "# 正确调用\n", "greet(name=\"Alice\", age=25)\n", "\n", "# 错误调用\n", "# greet(\"Alice\", 25) # 无 关键字命名 错误" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 可变关键字参数\n", "\n", "使用两个星号(**)定义可变数量的关键字参数。这些参数被存储在一个字典中。" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "name: Eve\n", "age: 28\n", "city: London\n" ] } ], "source": [ "def print_info(**kwargs):\n", " for key, value in kwargs.items():\n", " print(f\"{key}: {value}\")\n", "\n", "# 调用方式\n", "print_info( name=\"Eve\", age=28, city=\"London\" )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 解包可变参数\n", "\n", "在函数调用时,可以使用星号(*)或两个星号(**)来解包列表、元组或字典,将其中的元素或键值对作为参数传递给函数。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def func(a, b, *args, **kwargs):\n", " print(a, b, args)\n", " for key, value in kwargs.items():\n", " print(key, value)\n", "\n", "args = (3, 4) # 或者 [\"Alice\", 25, \"Beijing\"] 其它序列容器\n", "kwargs = {'x': 5, 'y': 6} \n", "func(1, 2, *args, **kwargs) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.3 混合使用各种参数" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 () 2 {}\n", "1 () 2 {'d': 3}\n", "1 () 2 {'d': 3, 'e': 4}\n", "1 () 2 {'d': 3, 'e': 4}\n", "1 () 2 {'d': 3, 'e': 4}\n" ] } ], "source": [ "# 顺序:普通参数、可变位置参数、命名参数、可变关键字参数\n", "# 可变位置参数后面,命名参数选取剩下的就是可变关键字参数\n", "\n", "def ff( a,*b,c,**d ): print( a,b,c,d )\n", "\n", "ff( 1,c=2 )\n", "ff( 1,c=2,d=3 )\n", "ff( 1,c=2,d=3,e=4 )\n", "ff( 1,d=3,e=4,c=2 )\n", "ff( 1,d=3,c=2,e=4 ) # 可推测其参数确定机制" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "普通参数 name : 1\n", "普通参数 age : 2\n", "可变参数 args : (3,)\n", "命名参数 department : math\n", "字典参数 kwargs : {}\n" ] } ], "source": [ "def ff( name , age ='20', *args, department = 'cs', **kwargs ): \n", " '''\n", " name 是必需的位置参数。\n", " age 是带有默认值的位置参数。\n", " *args 收集额外的位置参数。\n", " **kwargs 收集额外的关键字参数。\n", " ''' \n", " print('普通参数 name :', name )\n", " print('普通参数 age :', age )\n", " print('可变参数 args :', args )\n", " print('命名参数 department :', department )\n", " print('字典参数 kwargs :', kwargs )\n", "\n", "# ff()\n", "# ff(1)\n", "# ff(1,2)\n", "# ff(1,2,3)\n", "# ff(1,2,3,4)\n", "# ff(1,2,3,department='math')\n", "# ff(1,2,3,u1='math')\n", "# ff(1,2,3,4,5,u1='tsg',department='cmu',u2='pku' )" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 基础代码中常用( *args,**kwargs )参数表来抽象表示一般函数的参数\n", "\n", "def ff( *args,**kwargs ): \n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 总结\n", "\n", "#### 参数顺序规则\n", "\n", "def function(\n", " 位置参数, # 普通参数\n", " 默认参数 = '默认值', # 默认参数\n", " *args, # 可变位置参数 \n", " 关键字参数, # 普通关键字参数\n", " **kwargs # 可变关键字参数\n", "): pass\n", " \n", "\n", "- 可以有默认值:普通位置参数、 关键字参数" ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }