Python中的函数学习

定义一个函数,使用关键字def

def 函数名(参数列表):
    # 语句1
    # 语句2...

python可以在函数体内部定义全局变量:

a = 100
def testA():
    print(a)
def testB():
    global a
    a = 3000
    print(a)
def testC():
    print(a)
testA()#100
testB()#3000
testC()#3000

python定义函数的说明文档,可以用help()函数查看

def add(a,b):
    """函数的说明:求两个数字之和"""
    print("开始进行求和运算")
    return a+b;
print(add(3,5))
help(add)

在这里插入图片描述

函数可以有多个返回值,它们默认以元组形式返回

def return_num(a,b,c):
    return c,b,a
result = return_num(1,2,3)
print(result) #(3, 2, 1)
print(type(result)) #<class 'tuple'>

python中函数的参数

位置参数

位置参数:调用函数时根据函数定义时的参数的位置来传递参数。

根据位置参数的要求,函数调用的时候,实参和形参的书写顺序必须一致:

def user_info(name,age,gender):
    print(f'您的名字是{name},年龄是{age},性别是{gender}')
user_info("Tom",18,"man")#您的名字是Tom,年龄是18,性别是man
#假如我们错乱传参的顺序:(很显然达不到理想效果)
user_info(18,"Bob","男")#您的名字是18,年龄是Bob,性别是男

关键字参数

在python当中,可以使用关键字参数,通过“键=值”的形式加以指定,让函数更加清晰,容易使用,使得传递参数的顺序可以发生更改

def user_info(name,age,gender):
    print(f'您的名字是{name},年龄是{age},性别是{gender}')
user_info(gender="女",age=19,name="Lisa")#您的名字是Lisa,年龄是19,性别是女
user_info("小明",gender="男",age=20)#您的名字是小明,年龄是20,性别是男

缺省参数

缺省参数也叫做默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值。
但是要注意:所有位置参数必须出现在默认参数前,包括函数定义时和调用时。

def add100(a,b=100):
    return a+b
print(add100(8))#108

不定长参数

  • 包裹位置传递
    不定长参数也叫做可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
def user_info(*args):
    print(type(args))
    print(args)
user_info("小明",18,'男','小红')
#<class 'tuple'>
#('小明', 18, '男', '小红')

传进去的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。

  • 包裹关键字传递
    在包裹位置传递的基础上,args参数前再加一个*号,即可成为包裹关键字传递,也就是可以给每个传递的参数赋予一个名称,args变为字典类型。
def user_info(**args):
    print(type(args))
    print(args)
user_info(name = "小明",age = 19,id = 100)
# <class 'dict'>
# {'name': '小明', 'age': 19, 'id': 100}

无论是包裹位置传递和包裹关键字传递,都是一个组包的过程。

拆包交换变量值

拆包

  • 拆包:元组
def return_num():
    return 100,200
num1,num2 = return_num()
print(num1)#100
print(num2)#100
  • 拆包:字典
dict1 = {'name':'Tom',"age":19}
a,b = dict1
print(a) #name
print(b) #age

print(dict1[a]) #Tom
print(dict1[b]) #19

交换变量值

问题:有变量 a = 10,b = 20,如何交换两个变量的值?

  • 方法一:借助第三方变量
a = 10
b = 20
#借助第三方变量c
c = a
a = b
b = c
print(a)    #20
print(b)    #10
  • 方法二:
a,b = 10,20
a,b = b,a
print(a)    #20
print(b)    #10

引用

什么是引用

在python中,值是依靠引用传递来的。
我们可以用方法 id() 来判断两个变量是否为同一个值的引用。
id()函数的值可以理解为变量的内存地址。

  1. python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值’来传递对象。

  2. 当人们复制列表或字典时,就复制了对象列表的引用同,如果改变引用的值,则修改了原始的参数。

  3. 为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象。

# 1.int 类型测试
a = 1
b = a
print(b)    #1
print(id(a))#140710511502160
print(id(b))#140710511502160
a = 2

print(id(a))#140710511502192    (a变量的值发生改变,引用即发生改变)
print(id(b))#140710511502160    (b变量的值没有改变,引用就不发生改变)
print(b)    #1                  (b变量的值不因a的值更改而改变)
# 2.列表  类型测试
list1 = [10,20,30]
list2 = list1
print(id(list1))    #2088060740168
print(id(list2))    #2088060740168
list1.append(40)
print(id(list1))    #2088060740168
print(id(list2))    #2088060740168
print(list2)        #[10, 20, 30, 40]
#列表的引用始终没有改变,list2的值会随着list1的改变而改变

python中的每个数据值,都有它的唯一的引用值:

print(id(1))#140710511502160
print(id("s"))#1784527603280
print(id(7.8))#1784498663784

不同电脑对于同一值得引用基本都不一样,同一台电脑下次开机或重启集成开发环境后或者重新运行程序后打印同一值得引用也不尽相同。
但是int型的引用值在重新运行程序后却不变化。

引用当作实参

def test1(a):
    print(a)
    print(id(a))
    a+=a
    print(a)
    print(id(a))
# int:计算前后id值发生变化
b = 100
test1(b)
"""
100
140710486142896
200
140710486146096
"""
#列表:计算前后id值不变
c = [11,22]
test1(c)
"""
[11, 22]
2157135028872
[11, 22, 11, 22]
2157135028872
"""

可变类型和不可变类型总结

所谓的可变类型,就是指数据可以i直接进行修改。
不可变类型,指数据不可修改。

比如强行修改int型变量a的值,它的引用会发生变化。即它是不可变类型。

  • 可变类型
    • 列表
    • 字典
    • 集合
  • 不可变类型
    • 整型
    • 浮点型
    • 字符串
    • 元组

最后强调:python中数据的传递都是通过引用。

发布了76 篇原创文章 · 获赞 57 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43598138/article/details/105689410