第五章:Python函数基础篇

第五章:Python函数基础篇,第1张

  • 部分参考:菜鸟教程
    文章目录
    • 一:Python中定义函数
    • 二:使用函数
    • 三:关于函数返回值
      • (1)让Python函数一次返回多个值
      • (2)序列解包与链式赋值
    • 四:关于函数中的参数
      • (1)再谈对象、变量、类型
      • (2)Python中参数种类
        • A:必需参数
        • B:关键字参数
        • C:默认参数
        • D:不定长参数
          • ①:一个`*`
          • ②:两个`**`
    • 五:关于Python中函数变量作用域

函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段,之前经常使用到的print()就是Python中的内置函数,当然你可以自己创建函数,也即自定义函数


一:Python中定义函数

Python中函数的基本格式如下,注意一些细节

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明
  • 函数内容以冒号 : 起始,并且缩进
  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None

二:使用函数

如下是一个完整定义并调用函数的例子

def max_num(a, b):
    if a > b:
        return a
    else:
        return b

x = input()
y = input()

print(max_num(x, y))

下面的这个例子稍微复杂点,具体流程如下

  • 首先add(x, y)函数先被调用,将会结果3返回给a
  • 接着调用print_code(code)函数打印出了Python
  • 然后调用内置内置函数print()打印ab,由于print_code()函数是没有返回值的,因此会显示None
def add(x, y):
    result = x + y
    return result

def print_code(code):
    print(code)

a = add(1, 2)
b = print_code('Python')

print(a, b)

三:关于函数返回值 (1)让Python函数一次返回多个值

和其他语言一样,函数中一旦遇到return,该函数将会结束。一般情况下,利用return只能返回一个值,不能返回多个值,因此在其他语言中如果要返回多个值时,常常会使用在参数列表中利用引用或其他方式间接获取,而在Python中没有这样麻烦


在Python中,return语句是可以返回多个值的,使用逗号分隔即可,最终会以元组的形式返回

def test():
    a = 1
    b = 2
    c = 3
    return a, b, c
ret = test()
print(ret)
print(type(ret))

使用时当然可以采用索引的方式,例如ret[0],但是十分不建议这样 *** 作,可以采用序列解包的方式实现,例如

x, y, z =test()
(2)序列解包与链式赋值

Python中函数可以返货多个值,所以现在最大的问题就是如何使用。在Python中各个数据类型赋值是非常自由的,且阅读性也很好,这些 *** 作称之为序列解包与链式赋值

a, b, c = 1, 2, 3  # 给a,b,c分别赋值1,2,3

d = 1, 2, 3  # 现在d变成了一个元组
print(type(d))

x, y, z = d  # 解包

print(a, b, c)
print(d)
print(x, y, z)


四:关于函数中的参数
  • 参数是函数中非常重要的一部分内容,所以这里有必要详细探讨
(1)再谈对象、变量、类型

Python中函数的参数比较特殊,这源于在Python中变量是没有类型的,类型属于对象,对象有不同的类型之分

  • 下面的例子中,[1, 2, 3]list类型,“Hello”string类型,但变量a是没有类型的,它仅仅是一个对象的引用,可以指向list类型对象,也可以指向string类型对象

在Python中,stringtuplenumber是不可变的;而listdict则是可变的

  • 不可变:例如先执行a=1,再执行a=10,实际上是首先新生成了一个int值对象10,接着让a指向它,而int值为5的那个对象丢弃
  • 可变:例如执行list=[1, 2, 3, 4]然后再赋值list[2] = 5,这个 *** 作中list本身没有动,只是其内部的一部分值被修改了

对象的可变和不可变将会导致传参时产生巨大的差异,直白点讲就是值传递和引用传递的区别

  • 不可变:类似于C++中的值传递;例如fun(a),它传递的只是a的值,并不会影响函数外部的原来的a,而是在函数内部新生成了一个对象
  • 可变:类似于C++中的引用传递;例如fun(a),就会把外部的a传递过去,函数内部对a的修改会影响到本体

口说无凭,我们可以用id()函数,通过查看对象的地址来验证

def change(b):
    print(id(b))  # 此时指向同一个对象
    b = 10  #被修改,于是新生成了一个对象
    print(id(b))
a = 1
print(id(a))
change(a)

def change(a):
    a.append([1, 2, 3, 4])
    print(id(a))
    print("函数内:", a)
list1 = [10, 20 ,30]
change(list1)
print(id(list1))
print("函数外:", list1)

(2)Python中参数种类

Python中主要会遇到以下几种类型的参数

  • 必需参数
  • 关键字参数
  • 默认参数
  • 关键字参数
A:必需参数

必需参数必须以正确的顺序传入函数,且调用时的数量必须和声明时的一样。例如,下面的例子中由于缺少了一个参数所以会无法正确调用

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

test = add(1)

B:关键字参数

关键字参数允许函数调用时参数的顺序与声明时不一致,或者换句话说,关键字参数在调用时可以指定某个形参获取到某个值,如下

def add(x, y):
    return x, y
x, y = 1, 2
x, y = add(x=2, y=1)
print(x, y)

C:默认参数

默认参数会为形参设定一个默认值,用户在调用函数时就不需要传入相应位置处的实参了

如下是一个经典的例子,从这个例子中我们可以看到默认参数的一些特点

  • 如果对应位置不传递参数那么将会使用默认值
  • 如果对应位置传入了参数且有默认值,那么会优先使用用户传入的参数
  • 形参在设置时必须按照“非默认、非默认…非默认、默认、默认、默认…默认”这样的格式,否则Python将无法分清必需参数和默认参数
  • 注意默认参数经常和关键字参数配合使用
def display_student_info(name, gender='男', age=10, school='人名路小学'):
    print("Name:"+name)
    print("Gender:"+gender+'生')
    print("Age:"+str(age)+'岁')
    print("School:"+school)
    print("---------------------------------------")
display_student_info("老王")
display_student_info("老王", '女')
display_student_info("老王", '男', 10, "旺财小学")
display_student_info("老王", '男', 19)



##############################结果#######################################
Name:老王
Gender:男生
Age:10岁
School:人名路小学
---------------------------------------
Name:老王
Gender:女生
Age:10岁
School:人名路小学
---------------------------------------
Name:老王
Gender:男生
Age:10岁
School:旺财小学
---------------------------------------
Name:老王
Gender:男生
Age:19岁
School:人名路小学
---------------------------------------
D:不定长参数

如果想要一个函数能不固定接收任意多个参数,可以使用不定长参数

①:一个*

不定长参数第一种形式是加一个信号*,在这种方式下,参数会议tuple的形式导入,如下

def test(*a):
    print(a)
    print(type(a))

test(1, 2, 3, 4)

其实,它等价于

def test(a):
    print(a)

test((1, 2, 3, 4))

这里要特别注意,一旦定义了不定长参数,那么在传参时不要传入元组,因为这样的话他会变成一个二维的元组

def test(*a):
    print(a)
    print(type(a))
a = (1, 2, 3, 4)
test(a)

如果非要这么做,那么在调用时可以使用*对实参进行解包

def test(*a):
    print(a)
    print(type(a))
a = (1, 2, 3, 4)
test(*a)

②:两个**

另外一种就是加了两个 ** ,加了两个星号 ** 的参数会以字典的形式导入

def test(**a):
    print(a)
    print(type(a))
test(x = '2', y = 3)

特别注意,遍历字典时要使用它的items()方法,否则会出现一些问题

def test(**a):
    for key, value in a.items():
        print(key, ':', value)

test(Ruby=277, MySQL=288, Java=299)

和上面一样,如果传入的是字典也需要使用**解包

def test(**a):
    for key, value in a.items():
        print(key, ':', value)

language = {'C++':277, 'C#':288, 'Java':299, 'Python':311}

test(**language)


最后需要注意,不定长参数不是必需参数,它是可以不传入的

五:关于Python中函数变量作用域
  • 这里关于变量作用域就不从零基础开始说了,主要说一些Python中的特殊的地方

有别于其他语言,在Python中没有块级作用域,只有函数作用域。对于下面的例子,for循环中的变量a的作用域在整个函数内(这样的代码逻辑放到其他语言中是行不通的)

def test():
    c = 50
    for i in range(0, 9):
        a = 'a'
        c += 1
    print(c)
    print(a)  # 可以正确打印(最好在最前面“声明一下”,例如a = ' ')

test()


下面的代码中变量a肯定不会被打印出来,这是因为a是一个局部变量

def test():
    a = 1
test()
print(a)

Python中提供了一个关键字global可以使局部变量变为全局变量,使用方法如下

def test():
    global a
    a = 1
test()
print(a)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/792431.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存