目录

  • 函数
  1. 函数的定义
  2. 函数的参数
  1. 必选参数
  2. 默认参数值
  3. 可变参数
  4. 关键参数
  1. 局部变量
  2. 使用全局语句 global
  3. 使用非局部语句 nonlocal

函数

1. 函数的定义

函数三要素:关键字 def方法名()冒号 :

# 无参函数
def fun_name():
    print('statement...')

# 有参函数
def fun_name(arg1, arg2):
    print('statement...')

#空函数
def fun_empty():  #空函数会报错,所以使用'pass'关键字
    pass

2. 函数的参数

参数类型:
1. 必选参数:调用方法时,必须传入的参数(必选参数必须在最前,否则会报错);
2. 默认参数:默认参数必须指向不变对象;
3. 可变参数:可变参数就是传入的参数个数是可变的 (例如listtuple);
4. 关键参数:类似Java对象的概念,作用是扩展函数的功能 (例如 dict);

参数组合:参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数

'''
arg1、arg2:必选参数
arg3:默认参数,为默认值2
arg4:默认参数,为默认值'a'
arg5:可变参数
arg6:关键参数
'''
def play(arg1, arg2, arg3=2, arg4='a', *arg5, **arg6)
    print(arg1, arg2, arg3, arg4, arg5, arg6)

#只传入必选参数,则arg3使用默认参数2,arg4使用默认参数'a'
play('a', 'b')

#传入必选参数和默认参数,则arg3使用传入的参数4,arg4使用默认参数'a'
play('a', 'b', 4)  
#传入必选参数和默认参数,则arg3使用传入的参数4,arg4使用传入的参数'c'
play('a', 'b', 4, 'c') 
#执行有多个默认参数的函数时,不按顺序提供默认参数,则默认值需要写上参数名
play('a', 'b', arg4 = 'c') 

#传入可变参数(传入的可变参数被当做一个tuple,其实也被当做是一个参数)
play('a', 'b', 1, 2, 3)

list = [1, 2, 3]
play('a', 'b', 2, 'c', *list)

tuple = (1, 2, 3)
play('a', 'b', 2, 'c', *tuple) 
# 小结:定义可变参数和定义 list 或 tuple 参数相比,仅仅在参数前面加了一个*号;

#关键参数
#可变参数允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple
play('a', 'b', city='Beijing') 

#关键参数允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
dict = {'city': 'Beijing', 'job': 'Engineer'}
play('a', 'b', **dict) 

#对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的
list = (1, 2, 3, 4, 5)
kw = {'x': 99}
play(*list, **kw)
#1, 2, 3, 4, (5, ), {'x': 99}

3. 返回多个值(函数可以返回多个值)

函数返回多值的本质:Python函数返回的仍然是单一值;

import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

x, y = move(100, 100, 60, math.pi/6)
print('x=', x, 'y=', y)
>>> x=151.961524227 y=70.0

r = move(100, 100, 60, math.pi / 6)
>>> print(r) #返回值是一个tuple,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值
(151.96152422706632, 70.0)

4. 参数检查

调用函数时,如果参数 个数 不对,Python解释器会抛出TypeError异常;
调用函数时,如果参数 类型 不对,Python解释器则无法检查出错误;

示例: 对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数 isinstance 实现:

def my_abs(x):
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

5. 函数别名

函数名其实就是指向一个函数对象的引用,可以将函数名赋值给一个变量,相当于给这个函数起了一个“别名”。

a = abs # 变量a指向abs函数
a(-1) # 所以也可以通过a调用abs函数
>>> 1

局部变量

x = 50
def func(x):    
    print('x is', x)
    x=2  #局部变量,虽然和全局变量同名,但不会影响外部变量的值;
    print('Changed local x to', x)

func(x) #调用方法
print('x is still', x)

输出:

x is 50
Changed local x to 2
x is still 50 #值未被改变


使用全局语句(global

x = 50

def func():
    global x  #将变量x声明成全局变量

    print('x is', x)
    x = 2  #重新赋值
    print('Change local x to', x)


func()
print('Value of x is', x)

输出:

x is 50
Change local x to 2
Value of x is 2 #值被改变


使用非局部语句 (nonlocal)

非局部语句:当在函数 func_inner 的内部时,在函数 func_outer 的第一行定义的 ’x’ 相对来讲,既不是在局部范围也不是在全局的作用域中,使用这样的 x 称之为非局部 x 。

def func_outer(): 
    x=2
    print('x is',x) 

    def func_inner():
        nonlocal x x=5

    func_inner()
    print('Changed local x to',x)

func_outer()

输出:

x is 2
Changed local x to 5