首页 > 其他分享 >函数的调用方式、函数的参数、类型提示语、名称空间

函数的调用方式、函数的参数、类型提示语、名称空间

时间:2024-04-15 19:33:52浏览次数:20  
标签:调用 函数 age list num 参数 print name

【一】函数的调用方式

def student(name, age):
    print(f"my name is {name} and my age is {age}")

[1]直接调用函数

  • 函数名()-----> 调用函数
student(name = 'max', age = 18)

[2]用表达式调用函数

  • 用一个新变量存储函数的内存地址然后调用
def add(x,y):
    return x + y
result = add(2, 5) + 9
print(result)# 16
  • 函数作为返回值
def delete(a, b):
    return add(a, b)
print(delete(6, 9)) #15

def add(x,y):
    return x + y
def func():
    return add
foo = func()
print(foo(1, 9)) #10

[3]函数可以作为参数传递给另一个函数

def add(x,y):
    return x + y

def login(func):
    return func()
login(add) #所以login()函数中func参数进来的是add()中的x,y

【二】函数的参数

[1]形参和实参

  • 形参即在定义函数时,括号内声明的参数。
    • 形参本质就是一个变量名,用来接收外部传来的值。
  • 实参即在调用函数时,括号内传入的值
    • 值可以是常量、变量、表达式或三者的组合:
def add(x, y):
    return x + y

# 1:实参是常量
res_first = add(1, 2)
print(res_first) # 3

# 2:实参是变量
x = 5
y = 6
res_second = add(x, y)
print(res_second) #11

# 3:实参是表达式
res_third = add(10 * 2, 10 * add(3, 4))
print(res_third) #90

# 4:实参可以是常量、变量、表达式的任意组合
a = 2
res_forth = add(a, 10 * add(3, 4))
print(res_forth) #72
  • 在调用有参函数时,实参(值)会赋值给形参(变量名)

  • 在Python中,变量名与值只是单纯的绑定关系,而对于函数来说,这种绑定关系只在函数调用时生效,在调用结束后解除。

[2]位置此参数

  • 位置即顺序位置参数是按顺序定义的参数:
    • 在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参
    • 凡是按照这种形式定义多的形参都必须被传值

(1)有位置参数而不传值会报错

# 定义位置形参:name,age,sex,三者都必须被传值
def register(name, age, sex):
    print('Name:%s Age:%s Sex:%s' % (name, age, sex))

register()  # TypeError:缺少3个位置参数

(2)对应位置传参

# 定义位置形参:name,age,sex,三者都必须被传值
def register(name, age, sex):
    print('Name:%s Age:%s Sex:%s' % (name, age, sex))


register("max", 18, "男")
# Name:max Age:18 Sex:男

  • 在调用函数时,按照从左到右的顺序依次定义实参,称为位置实参
  • 凡是按照这种形式定义的实参会按照从左到右的顺序与形参一一对应

[3]关键字参数

在调用参数是,实参可以是 key=value 的形式

  • 凡是关键字传参,可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值
def student(name, age, gender):
    print(f"my name is {name} and my age is {age} and my gender is {gender}")

student('max',age=18,gender='male')
#输出结果:
my name is max and my age is 18 and my gender is male

# student(age=18,'max',gender='male')
# 这个是错误的,位置参数必须在关键字参数之前('max'必须在前面)

[4]默认参数

  • 在定义函数时,就已经为形参赋值,这类形参称之为默认参数
    • 当函数有多个参数时,需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数

(1)默认参数不传值

# 定义位置形参:name,age 必须被传值 sex默认值为 男
def register(name, age, sex="男"):
    print('Name:%s Age:%s Sex:%s' % (name, age, sex))


# 可以使用关键字和位置参数混合传参,但是一定要位置参数在前,关键字参数在后
# 参数有默认值,可以不传值
register("max", age=18)

# Name:max Age:18 Sex:男

(2)默认参数传值

【1】默认参数初始化
  • 默认参数必须在位置参数之后
  • 默认参数的值仅在函数定义阶段被赋值一次
# 定义位置形参:name,age 必须被传值 sex默认值为 男
def register(name, age, sex="男"):
    print('Name:%s Age:%s Sex:%s' % (name, age, sex))


# 可以使用关键字和位置参数混合传参,但是一定要位置参数在前,关键字参数在后
# 参数有默认值,重复传值会覆盖掉默认值
register("Max", age=18, sex="女")

# Name:Max Age:18 Sex:女
【2】默认参数为可变数据类型
  • 默认参数的值通常应设为不可变类型
  • 每次调用是在上一次的基础上向同一列表增加值
def append_list(num, list_inner=[]):
    list_inner.append(num)
    return list_inner


# 传入参数 1 ,对应在函数中的空列表参数中添加值
res_1 = append_list(1)
print(res_1)  # [1]

# 由于列表是可变数据类型,所以在上面的基础上,再添加值会添加到上一个列表内
res_2 = append_list(2)
print(res_2)  # [1, 2]

# 同理
res_3 = append_list(3)
print(res_3)  # [1, 2, 3]

【3】默认参数为空
  • 默认参数的值通常应设为不可变类型
def append_list(num, list_inner=None):
    if list_inner is None:
        list_inner = []
    list_inner.append(num)
    return list_inner


# 传入参数 1 ,对应在函数中的参数为空
# 在函数内部会有一个判断,不传值为空,则列表重置为空
res_1 = append_list(1)
print(res_1)  # [1]

# 在函数内部会有一个判断,不传值为空,则列表重置为空
res_2 = append_list(2)
print(res_2)  # [2]

# 在函数内部会有一个判断,不传值为空,则列表重置为空
res_3 = append_list(3)
print(res_3)  # [3]

[5]可变长参数

  • 参数的长度可变指的是在调用函数时,实参的个数可以不固定
    • 而在调用函数时,实参的定义无非是按位置或者按关键字两种形式
    • 这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数

【1】可变长位置参数(*args)

[1]任意类型参数
  • 如果在最后一个形参名前加 * 号,那么在调用函数时,溢出的位置实参,都会被 * 接收,以元组的形式保存下来赋值给该形参
# 在最后一个形参名args前加*号
def foo(x, y, z=1, *args):
    print(x)
    print(y)
    print(z)
    print(args)


foo(1, 2, 3, 4, 5, 6, 7)
# 实参1、2、3按位置为形参x、y、z赋值
# 多余的位置实参4、5、6、7都被*接收,以元组的形式保存下来,赋值给args
# 即args=(4, 5, 6,7)



def student(name, age, gender='male', *pppp):
    print(name)
    print(age)
    print(gender)
    print(pppp)

# student('dream', 18, 'male', 999, 888, 666)
num_list = [1,2,3,4,5,6,7,8,9,10]
num_list_tuple = (1,2,3,4,5,6,7,8,9,10)
name = 'dream'

# 解包语法 : * + 可迭代类型 就能将每一个元素单独解包出来
print(num_list)
print(*num_list)
print(*num_list_tuple)
print(*name)
student('dream', 18, 'male', num_list)
student('dream', 18, 'male', *num_list)

【2】命名关键字参数

'''
def student(name, age, gender, class_id, addr):
    print(name, age, gender, class_id, addr)
# 调用上面的函数传递参数可以按照关键字传递参数
# 也可以按照位置传递参数
student('dream', 18, 'male', 2, '上海')
'''

# 在位置参数中间指定 * 隔开,
# * 之前的位置参数支持位置和关键字传参数
# * 后面的参数必须按照关键字传参数
'''
def student(name, age, gender,*, class_id, addr):
    print(name, age, gender, class_id, addr)
student('dream', 18, 'male',class_id= 2, addr='上海')
'''

# 在命名关键字参数中指定默认参数的时候,默认参数允许放在位置参数之前
# 但是普通的位置参数是不允许关键字参数放在位置参数之前的
'''
def student(name, age, gender='male',*, class_id=2, addr):
    print(name, age, gender, class_id, addr)
student('dream', 18, 'male',class_id= 2, addr='上海')
'''

[6]混合使用

# 综上所述所有参数可任意组合使用,但定义顺序必须是:
# 位置参数、默认参数、*args 、**kwargs
# 所有位置参数、默认参数、*args 、**kwargs 混合使用的时候不允许使用关键字参数
# def student(name, age=18,*args,**kwargs):
# 所有位置参数、默认参数、*args 、**kwargs | **kwargs 必须在 *args 之后
'''
def student(name, age=18, *args, **kwargs):
    print(...)
'''

【三】类型提示语Optional

  • 什么是注解
    • 在定义函数的位置参数的时候可以指定参数的类型
def student(name: str, age: int, score: float, is_male: bool):
    print(name, type(name))
    print(age, type(age))
    print(score, type(score))
    print(is_male, type(is_male))


# 按照在定义函数的时候声明的参数类型传递参数
student('dream', 18, 100.0, True)
'''
# 【2】可变数据类型
# 字典 列表 元组 集合
# 字典:{键:值} ---> 约束二者
'''
from typing import Dict, List,Tuple,Set

def student(user_data: Dict[str, int], id_list: List[int],num_tuple:Tuple[str],num_set:Set[int]):
    print(user_data, type(user_data))
student({'age': 18}, [1],('1',),{2,3})
'''

# 【三】约定函数的返回值类型
'''
def add(x:int,y:int)->int:
    return x + y

print(add(1,2))
'''

# 【四】函数返回值既可以是字符串也可以是数字
# union 既可以返回一个又可以返回另一个类型
'''
from typing import Union

def add(x: int, y: int) -> Union[str, int]:
    # return x + y
    # return str(x + y)
    return True
'''

#【五】可以返回可选的采纳数类型
# 可以返回None ,也可以返回 int
'''
from typing import Optional
def add(x: int, y: int) ->Optional[None]:
    return 1
print(add(1,2))
'''

【四】名称空间

[1]什么是名称空间

  • 名称空间就是存放函数名与函数值对应关系的地方
  • 变量名 = 变量值
  • 先开辟一块内存空间 ,把函数值扔到内存空间中 ---> 内存空间
  • 然后你需要 用变量名 和 变量值进行绑定 ---> 名称空间

[2]名称空间的分类

(1)内建名称空间

  • 会随着代码启动而生成,随着代码结束而关闭
  • 第一个加载的名称空间
  • if def else

(2)全局名称空间

# 随着内建名称空间加载完成
# 走到了你自己写的代码里面
# 自己创建的变量名 / 函数名 / 类名
'''
# 这个列表是全局的列表
# 列表是可变数据类型 ---> 列表被修改后id不变
num_list = []
print(id(num_list)) # 1200291395392
def add_list(num):
    num_list.append(num)
    print(id(num_list)) # 1200291395392
add_list(1)
add_list(2)
add_list(3)
print(num_list) # [1, 2, 3]
print(id(num_list)) # 1200291395392
'''

(3)局部名称空间

# 在函数内部或者是类内部定义的变量
# 随着函数启动而创建,随着函数结束而消失
# 这个列表是全局的列表
# 列表是可变数据类型 ---> 列表被修改后id不变
def add_list(num):
    # 垃圾回收机制 ---> 节省内存开销
    num_list = []
    num_list.append(num)
    print(num_list)
    print(id(num_list)) # 1200291395392
add_list(1)
add_list(2)
add_list(3)

(4)名称空间的加载顺序

# 先加载内建名称空间
# 其次是全局名称空间
# 最后就是局部名称空间

(5)名称空间的查找顺序

# 如果你在全局查
# 先全局后内建 --> 在 py 文件中执行代码

# 如果在局部
# 先局部再全局再内建 ---> 在函数内部执行代码

# 所有的变量 尤其是 可变数据类型 字典  列表
# 尽量写在文件开头 , 如果放在函数下面可能会导致检索不到变量
num_list = []

def add_list(num):
    num_list.append(num)
    print(num_list)
add_list(num=1)

标签:调用,函数,age,list,num,参数,print,name
From: https://www.cnblogs.com/chosen-yn/p/18136739

相关文章

  • 9.函数参数 与 名称空间
    【一】函数作为参数1)分类1.形参函数定义时,括号内声明的值;用来接收外部传来的值2.实参函数调用时,括号内传入的得值;常是常量,变量,表达式或三者组合2)位置参数参数数量不对会报错必须按照顺序传入,否则顺序会乱3)关键字参数需指定定义时的名字,可不按位置传入4)默认参数......
  • const在类和函数之间的运用
    const在类和函数之间的运用第一种情况简单来说就是如果声明了一个const类但是调用了非const的方法.那么编译会不通过->const类只能调用const方法,非const类就都可以调用示例代码:宏定义:#pragma#ifndef__CONST_OBJECT__#define__CONST_OBJECT__​#include<iostream>#incl......
  • codegen的使用方法及常见参数配置
    前言在进行API开发时,我们通常需要定义API的接口规范和文档,以方便其他开发者调用和使用。Swagger是一款非常流行的API文档生成工具,它可以帮助我们快速生成API接口文档,并提供了许多便捷的功能。本文将介绍如何使用swagger-codegen来生成API接口文档。简介swagger-codegen是Swagge......
  • JS 中的函数式 - 常用概念
    一、柯里化-currying柯里化的意思是将一个多元函数,转换成一个依次调用的单元函数,用表达式表示: f(a,b,c)→f(a)(b)(c)  核心代码实现:exportfunctioncurry(fn){letlen=fn.length;//收集目标函数的参数个数(总)returnfunctioncurriedFn(...params){......
  • 在 C 中定义函数 - 如何定义 C 中的函数
    在C编程中,函数扮演着基本的角色。它们使您能够编写组织良好且易于维护的代码。在本文中,您将学习在C中定义函数的基础知识。(本文视频讲解:java567.com)C中的函数是什么?在编程中,函数是执行特定任务的代码块。函数接受输入,处理它们,执行操作,并产生输出。函数很重要,因为它们组......
  • Windows网络桥接:事件无法调用任何订户 (异常来自 HRESULT:0x80040201)异常处理
    开发Windows网络桥接使用接口Com组件:Interop.NETCONLib。设置成X64位时调用EnableSharing。出现一下异常System.Runtime.InteropServices.COMException(0x80040201):事件无法调用任何订户(异常来自HRESULT:0x80040201)在NETCONLib.INetSharingConfiguration.EnableSharin......
  • C++_内存模型和函数以及类
    C++内存模型函数函数与编译器类成员变量class内部通过 static修饰变量时,表示该变量为静态成员变量,必须在类外定义 staticconst修饰变量时,表示该变量为静态成员常量,可以在类内初始化,或者在类外初始化 staticconstexpr修饰变量时,表示该......
  • 函数对象,闭包函数及装饰器了解
    函数对象【1】定义函数对象指的是函数可以被当做数据来处理【2】可以直接被引用定义一个函数用一个新的变量名来存,用新的变量名来调用#定义一个函数defadd(x,y):returnx+y#将函数地址绑定给一个变量func=add#通过这个变量找到对应的地址,从而调用函数res......
  • hash()函数在python2和python3的区别
    在Python3中,对于字符串类型的对象,hash()函数会根据当前进程的种子值计算哈希值。这个种子值在每次Python进程启动时都会随机生成。因此,即使是相同的字符串,在不同的Python进程中调用hash()函数会得到不同的哈希值。这种设计的目的是为了增加哈希表的随机性,从而提高安全性......
  • 析构函数与 -O2 优化的一个问题
    在赋值时,我们需要先对原有对象调用析构函数。我的析构函数实现如下:~vector() { for(ptr*itr=begin_p;itr!=finish_p;itr++) { delete*itr; } delete[]begin_p; begin_p=nullptr;finish_p=nullptr;end_p=nullptr; }不使用-O2优化,程序运行正常,调用完析构函......