python函数一般不能_Python基础-函数

函数基本使用

python中定义函数所用的关键字是def, def 函数名() : 冒号代替其他编程语言的大括号,然后换行缩进写的代码就是函数体。

defwelcome():'''一个简单的函数

:return:'''

print("Hello World !")

welcome()

打印结果:

Hello World !

三引号中间的内容属于函数的注释文档,在实际项目中都尽量要把每个函数的文档注释写好,在这里为了节约篇幅,本文下面的代码示例就不再添加这个注释了。

函数还可以嵌套,也就是函数里面有函数:

defwelcome(name):defgo(name):print('我最棒:' +name)

go(name)

welcome('小明')

打印结果:

我最棒:小明

函数的参数

形参和实参

defwelcome(username):print("Hello World ! My name is" +str(username))

welcome("小明")

welcome("小花")

打印结果:

Hello World ! My name is 小明

Hello World ! My name is 小花

这是一个带参数的函数,在函数welcome中,username就是一个形参,也就是形式参数,是用来接收调用函数时传入的参数,你传的是啥它就是啥,传人它就是人,传鬼它就是鬼的那种。

实参就是实际参数,在调用函数的时候,传递是小明,那么小明就是实参,传递的是小花,那么小花也是实参,实参传递给函数后,会赋值给函数中的形参,然后我们就可以在函数中使用到外部传入的数据了。

参数默认值

写Java的时候最痛恨的就是方法不能设置默认值,使得必须得重载才行。

python允许我们给函数的形参设置一个默认值,不传参数调用的话,就统一默认是这个值。

def welcome(username = '奥特曼'):print("Hello World ! My name is" +str(username))

welcome("小明")

welcome()

打印结果:

Hello World ! My name is 小明

Hello World ! My name is 奥特曼

修改参数后影响外部

在函数中修改参数内容会不会影响到外部,这个问题取决于实参的类型是不是可变的,可不可变就是可不可以修改。

字符串就是一种不可变的类型。

比如:

name = "小明"name= "小花"

请问,我是把"小明"修改成了"小花"吗? 答案是 非也。

实际上我是把"小花"这个字符串赋值给了name,让name指向了这个新字符串,替换掉了原来的"小明",原来的"小明"仍然是"小明",没有受到一点改变。

在python中,不可变类型有:整数、字符串、元组,可变类型有:列表、字典。如果传递的参数包含可变类型,并且在函数中对参数进行了修改,那么就会影响到外部的值。

defchange(lis):

lis[1] = '小明他大爷'names= ['小明','小花','小红']

change(names)print(names)

打印结果:

['小明', '小明他大爷', '小红']

如果我们不希望出现这种事情,那么就将对象复制一份再传递给函数。

defchange(lis):

lis[1] = '小明他大爷'names= ['小明','小花','小红']

change(names[:])print(names)

打印结果:

['小明', '小花', '小红']

我们用切片的方法拷贝了一份names,函数中尽管修改了参数,也不过是修改的是副本,不会影响到原始的names。

关键字参数

关键字参数让你可以不用考虑函数的参数位置,你需以键值对的形式指定参数的对应形参。

defwelcome(name,address):print(f"你好 {name} , 欢迎来到 {address} !")

welcome(address='上海',name='小强')

打印结果:

你好 小强 , 欢迎来到 上海 !

收集参数

有时候我们需要允许用户提供任意数量的参数,函数的形参可以带个星号来接收,不管调用函数的时候传递了多少实参,都将被收集到形参这个变量当中,形参的类型是元组。

def welcome(*names):print(names)

welcome('小明','小强','小红','小黑')

打印结果:

('小明', '小强', '小红', '小黑')

还有一种是带两个星号的形参,用于接收键值对形式的实参,导入到函数中的类型是字典。

def welcome(**names):print(names)

welcome(name='小明',age=18,sex='男')

打印结果:

{'name': '小明', 'age': 18, 'sex': '男'}

分配参数

分配参数是收集参数的相反操作,可使得一个元组或字典变量自动分配给函数中的形参。

defwelcome(name,address):print(f"你好 {name} , 欢迎来到 {address} !")

a= ('小红','山东')

welcome(*a)

打印结果:

你好 小红 , 欢迎来到 山东 !

我们改成字典的方式:

defwelcome(name,address):print(f"你好 {name} , 欢迎来到 {address} !")

a= {'address':'山东','name':'小红'}

welcome(**a)

打印结果:

你好 小红 , 欢迎来到 山东 !

函数的返回值

首先说明,所有的函数都是有返回值的,如果编程人员没有指定返回值,那么默认会返回None,对标其他语言中的null。

一个简单的函数返回值的例子:

defget_full_name(first_name,last_name):return first_name +last_name

r= get_full_name('王','大锤')print(r)

打印结果:

王大锤

然而python中的函数还可以返回多个值,返回出的值被装载到元组中:

deffunc(num):return num**2,num**3,num**4result= func(2)print(result)

打印结果:

(4, 8, 16)

在python中函数定义的时候没有返回值的签名,导致我们无法提前知道函数的返回值是什么类型,返回的什么完全看函数中的return的是什么,特别是逻辑代码比较多的函数,比如里面有多个if判断,有可能这个判断return出来的是布尔值,另一个判断return出来的是列表,还一个判断啥也不return,你调用的时候你都搞不清楚该怎么处理这个函数的返回值,在这一点来说,Java完胜。

所以在无规则限制的情况下,代码写的健不健壮,好不好用,主要取决于编程人员的素质。

匿名函数

匿名函数就是不用走正常函数定义的流程,可以直接定义一个简单的函数并把函数本身赋值给一个变量,使得这个变量可以像函数一样被调用,在python中可以用lambda关键字来申明定义一个匿名函数。

我们把王大锤的例子改一下:

get_full_name = lambda first_name,last_name : first_name +last_name

r= get_full_name('王','大锤')print(r)

打印结果:

王大锤

函数的作用域

访问全局作用域

python每调用一个函数,都会创建一个新命名空间,也就是局部命名空间,函数中的变量就叫做局部变量,与外部的全局命名空间不会相互干扰。

这是常规状态,当然也会有非常规需求的时候,所以python给我们提供了globals()函数,让我们可以在局部作用域中访问到全局的变量。

deffunc():

a=globals()print(a['name'])

name= '小明'func()

打印结果:

小明

globals()函数只能让我们访问到全局变量,但是是无法进行修改的,如果我们要修改全局变量,需要用到global关键字将全局变量引入进来。

deffunc():globalname

name= '小花'name= '小明'func()print(name)

打印结果:

小花

访问嵌套作用域

对于嵌套函数的情况,如果想要使用嵌套作用域(非全局作用域)的变量,就需要用到nonlocal关键字。

defwelcome(name):defgo():

nonlocal name

name= '我变成小花了'go()print(name)

my_name= '小明'welcome(my_name)print(my_name)

打印结果:

我变成小花了

小明

函数与模块

导入模块

模块的官方定义是包含函数和变量的python文件就叫做模块,然而你照着这个定义去看,你会发现只要是.py的文件,其实都符合模块的定义。

我新建一个user.py文件 他也叫做user模块 里面写两个函数

defget_name():print('我的名字是小明')defget_age():print('我今年11岁了')

然后我用import导入这个user模块 并调用模块中的函数

importuser

user.get_name()

打印结果:

我的名字是小明

这个用处相当于公共函数的封装,当然了,我们面向对象的做法一般都是封装到类里面。

为了防止模块名字被当前程序的变量覆盖,你可以选择导入的时候用as指定别名:

importuser as model_user

model_user.get_name()

打印结果:

我的名字是小明

导入函数

还是拿上面user模块来做例子  我现在只导入其中某个函数

from user importget_name

get_name()

打印结果:

我的名字是小明

from ... import ... 的意思就是 从...中获取...,从user模块中获取get_name函数。

导入模块中所有函数

通配符星号表示导入所有函数,只是这种做法,有大几率出现函数被覆盖的风险

from user import *get_name()

get_age()

打印结果:

我的名字是小明

我今年11岁了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值