函数

浏览 2213

课文

函数调用

在程序里面,我们定义一个函数通常是为了将这部分代码重复使用。你可以为一个函数指定名字,定义可执行的语句。让它加班加点的为我们做重复劳动,压榨机器人的价值。

之前我们使用过的 typeprint 就是函数。

type(10)

这里 type 就是函数名,括号中的 10 是一个参数。参数是我们传给函数的值或变量。type 函数这里的作用是返回参数的类型,此时类型就是 type 的返回值。

内建函数

python 提供了一些内建函数使我们无需定义就能直接使用。

例如下面的 maxmin 函数的作用是返回所给参数中的最大值和最小值。

print('最大值:', max(1, 8, 3, 5))
print('最小值:', min(1, 8, 3, 5))
最大值: 8
最小值: 1

len 函数则能告诉我们一个字符串中有多少个字符。

print(len('小明是个傻X'))
6

len 函数还可计算一些类型的成员数,这将在之后提到。

类型转换函数

python 中提供了一些函数给我们转换类型,它们同样属于内建函数。例如 intstrfloat

例如 n 虽然书面意思是数字,但被包含在单引号中属于 str 类型。我们只需用 int 函数就能转换其为 int 类型。

n = '123'
print(type(n))
n = int(n)
print(type(n))
<class 'str'>
<class 'int'>

同样我们可以用 float 对带小数的 str 类型进行同样操作。

n = '34.12'
print(type(n))
n = float(n)
print(type(n))
<class 'str'>
<class 'float'>

当然我们也可以用 str 进行类型转换。

n = 34.12
print(type(n))
n = str(n)
print(type(n))
<class 'float'>
<class 'str'>

数学函数

Python 提供了 math 模块供我们进行一些数学上的操作。

在引入其他模块时我们使用的是 import 关键字。我们在引入之后直接 print 可以看到一些基本信息,并且能通过 print(math.**doc**) 查看其自身的描述。

import math

print(math)
print(math.__doc__)
<module 'math' (built-in)>
This module provides access to the mathematical functions
defined by the C standard.

引入 math 模块后我们往往一脸茫然无可下手,不知其能干嘛不知如何去使用。

用内建的 dir 函数能帮我们看到模块内部都有什么方法。

print(dir(math))
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

看到这些方法是不是有一股熟悉的感觉,我们还可以调用方法的 doc 方法知道他的基本描述。

print(math.log.__doc__)
print(math.pow.__doc__)
log(x, [base=math.e])
Return the logarithm of x to the given base.

If the base not specified, returns the natural logarithm (base e) of x.
Return x**y (x to the power of y).

学好英语很重要,能帮我们省去绕很多弯路的力气,直达问题的最终答案。不然要靠百度去吸收二手答案,可想会耗费多大力气。

接着我们完成一个运用勾股定理对直角三角形求斜边的程序。

import math

a = float(input('请输入一个直角边长度:'))
b = float(input('请输入另一个直角边长度:'))
print('斜边的长度是:', math.sqrt(math.pow(a, 2) + math.pow(b, 2)))

随机数

随机是我们日常生活中不或缺的一部分,比如我们抽奖是一个随机事件,天气是一个随机事件,晚上回家吃什么大概率也是个随机事件。

python 里面的 random 模块就提供了生成随机数的方法。random 模块中的 random 方法的作用是返回一个 0 到 1 的浮点数(包括 0 不包括 1)。

我们下面打印了三个随机数,每次都不一样。

import random

print(random.random())
print(random.random())
print(random.random())
0.7174432452813149
0.8797376860445014
0.22724064581942438

我们还能用 randint 方法,返回一个随机的整数。randint 方法接收两个参数 ab,返回 ab 之间的数(包括 ab)。

import random

print(random.randint(1, 5))
print(random.randint(1, 5))
print(random.randint(1, 5))
2
5
4

此时我们就能用 randint 方法决定我们晚饭吃啥了(下面的写法比较累赘,我们之后学到列表时会有更好的写法)。

import random

choice = random.randint(1, 5)

if choice == 1:
    print('吃鱼')
elif choice == 2:
    print('吃虾')
elif choice == 3:
    print('吃面')
elif choice == 4:
    print('吃肉')
elif choice == 5:
    print('吃土')
吃土

我今晚吃土,你们呢?

定义函数

到目前为止我们都还是用的 python 的内建函数,我们同样也可以自己定义一些函数。函数的目的是为了封装一些重复性的代码,避免重复造轮子,同时方便将功能直接给其他开发者调用。

下面我们定义一个函数,接着调用它。

def say_hello():
    print('叔叔阿姨早上好')
    print('哥哥姐姐晚上好')

say_hello()
叔叔阿姨早上好
哥哥姐姐晚上好

def 在这里表明我们定义了一个函数,后面紧接着的就是其函数名say_hello。函数名的选择类似于变量名,应避开 python 的关键字,不能以数字开头,尽量使名字有意义等。

函数名后面的空括号()表示这个函数不需要传递任何参数。

def say_hello(): 为其函数头的定义。从:往后的内容是函数的执行代码块。一般另起一行,以缩进(Tab)作为区分。

需要注意的是,python 是从上到下顺序执行的,因此 say_hello 的定义必需在其调用之前。

以下是错误示范,say_hello 的调用在其定义之前。

say_hello()

def say_hello():
    print('叔叔阿姨早上好')
    print('哥哥姐姐晚上好')
Traceback (most recent call last):
  File ".\first.py", line 1, in <module>
    say_hello()
NameError: name 'say_hello' is not defined

python 中执行顺序

为了保证你在调用函数之前就已经定义了函数,你需要了解 python 中的执行顺序。

python 中的执行永远从文件的第一行语句开始,从上到下顺序执行。

当执行到函数的定义部分时,会略过函数内部的代码块继续往下执行。

当执行到函数的调用部分时,会跳到函数内部执行代码,直到函数中的语句执行完成,并返回到调用的位置继续执行。

函数中也可以调用其他的函数。

我们通过编写下面的程序验证一下。

print(1)

def a():
    print(4)

print(2)

def b():
    print(3)
    a()

b()

print(5)
1
2
3
4
5

在函数定义时,上下空行不是必须的,但加上空行的话会让代码看起来更清晰。同样在写一段长代码时,不同意义的部分,比如 import 语句,变量的定义,执行语句,与不同含义的逻辑代码块间,同样可以插入空行,保证代码的可读性。

参数

在之前使用一些内建函数的时候,我们就已经接触过参数。例如对于 print 函数,他的参数是我们要打印的东西。对于 math.pow,他的参数有两个,底数与幂数。

我们同样可以在自定义函数中添加参数。

在下面的例子中,我们在定义函数的同时指定了一个形参 name,并且在调用时各自用 '叔叔阿姨''哥哥姐姐' 作为实参进行了传值。

在函数内部便可对传进来的值进行操作。

def say_hello(name):
    print(name + '早上好')

say_hello('叔叔阿姨')
say_hello('哥哥姐姐')
叔叔阿姨早上好
哥哥姐姐早上好

我们还可以定义多个参数,这样在使用时便可依次按照顺序传递值。

例如:

def eating(name, something):
    print(name + '正在吃' + something)

eating('小明', '土')
小明正在吃土

唉,吃土的生活,男默女泪。

返回值

在之前使用 random.randint 函数时,使用了一个变量接收其返回的值。我们同样可以在我们的函数中返回值。

下面的例子中,我们定义一下函数对输入的两个参数进行求和运算,并且返回所得结果。

def addtwo(a, b):
    added = a + b
    return added

x = addtwo(3, 5)
print(x)
8

如果一个函数并没有使用 return 返回一个值,那它的返回值将是 None

def addtwo(a, b):
    added = a + b

x = addtwo(3, 5)
print(x)
None

函数在执行到 return 时意味着结束,在 return 之后的代码将不会再被执行。从下面的例子可以看出,print('小明爱吃瓜') 并没有被执行。

def addtwo(a, b):
    added = a + b
    return added
    print('小明爱吃瓜')  # 这里并没有被执行到

x = addtwo(3, 5)
print(x)
8

函数的作用

  • 清晰的代码结构
  • 更少的代码空间
  • 方便部分 debug 与 修改
  • 重用与封装代码

实战

1.写一个函数,传入一个字符串,计算其中有多少个空格。

解析

1.写一个函数,传入一个字符串,计算其中有多少个空格。

def space_count(sentence):
    count = 0
    for word in sentence:
        if word == ' ':
            count += 1
    return count


print('空格数:', space_count('The longest day has an end.'))
空格数: 5

还有一种更 trick 的写法。

def space_count(sentence):
    return len([word for word in sentence if word==' ' ])


print('空格数:', space_count('The longest day has an end.'))
空格数: 5
点击查看

评论

登录参与讨论

小和

2022-09-03

回复

共 1 条
  • 1
前往
  • 1