函数 概念 定义 创建 参数

例题引导:

【模拟轮盘抽奖游戏】

轮盘分为三部分: 一等奖, 二等奖和三等奖;轮盘转的时候是随机的,奖项设置如下:
如果范围在[0,0.08)之间,代表一等奖,
如果范围在[0.08,0.3)之间,代表2等奖,
如果范围在[0, 1.0)之间,代表3等奖,

要求:假设本次活动1000人参加, 模拟游戏时各等级奖品个数需要准备多少个。

解题思路:定义游戏规则(用字典表达)-构建函数-生成随机数-编写游戏逻辑-调用函数-遍历1000名用户-打印输出

参考答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import random  #导入随机数模块

rewardDict = {
'一等奖': (0, 0.08),
'二等奖': (0.08, 0.3),
'三等奖': (0.3, 1)
} #因为该值为一对一映射,所以想到用字典定义得奖范围

def rewardFun(): #开始构建函数
"""用户得奖等级"""
# 生成一个0~1之间的随机数
num = random.random()
# 判断随机转盘转的数是几等奖
for k, v in rewardDict.items():
# 这里的v是元组
if v[0] <= num < v[1]:
return k

# print rewardFun()
resultDict = {}

for i in range(1000):
# res:本次转盘的等级(一/二/三等奖)
res = rewardFun() #调用函数
if res not in resultDict:
resultDict[res] = 1
else:
resultDict[res] = resultDict[res] + 1

for k, v in resultDict.items():
print k, '---------->', v

学习引导:

  • 函数概念
  • 函数定义
  • 函数调用
  • 参数调用
  • 参数传递

函数

函数的概念

函数是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集。它是编辑好的、可直接调用的、可重复使用的,用来实现单一或相关联功能的代码段

优点:

  • 提高程序的模块性;
  • 使程序变得可扩展;
  • 减少重复代码;
  • 使程序变得可维护;

函数的定义

函数必须先创建才可以使用,该过程称为函数定义,使用函数的过程称为函数调用。

函数可以根据自己的需求来定义,但有一些规则需要注意:

  • 函数代码块必须以def开头,后接函数标识符名称和圆括号();

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

  • 函数的第一行语句可以选择性的使用文档字符-用于存放函数说明;

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

  • 函数名称的命名应符合标识符的命名规则;(可由字母、下划线和数字组成;不能以数字开头;不能与关键字重名)

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

函数定义的一般格式:

1
2
3
#函数定义的一般格式:
def 函数名 (参数列表):
函数体
1
2
3
4
5
#实例1
def hello():
print('Hello World')

hello()
1
#Hello World

实例2-计算圆的面积,带参数

1
2
3
4
5
6
7
#实例2-计算圆的面积,带参数
def area(r):
pi=3.412
return pi*(r^2)

r=5
print('圆的面积为:',area(r))
1
#圆的面积为: 23.884

函数调用

即使用函数的过程

简单的调用应用

1
2
3
4
5
6
7
8
9
#函数功能:打印该字符串
def println(str):
print(str)
return

#调用函数
println('调用上述函数')
println('打印这段字符串')
println('多次调用函数')
1
2
3
#调用上述函数
#打印这段字符串
#多次调用函数

参数调用

参数分为形参、实参

  • 形参:函数定义时括号内的参数

  • 实参:函数调用时括号内的参数

  • 形参相当于变量,实参相当于变量的值

在实际代码中表示如下:

1
2
3
4
5
6
7
8
9
#定义时:
def func(a,b,c):
pass

其中 a,b,c 为形参

#调用时:
func(1,2,3)
其中123为实参

形参:

只在被调用时,才分配存储单元。调用结束,立刻释放所分配的内存。

形参只在函数内部有效

实参:

可以是:常量、变量、表达式、函数

进行函数调用时,实参必须是确定的值

位置参数:

  • 位置形参:函数定义时,从左往右写的参数,比如上面的 a, b , c

  • 位置实参:函数调用时,从左往右写的参数, 比如上面的 1,2,3

  • 位置形参定义多少个,调用时位置实参必须写上多少个,多一个少一个都不行。

  • 位置参数必须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

1
2
3
4
5
def func(a,b,c):
return a+b+c

#调用
print(func(2,3,4))
1
#9

错误演示:

1
2
3
4
5
def func(a,b,c):
return a+b+c

#调用
print(func(2,3)) #实参数量不对应,报错
1
2
3
4
5
6
7
8
9
---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-21-38b482e25fef> in <module>
3
4 #调用
----> 5 print(func(2,3))
TypeError: func() missing 1 required positional argument: 'c'

关键参数:

  • 正常情况下,给函数传参数,要按顺序。如果不想按顺序,就用关键参数。

  • 指定参数名的参数,就叫做关键参数。

  • 函数调用时:func(a=1, b=2), 这种指定了参数名的参数,就是关键参数。

  • 调用函数时,关键参数可以和位置参数一起用,但是关键参数必须在位置参数的后面。不然会报错。

1
2
3
4
5
def func(a,b,c):
return a+b+c

#调用
print(func(4,c=3,b=2))
1
#9

默认参数:

  • 函数定义时,默认参数必须在位置形参的后面。

  • 函数调用时,指定参数名的参数,叫关键参数。

  • 而在函数定义时,给参数名指定值的时候,这个参数叫做默认参数。

  • 关键参数,和默认参数两个参数写法一样,区别在于:

    关键参数是在函数调用时,指定实参的参数名,也可以说指定值的参数名。

    默认参数是在函数定义时,指定参数名的值。

  • 写法:

    1
    2
    def (a, b=100):
    pass
  • 定义时,有默认参数的话,调用时,这个实参可以不写。如果实参不写的话,这个形参的参数值是他的默认值。

实例演示:

1
2
3
4
5
6
7
8
9
def info(name,age=18):
print('名字:',name)
print('年龄:',age)
return

#调用
info(age=22,name='Jack')
print('****************')
info(name='Jack')
1
2
3
4
5
6
7
'''
名字: Jack
年龄: 22
*****************
名字: Jack
年龄: 18
'''

动态参数: * args ** kwargs

当你需要一个函数能处理很多参数,超过已声明的参数数量,这时就需要动态参数。与上述两中参数不同的是,该参数声明不需要命名。

* args

一个’* ‘的参数会以元组(tuple)的形式导入,存放未命名的变量参数

1
2
3
4
5
6
7
8
#函数定义
def printinfo(arg1,*vartuple):
print('输出:')
print(arg1)
print(vartuple)

#调用
printinfo(34,45,32,12)
#输出:
#34
#(45, 32, 12)

如果函数调用时没有指定参数,动态参数则表现为空元组。

1
2
3
4
5
6
7
8
#函数定义
def printinfo(arg1,*vartuple):
print('输出:')
print(arg1)
print(vartuple)

#调用
printinfo(34)
#输出:
#34
#()
** kwargs

还有一种动态参数,加了两个星号则以字典的形式导入

1
2
3
4
5
6
7
8
#函数定义
def printinfo(arg1,**vardict):
print('输出:')
print(arg1)
print(vardict)

#调用
printinfo(34,a=45,b=32,c=12)
#输出:
#34
#{'a': 45, 'b': 32, 'c': 12}

声明函数时,参数中的* 可以单独出现。

如果* 单独出现,后面的参数必须以关键字传入

1
2
3
4
def func(a,b,*,c):
return a+b-c

func(3,2,4) #非关键字传入报错
1
2
3
4
5
6
7
8
9
---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-34-f69556d382a4> in <module>
2 return a+b-c
3
----> 4 func(3,2,4)
TypeError: func() takes 2 positional arguments but 3 were given

关键字传入正确

1
func(3,4,c=5)  
1
#2

参数传递

python语言中,类型属于对象,变量是没有类型的,例如:

a=[1,2,3]

a=’DataScience’

其中[1,2,3]是list类型,’DataScience’是string类型,变量a没有类型,它只是一个对象的引用(一个指针),可以指向list类型对象也可以指向string类型对象

可更改(mutable)与不可更改(immutable)对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。

  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

  • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

  • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

1
2
3
4
5
6
7
8
9
10
#传不可变对象实例
#
#函数定义
def changeInt(a):
a=10

#函数调用
b=5
changeInt(b)
print(b)
1
#5

实例中有 int 对象 2,指向它的变量是 b,在传递给 ChangeInt 函数时,按传值的方式复制了变量 b,a 和 b 都指向了同一个 Int 对象,在 a=10 时,则新生成一个 int 值对象 10,并让 a 指向它。

1
2
3
4
5
6
7
8
9
10
11
#传可变对象实例
def changelist(List):
#对传入的列表进行扩展
List.append([1,2,3,4])
print('函数内取值:',List)
return

#函数调用
List=['datascience']
changelist(List)
print('函数外取值:',List)
1
2
#函数内取值: ['datascience', [1, 2, 3, 4]]
#函数外取值: ['datascience', [1, 2, 3, 4]]

可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。

传入函数的和在末尾添加新内容的对象用的是同一个引用。

小作业

  1. 1.构造一个describe_pet函数,调用该函数输入以下2只宠物的信息:

    I have a cat. My cat’s name is Monkey.

    I have a lizard. My lizard’s name is Cola.

  2. 编写函数, 接收一个列表(包含10个整形)和一个整形k, 返回一个新列表,要求:

    \- 将列表下标k之前对应(不包含k)的元素逆序;
    \- 将下标k及之后的元素逆序;
  3. 请用函数实现一个判断用户输入的年份是否是闰年的程序

  4. 构造一个greeting函数,调用函数并使用循环,对输入的参数返回整理后的greeting信息。

    例如,在控制台分别输入名字“Mary”和姓“Chen”,调用函数后输出”Hello, Mary Chen!”,并提示输入下一组姓和名。直到控制台输入姓或名为“end”时,程序结束。

评论