Python 函数定义详解(More on Defining Functions)- 默认参数/位置参数/关键字参数

在这里插入图片描述

1.函数的定义和调用方法

1.1函数定义方法

"""
    def 关键字用来定义一个函数。
    function_name 是函数名,应遵循命名规范。
    parameter1, parameter2, ... 是函数的参数列表,可以是任意数量和类型的参数。
    函数体是用缩进(通常为4个空格)来表示的代码块。
    return 语句用于返回函数的结果。
"""
# def function_name(parameter1, parameter2, ...):
    # Function body
    #    return result

1.2函数调用方法

"""
function_name 是要调用的函数名。
argument1, argument2, ... 是传递给函数的参数列表。
函数执行后,将返回一个结果,可以将其赋值给一个变量。
"""
# result = function_name(argument1, argument2, ...)

1.3示例:定义一个函数计算两个数之和

"""
    定义个函数计算两个数之和
"""
def add_numbers(num1,num2):# 定义函数
    result = num1 +num2
    return result

sum = add_numbers(100,200)# 调用函数

print(sum) # 输出结果为300

2.默认值参数(Default Argument Values)

  Python允许在函数定义中为参数提供默认值,这使得函数在调用时可以省略部分参数,从而提供了更大的灵活性。

2.1示例1:简单的示例函数,用于打招呼

def greet(name, greeting="Hello"):
    # 参数name是位置参数,必须提供值。
    # 参数greeting是默认值参数,如果不提供值,默认为"Hello"。
    return f"{greeting}, {name}!"

# 调用函数时可以只提供name参数,greeting参数会使用默认值。
result1 = greet("Alice")
print(result1)  # 输出 "Hello, Alice!"

# 也可以同时提供name和greeting参数的值,这将覆盖默认值。
result2 = greet("Bob", "Hi")
print(result2)  # 输出 "Hi, Bob!"

  greet函数接受两个参数,name和greeting,其中greeting是一个带有默认值的参数,默认值为"Hello"。当调用函数时,如果只提供了name参数,那么greeting参数将使用默认值。如果同时提供了name和greeting的值,那么提供的值将覆盖默认值。

2.2python官网示例

def ask_ok(prompt, retries=4, reminder='Please try again!'):
    # 定义一个函数ask_ok,接受三个参数:prompt、retries和reminder。
    # 默认情况下,retries被设置为4,reminder被设置为'Please try again!'。
    
    while True:
        # 进入一个无限循环,直到用户提供有效的回答或达到重试次数。
        
        ok = input(prompt)
        # 使用input()函数向用户提供一个提示,等待用户的输入,并将输入保存在ok变量中。
        
        if ok in ('y', 'ye', 'yes'):
            return True
            # 如果用户输入了'y', 'ye', 'yes'中的一个,函数返回True。
            
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
            # 如果用户输入了'n', 'no', 'nop', 'nope'中的一个,函数返回False。
            
        retries = retries - 1
        # 如果用户输入既不是True也不是False,减少重试次数retries。
        
        if retries < 0:
            raise ValueError('invalid user response')
            # 如果重试次数小于0,引发一个ValueError异常,表示用户提供的回答无效。
            
        print(reminder)
        # 如果用户提供的回答不在有效选项内,打印提醒消息reminder,然后继续循环。

# 通过以下方式调用:
ask_ok('Do you really want to quit?')#只给出必选实参
ask_ok('OK to overwrite the file?', 2)#给出一个可选实参
ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')#给出所有实参

2.3重要提示

  默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果。
  下面以列表、字典或类实例示例说明:

"""
    列表作为默认参数
    在这个例子中,期望每次调用append_to函数时,列表都是新的,互不干扰。
    然而,由于默认参数的特性,得到的列表是共享的,所以每次调用都会影响这个列表。
"""
def append_to(num, target=[]):  
    target.append(num)  
    return target  
  
print(append_to(1))  # 输出:[1]  
print(append_to(2))  # 输出:[1, 2],而不是[1]  
print(append_to(3))  # 输出:[1, 2, 3],而不是[1, 2]
"""
    字典作为默认参数
    期望每次调用update_dict函数时,字典都是新的,但是因为默认参数的特性,得到的字典是共享的。
"""
def update_dict(key, target={}):  
    target[key] = key  
    return target  
  
print(update_dict(1))  # 输出:{1: 1}  
print(update_dict(2))  # 输出:{1: 1, 2: 2},而不是{1: 1}  
print(update_dict(3))  # 输出:{1: 1, 2: 2, 3: 3},而不是{1: 1, 2: 2}
"""
    类实例作为默认参数
    期望每次调用increment_by函数时,TestClass的实例都是新的,互不干扰。然而,由于默认参数的特性,得到的实例是共享的,所以每次调用都会影响这个实例的状态
"""
class TestClass:  
    def __init__(self):  
        self.value = 0  
  
    def increment(self, num):  
        self.value += num  
        return self.value  
  
def increment_by(num, target=TestClass()):  
    target.increment(num)  
    return target.value  
  
print(increment_by(1))  # 输出:1  
print(increment_by(2))  # 输出:3,而不是2  
print(increment_by(3))  # 输出:6,而不是5

2.4建议

  1.使用可变对象作为默认参数时,可以考虑使用None作为默认值,并在函数内部进行判断和处理。每次调用的时候,都会创建一个新的列表,避免了共享默认参数的问题。

def append_to(num, target=None):  
    if target is None:  
        target = []  
    target.append(num)  
    return target
    
print(append_to(1))
print(append_to(2))
print(append_to(3))

  2.对于字典或类实例等可变对象,可以考虑使用函数内部的局部变量作为默认值,而不是使用一个全局变量。每次调用的时候都会创建一个新的字典或实例,避免共享默认参数的问题。

def update_dict(key, target=None):  
    if target is None:  
        target = {}  
    target[key] = key  
    return target
def increment_by(num, target=None):  
    if target is None:  
        target = TestClass()  
    target.increment(num)  
    return target.value

  3.如果可能的话,尽量避免使用可变对象作为默认参数,可以避免潜在的共享问题。考虑使用不可变对象(如字符串、数字或元组)作为默认参数。
  4.如果默认参数的值是一个复杂对象(如列表、字典或类实例),并且需要重复使用,可以考虑将该对象定义为全局变量或属性,并在函数内部引用该全局变量。可以确保每次调用函数时都使用同一个对象,避免了重复创建对象的开销。但是需要注意避免全局变量导致的命名冲突和其他问题。
  5.如果默认参数的值是一个不可变对象(如字符串、数字或元组),并且需要重复使用,可以考虑将该对象定义为函数的一个属性或静态变量。这样可以避免每次调用函数时都重新计算该对象的开销。但是需要注意避免该对象被修改导致的问题。

3.关键字参数(Keyword Arguments

  kwarg=value 形式的关键字参数 也可以用于调用函数。
  在函数调用中前面带有标识符(例如 name=)或者作为包含在前面带有 ** 的字典里的值传入。
  如:3和5在以下对*complex()*方法的调用中均属于关键字参数
  complex(real=3, imag=5)
  complex(**{‘real’: 3, ‘imag’: 5})

3.1官网示例

"""
    parrot()函数接受一个必选参数(voltage)和三个可选参数(state, action 和 type)
    其中voltage既可以是位置参数,也可以是关键字参数;
    state、action、type是关键字参数
"""
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, "!")

# 可用下列方法进行调用
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

  函数调用时,关键字参数必须跟在位置参数后面。所有传递的关键字参数都必须匹配一个函数接受的参数(比如,actor 不是函数 parrot 的有效参数),关键字参数的顺序并不重要。这也包括必选参数,(比如,parrot(voltage=1000) 也有效)。不能对同一个参数多次赋值。
#%% md

3.2 *args和**kwargs

  在Python中,*args 和 **kwargs 是特殊的参数,用于在函数定义中接收任意数量的位置参数和关键字参数。
args 表示一个元组类型的参数,用于接收任意数量的位置参数。这些参数将按照它们在函数调用中的顺序依次赋值给args参数。在函数体中,可以像处理普通元组一样处理 *args 参数。
**kwargs 表示一个字典类型的参数,用于接收任意数量的关键字参数。这些参数将作为字典的键值对赋值给 **kwargs参数。在函数体中,可以使用 **kwargs参数来访问这些关键字参数。

"""
    *argument 形参接收一个元组,在它之前的为位置参数
    **keywords 形参接收一个字典,传参数数时必须带变量名
"""
def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    for kw in keywords:
        print(kw, ":", keywords[kw])

#调用该函数
cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

# 输出结果:
"""
    -- Do you have any Limburger ?
    -- I'm sorry, we're all out of Limburger
    It's very runny, sir.
    It's really very, VERY runny, sir.
    ----------------------------------------
    shopkeeper : Michael Palin
    client : John Cleese
    sketch : Cheese Shop Sketch
"""

4.特殊参数

  默认情况下,参数可以按位置或显式关键字传递给 Python 函数。为了让代码易读、高效,最好限制参数的传递方式,这样,开发者只需查看函数定义,即可确定参数项是仅按位置、按位置或关键字,还是仅按关键字传递。
函数定义如下:
在这里插入图片描述

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

4.1 位置或关键字参数

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

4.2 仅位置参数

  仅限位置时,形参的顺序很重要,且这些形参不能用关键字传递。仅限位置形参应放在 / (正斜杠)前。/ 用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有 /,则表示没有仅限位置形参。
/ 后可以是 位置或关键字 或 仅限关键字 形参。

4.3 仅限关键字参数

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

"""
    / 和 * 在参数中使用的语法:
    def function(positional_or_keyword_parameters, *, keyword_only_parameters):
    def function(positional_only_parameters, /, positional_or_keyword_parameters,*, keyword_only_parameters):
    
    在“/”左边的参数被视为仅位置参数
    如果函数定义中“/”没有指定,则函数中所有参数都不是仅位置参数
    仅位置参数的可选值的逻辑与位置-关键字参数的逻辑相同。
    一旦使用默认值指定了仅位置参数,下面的仅位置参数和位置-关键字参数也需要具有默认值。
"""
# 有效的函数定义:
def fun1(positional1, positional2, /, positional_or_keyword, *, keywords):pass
def fun2(positional1, positional2=None, /, positional_or_keyword=None, *, keywords):pass
def fun3(positional1, positional2=None, /, *, keywords):pass
def fun4(positional1, positional2=None, /):pass
def fun5(positional1, positional2, /, positional_or_keyword):pass
def fun6(positional1, positional2, /):pass
def fun7(positional_or_keyword, *, keywords):pass
def fun8(*, keywords):pass

# 无效定义
def fun9(positional1, positional2=None, /, positional_or_keyword, *, keywords):pass
def fun10(positional1=None, positional2, /, positional_or_keyword=None, *, keywords):pass
def fun11(positional1=None, positional2, /):pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/122655.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s:kubectl 详解

目录 1 kubectl 2 基本信息查看 2.1 查看 master 节点状态 2.2 查看命名空间 2.3 查看default命名空间的所有资源 2.4 创建命名空间app 2.5 删除命名空间app 2.6 在命名空间kube-public 创建副本控制器&#xff08;deployment&#xff09;来启动Pod&#xff08;nginx-wl…

LaMa 论文复现:Resolution-robust Large Mask Inpainting with Fourier Convolutions

代码&#xff1a;GitHub - andy971022/auto-lama 论文&#xff1a;https://arxiv.org/abs/2109.07161 1 LaMa 论文简介 2 LaMa代码复现 2.1 环境部署 2.1.1 下载源码&#xff0c;创建环境&#xff0c;安装必需库 git clone https://github.com/advimman/lama cd lama con…

Figma转Sketch文件教程,超简单!

相信大家做设计的都多多少少听过一点Figma和Sktech&#xff0c;这2个设计软件是目前市场上很受欢迎的专业UI设计软件&#xff0c;在全球各地都有很多粉丝用户。但是相对来说&#xff0c;Figma与Sketch只支持iOS系统有所不同&#xff0c;Figma是一个在线设计软件&#xff0c;不限…

TikTok shop美国小店适合哪些卖家做?附常见运营问题解答

一、Tiktok shop小店分类 大家都知道&#xff0c;美国小店可以分为5 种&#xff1a; 美国本土个人店: 最灵活&#xff0c;有扶持政策&#xff1b;美国法人企业店&#xff1a;要求高&#xff0c;有扶持政策&#xff1b;美国公司中国人占股店 (ACCU店) : 权重相对低&#xff0c…

Java版本spring cloud + spring boot企业电子招投标系统源代码

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及审…

《向经典致敬》第二届粤港澳大湾区著名歌唱家音乐会完美落幕

百年经典 歌坛盛会 “《向经典致敬》第二届粤港澳大湾区著名歌唱家音乐会暨2023福田人才之夜”完美落幕 2023年11月4日&#xff0c;阳光普照&#xff0c;秋意正浓&#xff0c;由中共深圳市福田区委宣传部、深圳市福田区文学艺术界联合会主办&#xff0c;深圳歌唱家协会承办&…

SpringBoot测试类启动web环境

1.坐标修改 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> 2.测试类测试 说明&#xff1a;SpringBootTest()中的webEnvironment值的说明&#xff1b; 2.1不启…

VMware 虚拟机如何修改虚拟机系统的网卡速率为万兆——筑梦之路

1. 找到虚拟机系统安装目录 比如E:\vmware-system\kali\ 2. 找到vmx文件&#xff0c;用记事本打开 将 ethernet0.virtualDev "e1000" 这行改为 ethernet0.virtualDev "vmxnet3" 后保存&#xff08;注意vmxnet3全为小写&#xff09;&#xff0c;如果没…

Babylonjs学习笔记(九)——第一人称控制器

书接上回&#xff0c;实现第一人称控制器&#xff01;&#xff01;&#xff01; 以下步骤&#xff0c;缺一不可 相机相关设置 camera.applyGravity true; // 应用重力 camera.checkCollisions true; // 开启碰撞检测 const camera new FreeCamera("camera",ne…

Yakit工具篇:WebFuzzer模块之序列操作

简介 Web Fuzzer 序列就是将多个 Web Fuzzer 节点串联起来&#xff0c;实现更复杂的逻辑与功能。例如我们需要先进行登录&#xff0c;然后再进行其他操作&#xff0c;这时候我们就可以使用 Web Fuzzer 序列功能。或者是我们在一次渗透测试中需要好几个步骤才能验证是否有漏洞这…

Next.js 项目——从入门到入门(Eslint+Prettier)

Next.js官方文档地址 什么是 Next.js 这是一个用于生产环境的 React 框架。 Next.js 为您提供生产环境所需的所有功能以及最佳的开发体验&#xff1a;包括静态及服务器端融合渲染、 支持 TypeScript、智能化打包、 路由预取等功能&#xff0c;无需任何配置。 功能&#xff…

uniapp小程序接入腾讯云【增强版人脸核身接入】

文档地址&#xff1a;https://cloud.tencent.com/document/product/1007/56812 企业申请注册这边就不介绍了&#xff0c;根据官方文档去申请注册。 申请成功后&#xff0c;下载【微信小程序sdk】 一、解压sdk&#xff0c;创建wxcomponents文件夹 sdk解压后发现是原生小程序代…

数据结构-堆

一、什么是堆 先了解两种特别的二叉树 满二叉树 除最后一层无任何子节点外&#xff0c;每一层上的所有结点都有两个子结点的二叉树 完全二叉树 完全二叉树相对于满二叉树来说&#xff0c;最后一层叶子节点从左到右中间没有空缺的&#xff0c;像这样&#xff1a; 计算机科学…

驾考在线答题系统源码:含PC+手机版驾考宝典多题库

安装说明&#xff1a; 1、上传到网站根目录 2、用 phpMyadmin 导入数据库文件 db.sql 3、修改数据库链接文件 /ThinkPHP/Conf/convention.php# &#xff08;记得不要用记事本修改&#xff0c;否则可能会出现验证码显示不了问题&#xff0c;建议用 Notepad 4、 帐号 admin 密码…

Git 入门使用 —— 建库、代码上下传、常用命令

目录 一、Git 入门 1.1 Git简介 1.2 Git安装 1.3 创建码云仓库 二、Git 使用 2.1 git初始化操作 2.2 代码上传 2.3 代码下载 2.4 代码更新 2.4.1 仓库管理者 2.4.1 仓库使用者 三、Git 常用命令 一、Git 入门 1.1 Git简介 Git是一个开源的分布式版本控制系统&am…

Wireshark分析tcp交互过程

三次握手 客户端发起请求 Tcp段长度为575字节&#xff0c;seq1&#xff0c;ack1&#xff0c;next_seq576 服务器响应&#xff1a; Tcp段长度为175字节&#xff0c;seq1&#xff0c;ack576&#xff0c;next_seq176 客户端响应&#xff1a; Tcp段长度523字节&#xff0c;seq576&…

Lazarus安装和入门资料

azarus-2.2.6-fpc-3.2.2-win64 下载地址 Lazarus 基础教程 - Lazarus Tutorials for Beginners Lazarus Tutorial #1 - Learning programming_哔哩哔哩_bilibili https://www.devstructor.com/index.php?pagetutorials Lazarus是一款开源免费的object pascal语言RAD IDE&…

数据结构: 哈希桶

目录 1.概念 2.模拟实现 2.1框架 2.2哈希桶结构 2.3相关功能 Modify --Insert --Erase --Find 2.4非整型数据入哈希桶 1.仿函数 2.BKDR哈希 1.概念 具有相同地址的key值归于同一集合中,这个集合称为一个桶,各个桶的元素通过单链表链接 2.模拟实现 2.1框架 a.写出…

H5横屏适配方案

横屏模式一般使用场景比较少&#xff0c;特殊情况除外&#xff0c;一般用于游戏、操作性比较大的网页会采用横屏 整体代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" conte…

【第2章 Node.js基础】2.2 Node.js回调函数

学习目标 &#xff08;1&#xff09;理解Node.js的回调函数&#xff1b; &#xff08;2&#xff09;掌握回调函数的使用。 什么是回调函数 回调函数是一种特殊的函数&#xff0c;它作为参数传递给另一个函数&#xff0c;并在特定的事件或条件发生时被调用。回调函数通常用于异…