python一个函数可以有参数也可以没有参数_【python】-- 函数、无参/有参参数、全局变量/局部变量...

函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

一、定义函数

1、定义一个由自己想要功能的函数,以下是简单的规则:

函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。

任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

函数内容以冒号起始,并且缩进。

return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

deftest():"""for test"""

print("in the test funcation")return0#def 定义函数的关键字#test 函数名(函数标识名称符)#() 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数#"""for test""" 函数说明,说明函数作用,方便他人阅读代码#print("in the test funcation") 函数体(代码块),注意缩进#return 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None

2、函数特征:

代码重复利用

可扩展性

保持一致性

优化前:

ContractedBlock.gif

ExpandedBlockStart.gif

#打印字符串

print("ABCD")print("EFGH")#现在下面有2个函数,每个函数处理完了,都需要使用上面的逻辑,那么唯一的方法就是拷贝2次这样的逻辑

deftest_1():"test"

print("in the test1")print("ABCD")print("EFGH")deftest_2():"test"

print("in the test2")print("ABCD")print("EFGH")

View Code

优化后:

ContractedBlock.gif

ExpandedBlockStart.gif

#新定义一个函数

deftest():"""test"""

print("ABCD")print("EFGH")#在想执行打印字符串功能的函数中,调用test()函数就可以了

deftest_1():"""test"""

print("in the test1")

test()#调用test()函数

deftest_2():"""test"""

print("in the test2")

test()#调用test()函数

View Code

二、有参函数和无参函数:

1、无参函数实现和调用:

ContractedBlock.gif

ExpandedBlockStart.gif

#定位test() 无参函数

deftest():print("in the test")

test()#调用函数

#in the test

View Code

2、有参函数实现和调用:

下面说说带参数的函数:

形参:指的是形式参数,是虚拟的,不占用内存空间,形参单元只有被调用的时才分配内存单元

实参:指的是实际参数,是一个变量,占用内存空间,数据传递单向,实参传给形参,形参不能传给实参

def test(x,y): #x,y是形参

print(x)print(y)

test(1,2) #1和2是实参#输出

1

2

(1)、位置参数

从上面的例子可以看出,实际参数和形式参数是一一对应的,如果调换位置,x和y被调用的时,位置也会互换,代码如下:

deftest(x,y):print(x)print(y)print("--------互换前-----")

test(1,2)print("--------互换后-----")

test(2,1)#输出

--------互换前-----

1

2

--------互换后-----

2

1

因为定义x,y两个形参,所以传递实参的时候,也只能传递两个实参,多一个或少一个都是有问题的:

a:多传递一个参数

ContractedBlock.gif

ExpandedBlockStart.gif

deftest(x,y):print(x)print(y)print("--------多一个参数----")

test(1,2,3)#输出

--------多一个参数----Traceback (most recent call last):

File"D:/PycharmProjects/pyhomework/day3/函数_带参数.py", line 8, in test(1,2,3)

TypeError: test() takes2 positional arguments but 3 were given #test()函数需要传两个实参,你传了三个实参

View Code

b:少传递一个实参

ContractedBlock.gif

ExpandedBlockStart.gif

deftest(x,y):print(x)print(y)print("--------少一个参数----")

test(1)#输出

--------少一个参数----Traceback (most recent call last):

File"D:/PycharmProjects/pyhomework/day3/函数_带参数.py", line 8, in test(1)

TypeError: test() missing1 required positional argument: 'y' #没有给y参数传实参

View Code

(2)、关键字参数

上面的位置参数,看起来有点死,必须形参和实参的位置一一对应,不然就会传错参数,为了避免这种问题,就有了关键字参数的玩法:关键字传参不需要一一对应,只需要你指定你的哪个形参调用哪一个实参即可;

deftest(x,y):print(x)print(y)print("--------互换前------")

test(x=1,y=2)print("--------互换后------")

test(y=2,x=1)#输出

--------互换前------

1

2

--------互换后------

1

2

研究一下位置参数和关键字参数结合使用:

1,位置参数在前,关键字参数在后

deftest(x,y):print(x)print(y)

test(1,y=2)#输出

1

2

deftest(x,y,z):print(x)print(y)print(z)

test(1,z=2,y=3)#输出

1

3

2

2、上面的列子是关键字传参传给y,现在传给x,代码如下:

deftest(x,y):print(x)print(y)

test(1,x=2)#输出

Traceback (most recent call last):

File"D:/PycharmProjects/pyhomework/day3/函数_带参数.py", line 8, in test(1,x=2)

TypeError: test() got multiple valuesfor argument 'x' #给x形参传的值过多,之前位置参数 就传实参给x一次,后面关键字又传实参给x,造成报错

3 、关键字参数在前,位置参数在后:

deftest(x,y):print(x)print(y)

test(y=2,1)#输出

File "D:/PycharmProjects/pyhomework/day3/函数_带参数.py", line 8test(y=2,1)^SyntaxError: positional argument follows keyword argument#关键字参数在位置参数的前面

另外一种,就是关键字参数在中间:

deftest(x,y,z):print(x)print(y)

test(1,y=2,3)#输出

File "D:/PycharmProjects/pyhomework/day3/函数_带参数.py", line 8test(1,y=2,3)^SyntaxError: positional argument follows keyword argument

结论:关键字参数是不能写在位置参数前面的。

三、全局变量和局部变量

1、局部变量

局部变量:顾名思义,指在局部生效,定义在函数体内的变量只能在函数里面生效,出个这个函数体,就不能找到它,这个函数就是这个变量的作用域,如下代码:

name = "apple"

deftest(name):print("before change:",name)

name= "bananan" #局部变量name,只能在这个函数内生效,这个函数就是这个变量的作用域

print("after change:",name)

test(name)print(name)#输出

before change: apple

after change: bananan#局部变量生效

bananan#外部的变量还是apple,仅函数内的name变成了bananan

2、全局变量

全局变量:指的是在整个程序中都生效的变量,在整个代码的顶层声明:

name = "apple"

deftest(name):print("before change:",name)

name= "bananan" #局部变量name,只能在这个函数内生效,这个函数就是这个变量的作用域

print("after change:",name)deftest1(name):print(name)

test(name)

test(name1)print(name)#输出

before change: apple

after change: bananan#局部变量生效

apple#全局变量

apple#全局变量

注:全局变量的优先级是低于局部变量的,当函数体内没有局部变量,才会去找全局变量

3、局部变量改成全局变量

改前用global先声明一下全局变量

将全局变量重新赋值

name = "apple"

deftest(name):global name #使用global 声明全局变量

print("before change:",name)

name= "bananan" #全局变量重新赋值

print("after change:",name)deftest1(name):print(name)

test(name)

test(name1)print(name)#输出

before change: apple

after change: bananan

bananan

bannann

注:最好不要用global这个关键字,因为你用了,其他人调你的函数时,就乱套了,而且还不好调试。

4、全局变量定义成列表

names = ['AAAA',"BBBB"] #定义一个列表

deftest():

names[0]= "CCCC"

print(names)print("--------test-----")

test()print("------打印names--")print(names)#输出

--------test-----['CCCC', 'BBBB'] #函数内的names输出

------打印names--['CCCC', 'BBBB'] #函数外的names输出

注:1、只有字符串和整数是不可以被修改的,如果修改,需要在函数里面声明global。2、但是复杂的数据类型,像列表(list)、字典(dict)、集合(set)、类(class)都是可以修改的。

5、小实验:

局部作用域和全局作用域的访问顺序

#局部作用域和全局作用域的访问顺序

x=0defgrandpa():

x=1

defdad():

x=2

defson():

x=3

print(x)

son()

dad()#调用grandpa

grandpa()#输出

3

注:作用域,只能是从里往外找,一层一层的的找。

全局变量和局部变量小结:

在子程序(函数)中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量。

全局变量的作用域是整个程序,局部变量的作用域是定义该变量的子程序(函数)。

当全局变量和局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其他地方,全局变量起作用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值