首页 > 其他分享 >函数的基本使用

函数的基本使用

时间:2023-12-06 18:24:11浏览次数:27  
标签:基本 bar 函数 形参 func 使用 print def

什么是函数

函数就相当于具备某一功能的工具

使用函数必须遵循一些规则:

  • 先定义
  • 后调用

为何要使用函数

  1. 组织结构不清晰,可读性差
  2. 代码冗余,臃肿
  3. 因为代码冗余导致可维护性,扩展性差

函数的定义

函数是一个工具,函数名应该定义为动词,而不是名词。

def function_name(parameters):
    """函数文档字符串"""
    # 函数体
    # 可以包含多条语句
    return expression
  1. def 是定义函数使用的关键字

  2. function_name是函数名,符合变量命令规范即可。

    • 函数的命名应该反应出函数的功能

    • 函数名指向函数内存地址,是对函数体代码的引用

    • 函数名加上一个小括号就实现了这个函数的功能

  3. ( )括号内放函数需要输入的参数,即使函数不需要输入任何参数,也不能省略( )

  4. parameters是函数的参数,确切的说是形参,即形式参数,如果函数不需要形参,可以不传参

  5. : 括号后面要加上冒号,然后下一行开始缩进编写函数体的代码

  6. """函数文档字符串"""这部分是函数的注释部分,描述函数的功能和参数的意义

  7. 函数体代码块:函数体代码块是完成函数的功能部分

  8. return后面跟函数的返回值,可以没有,也可以1个或多个

    • 没有返回值,默认返回None

定义函数发生的事情

  1. 申请内存空间保存函数体代码
  2. 将上述内存地址绑定给函数名
  3. 定义函数不会执行函数体代码,但是会检测函数体的语法

调用函数发生的事情

  1. 通过函数名找到函数的内存地址
  2. 然后加括号就是在触发函数体代码的执行

形式1:无参函数

def func():
    print('哈哈哈')
 
func()

# 哈哈哈

示范1

def bar():  # bar=函数的内存地址,所以可以直接访问到
    print("from bar")


def foo():
    print(bar)  # 打印bar()函数的内存地址
    bar()  # 内存地址加括号可以执行函数体代码
    print("from foo")


foo()
<function bar at 0x0000018F1054F0A0>
from bar
from foo

示范2

def foo():
    print(bar)  # 打印bar()函数的内存地址
    bar()  # 内存地址加括号可以执行函数体代码
    print("from foo")


def bar():  # bar=函数的内存地址,所以可以直接访问到
    print("from bar")


foo()
<function bar at 0x000001B62C1D4670>
from bar
from foo

示范3

def foo():
    # 因为bar在
    print(bar)  # 打印bar()函数的内存地址
    bar()  # 内存地址加括号可以执行函数体代码
    print("from foo")


foo()


def bar():
    print("from bar")

# 结果报错:NameError: name 'bar' is not defined

在给出的代码中,调用 bar() 的语句位于 foo() 函数的定义之前,这会导致 NameError 异常。

在 Python 中,函数必须在调用它们之前被定义。因此,当 foo() 函数在定义的时候尝试调用 bar() 函数时,由于 bar() 函数还没有被定义,Python 会引发 NameError 异常。

要解决这个问题,您可以将 bar() 函数的定义移动到 foo() 函数的上方,或者将 bar() 函数的定义放在整个代码块的最上方。

以下是修改后的代码示例:

def bar():
    print("from bar")

def foo():
    print(bar)  # 打印bar()函数的内存地址
    bar()  # 内存地址加括号可以执行函数体代码
    print("from foo")

foo()

这样修改后,首先定义了 bar() 函数,然后定义了 foo() 函数,并在其中调用了 bar() 函数。现在,代码将按预期运行,输出如下:

<function bar at 0x00000123ABCD>
from bar
from foo

请注意,函数的定义顺序对代码的执行顺序非常重要。确保在调用函数之前先定义它们。

形式2:有参函数

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


func(1, 2)  
# 1 2

形式3:空函数,函数体代码为pass或者三个点...

一般都是使用pass,遵循python原则

def func(x, y):
    pass


func(1, 2)
# 无结果输出
def func(x, y):
    ...


func(1, 2)
# 无结果输出

三种定义方式各用在何处

判断函数是否被写死了,就是看需不需要外部传参

1. 无参函数的应用场景

# 无参函数,假如用到30个地方
def interactive():
    name = input("输入姓名:")
    age = input("输入年龄:")
    gender = input("输入性别:")
    
    msg = f"姓名:{name} 年龄:{age} 性别:{gender}."
    print(msg)


interactive()
interactive()
输入姓名:小满
输入年龄:3
输入性别:女
姓名:小满 年龄:3 性别:女.
输入姓名:大乔
输入年龄:4
输入性别:女
姓名:大乔 年龄:4 性别:女.

2. 有参函数的应用场景

如果把函数想象成工厂,形参相当于函数的材料,返回值相当于产品。

def add(x, y):  # 参数--> 原材料
    result = x + y
    return result  # 产品


res = add(10, 2)
print(res)  # 12

3. 空函数的应用场景

主要用于构思程序的时候,可以适量写提示语或者文档描述

def auth_user():
    pass


def download_file():
    pass


def upload_file():
    pass

函数的调用

1. 语句的形式:只加括号调用函数

interactive()
add(1, 2)

2. 表达式形式

def add(x, y):  # 参数 --> 原材料
    result = x + y
    return result


# 赋值表达式
r1 = add(1, 2)
print(r1)  # 3

# 数学表达式
res = add(10, 2) * 10
print(res)  # 120

3. 函数调用可以当做参数

def add(x, y):  # 参数 --> 原材料
    result = x + y
    return result  # 产品


# 函数调用可以当做参数
res = add(add(1, 2), 10)  # 第一次add(1, 2)返回3  然后add(3, 10)结果13
print(res)  # 13

函数的返回值

1. 什么时候需要返回值

看用户需求

2. 创建返回值

  1. return是函数结束的标志,即函数体代码一旦运行到return会立刻终止函数的运行,并且会将return后的值当做本次运行的结果返回。
    • 即便写了很多死循环,只要遇到return立马终止函数的运行
  2. 返回值None的几种情况:
    1. 函数体内没有return
    2. return后没有任何代码(即单独一个return)
def func():
    while True:
        while True:
            while True:
                while True:
                    while True:
                        print("就打印了一次就结束了")
                        # return 之后什么都不写
                        return
                    

res = func()
print(res)
就打印了一次就结束了
None

返回一个值

return 值

def func():
    result = 10
    return result


res = func()
print(res)  # 10

返回多个值

用逗号分割开多个值,会被return返回成元组

def func():
    return 10, "小满", True, [3, 4], {1: 1}


res = func()
print(res, type(res))
# (10, '小满', True, [3, 4], {1: 1}) <class 'tuple'>

函数的参数

形参

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

相当于变量名

实参

在调用阶段传入的值成为实际参数,简称实参

相当于变量值

形参与实参的关系

  1. 在调用阶段,实参(变量值)会绑定给形参(变量名)
  2. 这种绑定关系只能在函数体内使用
  3. 实参与形参的绑定关系在调用时生效,函数调用结束后解出绑定关系
def func(x, y):  # x y 形参
    print(x, y)
    

func(1, 2)  # 1 2实参,结果也是1 2

实参是传入的值,但是可以是以下形式

形式1

func(1, 2)

形式2

a = 1
b = 2
func(a, b)

形式3

func(int("1"), 2)
func(func(1, 2), func(2, 3), 333)

形参与实参的具体使用

位置参数

按照从左到右的顺序依次定义的参数称之为位置参数

位置形参

在函数定义阶段,按照从左到右的顺序直接定义的“变量名”

特点:必须被传值,多一个不行少一个也不行

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


func(1, 2)  # 1 2

位置不够,报错的一般是miss...

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


func(1)  # 报错TypeError: func() missing 1 required positional argument: 'y'

参数多了,报错的一般是but ... given

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


func(1, 2, 3)  # 报错TypeError: func() takes 2 positional arguments but 3 were given

位置实参

在函数调用阶段,按照从左到右的顺序依次传入的值

特点:按照顺序与形参一一对应

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


func(1, 2)  # 1 2

关键字实参

在调用函数阶段,按照key=value的形式传入的值

特点:指名道姓的给某个形参传值,可以完全不参考顺序

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


func(y=2, x=1)  # 1 2

混合使用(强调)

  1. 位置参数必须放在关键之参数之前

    一般报错 follows ...

    def func(x, y):
        print(x, y)
    
    
    func(1, y=2)  # 1 2
    func(y=2, 1) # 报错 语法错误 SyntaxError: positional argument follows keyword argument
    
  2. 不能为同一形参重复传值

    一般报错 multiple ...

    def func(x, y):
        print(x, y)
    
    
    func(1, y=2, x=3)  # 报错
    func(1, 2, x=3, y=4)  # 报错
    # TypeError: func() got multiple values for argument 'x'
    

默认形参

在定义函数阶段,就已经被赋值的形参,称之为默认形参

特点:在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值

def func(x, y=3):
    print(x, y)


func(x=1)  # 1 3
func(5)  # 5 3 
func(x=1, y=444)  # 1 444

什么情况下使用位置参数和默认形参

看情况,实例分析注册功能

def register(name, age, gender="男"):
    print(name, age, gender)


register("老夫子", 18)
register("夏侯淳", 19)
register("阿珂", 16, "女")
register("小满", 3, "女")
老夫子 18 男
夏侯淳 19 男
阿珂 16 女
小满 3 女

位置形参与默认形参混用(强调)

  1. 位置形参必须在默认形参的左边

    def func(y=2, x):  # 报错 语法错误 SyntaxError: non-default argument follows default argument
        pass
    

    正确演示

    def func(x, y=2): 
        pass
    
  2. 默认参数的值是在函数定义阶段被赋值的,准确的说被赋值的是内存地址

    示范1

    m = 2
    
    
    def func(x, y=m):  # y --> 2的内存地址
        print(x, y)  # 1 2
    
    
    func(1)
    

    示范2

    m = 2
    
    
    def func(x, y=m):  # y --> 2的内存地址
        print(x, y)  # 1 2
    
    
    m = 333333333
    func(1)
    

    示范3

    m = [11111]
    
    
    def func(x, y=m):  # y --> [11111]的内存地址
        print(x, y)  # 1 [11111, 3333333333]
    
    
    m.append(3333333333)
    func(1)
    

虽然默认值可以被指定为任意数据类型,但是不推荐使用可变类型

解决可变类型形参

如果有默认参数为可变类型的需求,下面是推荐的写法,将形参默认值设置为None内部进行判断,增加可变类型

def func(x, y, z, ls=None):
    if ls is None:
        ls = []

    ls.append(x)
    ls.append(y)
    ls.append(z)

    print(ls)


new_ls = [44, 55, 66]
func(1, 2, 3)
func(77, 88, 99, new_ls)
[1, 2, 3]
[44, 55, 66, 77, 88, 99]

函数最理想的状态

函数的调用只跟函数本身有关系,不受外界代码的影响

可变长度参数(*与**的用法)

可变长度指的是在调用函数时,传入的值(实参)的个数不固定,而实参是用来为形参赋值的,所以对应着,针对溢出的实参必须有对应的形参来接收。

可变长度的位置参数

*形参名:用来接收溢出的位置参数,溢出的位置实参会被*保存成元组的格式,然后赋值给紧跟其后的形参名

*后面跟的可以是任意名字,但是约定俗成应该是args

def func(x, y, *args):  # (3, 4, 5, 6)
    print(x, y, args)
    print(type(args))


func(1, 2, 3, 4, 5, 6)
1 2 (3, 4, 5, 6)
<class 'tuple'>
def my_sum(*args):
    count = 0
    for index in args:
        count += index
    return count


res = my_sum(1, 24, 4, 5, 7)
print(res)  # 41

可变长度的关键字参数

**形参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典格式,然后赋值给紧跟其后的形参名,**后跟的可以是任意名字,但是约定俗成应该是kwargs

def func(x, y, **kwargs):
    print(x, y, kwargs)
    print(type(kwargs))
    

func(1, y=2, a=1, b=2, c=3)
1 2 {'a': 1, 'b': 2, 'c': 3}
<class 'dict'>

*可以用在实参中,实参中带*,先*后被打散成位置实参

需要注意的是,数量需要一一对应,实参*后只要是可以被for循环的类型都行(list str tuple ...)

def func(x, y, z):
    print(x, y, z)


func(*[11, 22, 33]) 
ls = [44, 55, 66]
func(*ls)
11 22 33
44 55 66
def func(x, y, z):
    print(x, y, z)  # x y z


func(*{"x": 1, "y": 2, "z": 3})

形参与实参都带*

def func(x, y, *args):
    print(x, y, args)  # 1 2 ([3, 4, 5, 6],)


func(1, 2, [3, 4, 5, 6])  
def func(x, y, *args):
    print(x, y, args)  # 1 2 (3, 4, 5, 6)


func(1, 2, *[3, 4, 5, 6])  
def func(x, y, *args):
    print(x, y, args)  # h e ('l', 'l', 'o')


func(*"hello")

**可以用在实参中(**后面跟的只能是字典),实参中带**,先**后的值打散成关键字实参

def func(x, y, z):
    print(x, y, z)  # 1 2 3


func(**{"x": 1, "y": 2, "z": 3})  # 理解为 func(x=1, y=2, c=3)

形参与实参都带*

def func(x, y, **kwargs):
    print(x, y, kwargs)  # 111 222 {'a': 333, 'z': 444}


func(**{"y": 222, "x": 111, "a": 333, "z": 444})  # func(y=222, x=111, a=333, z=444)

混用***

*args必须在**kwargs之前

def func(**kwargs, *args):
    pass

# 结果报错 语法错误
def func(*args, **kwargs):
    print(args, kwargs)  # (1, 2, 3, 4, 5) {'a': 6, 'b': 7, 'c': 9}


func(1, 2, 3, 4, 5, a=6, b=7, c=9)

拓展(掌握好这个对语法糖非常有帮助)

def index(x, y, z):
    print("index======>", x, y, z)  # index======> 1 2 3


def wrapper(a, b, c):
    index(a, b, c)


wrapper(1, 2, 3)

关键字命名参数(了解)

命名关键字参数:

在定义函数时,*后自定义的参数,如下所示,称之为命名关键字参数

特点

命名关键字实参必须按照key=value的形式为其传值

不传参不行,位置参数也不行

def func(x, y, *, a, b):  # # 其中a和b成为命名关键字参数
    print(x, y)  # 1 2
    print(a, b)  # 222 111


func(1, 2, a=222, b=111)

*后面的key=value并不是默认参数

# 不会报错
def func(x, y, *, b=222, a):  # 次处的b就不叫默认参数了,可以理解为为关键字参数b赋了一个默认值
    print(x, y)  # 1 2
    print(a, b)  # 222 222


func(1, 2, a=222)

组合使用(了解)

基本上没有应用场景,仅做了解.

形参混用的顺序:位置形参,默认形参,*args, 命名关键字形参,**kwargs

def func(a, b, c, *args, x=500, y, **kwargs):
    print('a=', a)
    print('b=', b)
    print('c=', c)
    print('x=', x)
    print('y=', y)
    print('args=', args)
    print('kwargs=', kwargs)


func(20, 50, '纯二', '哈利波特', '会魔法', y=9527, music='天空之城', movie='哈尔的移动城堡', author='宫崎骏')
a= 20
b= 50
c= 纯二
x= 500
y= 9527
args= ('哈利波特', '会魔法')
kwargs= {'music': '天空之城', 'movie': '哈尔的移动城堡', 'author': '宫崎骏'}

实参混用的顺序:
遵循位置参数在关键字参数左边就行,包括***的参数

def func(x, y, z, a, b, c):
    print('x=', x)
    print('y=', y)
    print('z=', z)
    print('a=', a)
    print('b=', b)
    print('c=', c)


func(111, 333, 444, a=222, **{'b':555, 'c':666})
# func(111, 333, 444, a=222, b=555, c=666)
x= 111
y= 333
z= 444
a= 222
b= 555
c= 666

标签:基本,bar,函数,形参,func,使用,print,def
From: https://www.cnblogs.com/ccsvip/p/17880234.html

相关文章

  • C++_调用函数以及不同数据类型
    调用其他文件中的函数add_library可以生成我们所需的动态库或者静态库,我们要把制作出的库文件发布出去供第三方使用一些函数方法单独在一个cpp的源文件中定义,然后在另一个源文件中需要用到自定义的函数时直接调用就可以了!方法1.学过c++的人可能最熟悉的方法还是利用头文件......
  • pandas函数映射
    pandas函数映射importpandasaspdimportnumpyasnpfrompandasimportSeries,DataFramedf1=DataFrame(np.random.choice(range(20),size=(4,3),replace=False),index=list('ABCD'),columns=list('abc'))print(df1)#使用numpy函......
  • 在中间件中使用 Scoped 模式服务
    作用域(Scoped)服务和瞬时(Transient)服务都与请求的生命周期相关,但它们之间有一些区别。1.作用域(Scoped)服务:-作用域服务的生命周期与每个请求的生命周期相对应。也就是说,每个请求都会创建一个作用域服务的实例,并且在请求处理过程结束时该实例将被释放。-作用域服务在同一个......
  • windows 使用wsl安装linux环境
    网上的教程大多都需要安装虚拟机,找寻起来比较麻烦,特此记录本机用的window11系统第一步:关掉防火墙,以管理员身份打开终端然后输入wsl--install只输入wsl也可,会有对应的帮助信息弹出如果弹出无法解析服务器的名称或地址。如果网络链接没有问题,则需要去检查自己的网络配置,设置DNS......
  • 无涯教程-Erlang - get函数
    此方法用于获取映射中特定键的值。get-语法get(key,map)key   - 这是需要为其返回值的键。Map  - 这是需要在其中搜索键的Map。get-返回值如果在Map上找到键,则返回值。-module(helloLearnfk).-export([start/0]).start()->Lst1=[{"a",1},{"......
  • 为什么 idea 建议去掉 StringBuilder,使用“+”拼接字符串
    为什么idea建议去掉StringBuilder,使用“+”拼接字符串目录为什么idea建议去掉StringBuilder,使用“+”拼接字符串1、普通拼接2、循环拼接总结各位小伙伴在字符串拼接时应该都见过下面这种提示:内容翻译:报告StringBuffer、StringBuilder或StringJoiner的任何用法,这些用法......
  • 金蝶云星空使用webapi查询单据附件的主键
    业务需求:查询采购价目表的附件 详细操作 一、查询单据附件查看账套单据附件 查询采购价目表的单据内码和单据体内码SELECTa.FNUMBER,a.FID,b.FENTRYID,b.FSEQFROMt_PUR_PriceListaLEFTJOINt_PUR_PriceListEntrybONa.FID=b.FIDWHEREa.FNUMBER='CGJM......
  • 函数的基本定义语法
    函数的定义和调用函数定义的语法'''def函数名():执行代码的函数体return返回值'''【1】函数基本定义deffun():pass #...fun()【2】无参无返回值的函数定义deflogin():username=input("用户名:>>>").strip()password=input(&......
  • VUE3引入pinia配置使用
    文档:https://pinia.vuejs.org/zh/introduction.html1.引入pinnanpminstallpinia-S2.在src文件里面创建store文件article.js在main.js中引用pinnaimport{defineStore}from'pinia'//你可以对`defineStore()`的返回值进行任意命名,但最好使用store的名字,同时以......
  • 软件测试/人工智能|Python逻辑运算符如何灵活使用
    前言当初学者探索Python编程时,理解逻辑运算符是掌握编程逻辑和决策流程的重要一环。逻辑运算符允许我们对多个条件进行组合,以便进行更复杂的逻辑判断。让我们深入了解Python中常用的逻辑运算符及其使用方法。逻辑运算符逻辑运算符一般用来解决当有多个关系条件需要判断时使用,......