1.什么是函数
我们在写程序的时候会多次使用重复的代码,函数就可以简化这种重复。我们在函数里写重复的内容, 然后等需要使用的时候直接调用就可以
-
Python
函数定义的通常格式为:
def 函数名(参数列表):
#函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明
函数体
#return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None
2. 定义函数
先进入到python
的命令行模式
➜ ~ source yiluo/bin/activate
(yiluo) ➜ ~ python3
Python 3.7.5 (default, Nov 29 2019, 14:32:46)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
- 创建一个输出任意范围内
Fibonacci
数列的函数:
>>> def fib(n):
... a, b = 0, 1
... while a<n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
【1】.def
关键字定义函数
【2】.函数体的第一个语句可以(可选的)是字符串
文字
【3】.函数的 执行 会引入一个用于函数局部变量
的新符号表
【4】.在函数被调用时,实际参数(实参
)会被引入被调用函数的本地符号表中
【5】.函数名称的值具有解释器
将其识别为用户定义函数的类型。这个值可以分配给另一个名称
>>> fib
<function fib at 0x10726a290>
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
- 写一个返回
斐波那契数列
的列表(而不是把它打印出来)的函数
>>> def fib2(n):
... result = []
... a, b = 0, 1
... while a<n:
... result.append(a)
... a, b =b ,a+b
... return result
...
>>> f100 = fib2(100)
>>> f100
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>>
3.内置函数
内置函数就是 Python
解释器中不用引入任何包,一直可以使用的函数义和调用
- 常用的
len
type
abs
来看一下
>>> a = 'hello'
>>> len(a)
5
>>> type(a)
<class 'str'>
>>> b = -1
>>> abs(b)
1
len
获取来字符串的个数
type
获取了类型是字符串
abs
是绝对值函数 -1
的绝对值是1
4.变量作用域
局部变量
和全局变量
- 创建一个文件,然后
vim
进行编辑
(yiluo) ➜ Code touch a.py
(yiluo) ➜ Code vim a.py
#!/usr/bin/env python3
def demo():
n = 100
print(n)
n = 1
print("Before demo ", n)
print("Inside demo", end=' ')
demo()
print("After demo", n)
- 保存文件然后命令行执行看一下结果
(yiluo) ➜ Code python a.py
Before demo 1
Inside demo 100
After demo 1
以上 n=1
是全局变量, n=100
是局部变量
- 例子2
#!/usr/bin/env python3
def test_local():
name = "Yiluo"
print(name)
name = 'Tom'
print('Before', name)
print('inside',end = ' ')
test_local()
print('After', name)
- 执行结果
➜ code python3 local.py
Before Tom
inside Yiluo
After Tom
5. global
关键字
#!/usr/bin/env python3
def demo2():
global n
n = 100
print(n)
n = 1
print("Before demo2", n)
print("Inside demo2", end=' ')
demo2()
print("After demo2", n)
- 保存文件,然后在命令行模式下运行
(yiluo) ➜ Code python b.py
Before demo2 1
Inside demo2 100
After demo2 100
- 举例2
>>> name = 'Yiluo'
>>> def test_local():
... print(name)
... name = 'Tom'
...
>>> test_local()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in test_local
UnboundLocalError: local variable 'name' referenced before assignment
- 当执行到
print(name)
的时候会报错,因为name
作为函数局部变量是在print(name)
之后才定义的 - 现在我们使用
global
关键字,对函数中的name
标志为全局变量,让函数内部使用全局变量的name
,那么整个程序中出现的name
都将是这个
>>> name = 'Tom'
>>> def name_global():
... global name
... print(name)
... name = 'Yiluo'
...
>>> print(name)
Tom
>>> name_global()
Tom
>>> print(name)
Yiluo
- 关键字
global
来告诉name
的定义是全局的,因此在函数内部更改了name
的值,函数外name
的值也实际上更改了
6.函数的参数
Python
常用参数有四种:必选参数
、默认参数
、可变参数
和关键字参数
,复合使用时各类参数的定义顺序须同上
1. 必选参数
>>> def student(name, age):
... print("NAME: ", name)
... print("AGE: ", age)
...
>>> student('yiluo', 18)
NAME: yiluo
AGE: 18
也可是使用参数名进行传参
>>> student(name='yiluo', age=18)
NAME: yiluo
AGE: 18
- 必选参数可以不写参数名,但必须对其赋值,参数赋值顺序是定义的时候指定的,所以必选参数又称为位置参数
>>> def info(student_id, student_name):
... print("Student ID: ", student_id)
... print("Student Name: ", student_name)
...
>>> info(1, 'Yiluo')
Student ID: 1
Student Name: Yiluo
>>> info('Yiluo', 2)
Student ID: Yiluo
Student Name: 2
>>> info(student_name='Yiluo', student_id=1)
Student ID: 1
Student Name: Yiluo
2. 默认参数
>>> def student(name, age=18):
... print("NAME: ", name)
... print("AGE: ", age)
...
>>> student('yiluo')
NAME: yiluo
AGE: 18
>>> student('yiluo', 20)
NAME: yiluo
AGE: 20
如果不传年龄会自动给出默认年龄值
- 例子2
>>> def info(student_name, student_id, city='深圳'):
... print("Student ID: ", student_id)
... print("Student Name: ", student_name)
... print('City: ', city)
...
>>> info('Yiluo', 1)
Student ID: 1
Student Name: Yiluo
City: 深圳
>>> info('Yiluo', 1, '上海')
Student ID: 1
Student Name: Yiluo
City: 上海
- 默认参数没有赋值,则会自动赋其默认值
- 默认参数后面不能再有必选参数,例如 f(a,b=90,c) 就是错误的
- 默认参数的默认值必须设为不可变的数据类型(如字符串、元组、数字、布尔值、None 等)
3. 可变参数
可变参数的定义格式是在参数名前面加上 *
,参数名可以自定义,通常写成 *args
>>> def student(name, age=19, *score):
... print("NAME: ", name)
... print("AGE: ", age)
... print("SCORE: ", score)
...
>>> student('yiluo',19,88,90,100)
NAME: yiluo
AGE: 19
SCORE: (88, 90, 100)
学生的得分分别是 88
,90
,100
4. 关键字参数
关键字参数的定义格式是在参数名前面加上 **
,参数名可以自定义,通常写成 **kw
>>> def student(name, age, **score):
... print("NAME: ", name)
... print("AGE: ", age)
... print("SCORE: ", score)
>>> score = {'数学':'88', '语文':'90','英语':'100'}
>>> student('yiluo', 19, **score)
NAME: yiluo
AGE: 19
SCORE: {'数学': '88', '语文': '90', '英语': '100'}
- (必选参数、默认参数、可变参数)在赋值时都可以不写参数名,而关键字参数允许传入零个或任意多个带参数名的参数,其中参数名可自定义
- 关键字参数会在函数内部自动生成一个字典
- 关键字参数的定义格式是在参数名前面加上 **
- 参数名可以自定义,通常写成 **kw
- 函数体内部使用该参数时,前面不要加 **
5. 命名关键字参数
前文提到,必选参数
、默认参数
、可变参数
在赋值时都可以不写参数名,而命名关键字参数
恰好相反, 赋值时必须写上参数名
>>> def student(*, name):
... print("Hello", name)
...
>>> student('yiluo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: student() takes 0 positional arguments but 1 was given
>>> student(name='yiluo')
Hello yiluo
- 赋值时必须写上参数名
- 此参数的特征就是前面有一个用逗号隔开的 *
- 用户调用函数时,每一个命名关键字参数都必须使用相应的参数名赋值,否则会抛出 TypeError
>>> def hi(*, name):
... print('hi ', name)
...
>>> hi('Yiluo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: hi() takes 0 positional arguments but 1 was given
>>> hi(name='Yiluo')
hi Yiluo
6. 函数中修改参数值
- 函数参数传值的意思是函数调用过程中,在函数内部使用到的参数只是一个局部变量,在函数执行结束后就销毁了。不影响调用该函数的外部参数变量的值
- 函数参数传引用的意思是传递给函数的参数就是外部使用的参数,函数执行过程中对该参数进行的任何修改都会保留,当函数调用结束后,这个参数被其他代码使用中都是函数修改过后的数据
- Python 函数的参数是没有类型的,可以传递任意类型的对象作为参数。但不同类型的参数在函数中,有的可以修改(例如列表对象),有的不可以修改(例如字符串对象)
>>> ipaddress = '192.168.1.168'
>>> ports = [11, 12, 13]
>>> def connect(ipaddress, ports):
... print("IP: ", ipaddress)
... print('Ports: ', ports)
... ipaddress = '10.10.10.1'
... ports.append(8000)
...
>>> print(ipaddress, ports)
192.168.1.168 [11, 12, 13]
>>> connect(ipaddress, ports)
IP: 192.168.1.168
Ports: [11, 12, 13]
>>> connect(ipaddress, ports)
IP: 192.168.1.168
Ports: [11, 12, 13, 8000]
>>> connect(ipaddress, ports)
IP: 192.168.1.168
Ports: [11, 12, 13, 8000, 8000]
>>> print(ipaddress, ports)
192.168.1.168 [11, 12, 13, 8000, 8000, 8000]
- ipaddress 的值没有起到效果,但 ports 列表的值却改变了
- Python 中的对象有不可变对象,指的是数值、字符串、元组等,和可变对象,指的是列表、字典等。如果是不可变对象作为参数,函数中对该参数的修改只能用等号赋值,实际上是创建了一个新的局部变量。如果是可变对象作为参数,函数中的修改会保留
欢迎下方【戳一下】【点赞】
Author:伊洛Yiluo
愿你享受每一天,Just Enjoy !
网友评论