一、函数定义

# 定义一个函数
def my_func(input_text):
    print(input_text)

my_func('hello world')
 # hello world
 
 # 其中
 # def是定义函数的声明
 # my_func 是函数的名称
 # 括号里面的input_text 是函数的参数
 # print部分是函数的执行语句部分
 # 在函数最后,你可以返回调用结果(return 或 yield),也可以不返回值
 
 # 抽象出来大概就是
 def func_name(param1,param2,...,paramN):
   statements
   return/yield value

由于python是不需要编译的,所以其函数def是可执行的一条语句,也就意味着直到函数被调用前,这个函数都不存在,直到函数被调用时,def语句才会创建一个新的函数对象,并赋予名字。

函数使用小tips:

  1. 如果我们的主程序调用函数时,函数没有在之前定义,那就会报出错误
my_func('hello world')
def my_func(input_text):
    print(input_text)
#NameError: name 'my_func' is not defined
  1. 但是如果我们是在函数中去调用函数,那函数定义的先后就不受影响
def my_func_v1(input_text):
    my_func(input_text)
    
def my_func(input_text):
    print(input_text)
    
my_func_v1('hello world')
#hello world

二、函数参数

函数在调用参数的时候,可以为其设定一个默认的值,这样如果param没有传入,则参数默认传0;而如果传入了参数则会覆盖默认值。

def my_sum(num1, num2 = 1):
    return num1+num2

print(my_sum(1))
# 2
print(my_sum(1, 2))
# 3

注:由于python是动态类型的,也就是说python可以接受任意数据类型的值。而对于函数参数来说,这一点用样的适用。

print(my_sum([1,2],[2,3]))
#[1, 2, 2, 3]

print(my_sum('hello',' python'))
#hello python

print(my_sum('hello',[1,2]))
#TypeError: can only concatenate str (not "list") to str

# 可以看出python不用考虑输入的数据类型,程序内部会去判断执行,
# 同一个函数可以同时应用在多种数据类型操作中,而这样的行为在java等语言中被称为多态


三、函数嵌套

python 函数还有一大特性就是支持函数的嵌套。所谓的函数嵌套,就是函数里面又有函数

def f1():
    print('hello')
    def f2():
        print('python')
    f2()
f1()
#hello
#python

函数嵌套可以保证内部函数的隐私。内部函数只能被外部函数所调用和访问,不会暴露在全局作用域,因此,如果你的函数内部有一些隐私数据,不想暴露在外,那你就可以使用函数的嵌套,将其封装在内部函数中,只通过外部函数来访问。其另一个作用就是可以简化代码

四、函数变量作用域

python 函数中变量的作用域和其他语言类似,分为全局变量和局部变量

# 定义局部变量,此时的file就是一个局部变量函数外部是无法访问的
def read_text(file_path):
  with open(file_path) as file:
    ...
    
# 定义全局变量,此时的MIN_VALUE & MAX_VALUE 就是全局变量,程序任意位置都可以访问
MIN_VALUE = 1
MAX_VALUE = 10
def val_check(value):
  if value > MAX_VALUE or value < MIN_VALUE:
    raise Exception('check fails')
   

在python中我们不能在函数内部随意改变全局变量的值

# 函数内部修改全局变量
MIN_VALUE = 1
MAX_VALUE = 10
def val_check(value):
  MIN_VALUE += 1
  
val_check(1)
# 这段代码在idea中会不通过。运行的话会报错:UnboundLocalError: local variable 'MIN_VALUE' referenced before assignment
# 原因是python解释器会默认函数内部的变量都为局部变量,但是有没有关于MIN_VALUE 的声明。

# 如果我们需要修改在函数中修改全局变量的值,需要加上global,通过其告诉python解释器,
# 函数内的MIN_VALUE 是我们之前定义的全局变量
MIN_VALUE = 1
MAX_VALUE = 10
def val_check(value):
    global MIN_VALUE
    MIN_VALUE += 1

val_check(1)
print(MIN_VALUE)
# 2

# 如果函数内与函数外定义了同名变量,则函数内部就是函数内部定义的值,函数外则是函数外定义的值
MIN_VALUE = 1
MAX_VALUE = 10

def val_check():
    MIN_VALUE = 3
    print(f"函数内:{MIN_VALUE}")

val_check()
print(f"函数外:{MIN_VALUE}")
# 函数内:3
# 函数外:1

# 映射至函数嵌套。如果内部函数要修改外部函数的值,需要使用nonlocal 定义一下
def out_func():
  x = 'out'
  def inn_func():
    nonlocal x 
    x = 'inn'
    print(f"inn_func:{x}")
  inn_func()
  print(f"inn_func:{x}")
out_func()

#inn_func:inn
#inn_func:inn

五、闭包

其与上讲解的嵌套函数类似,不同的是外部函数返回的是一个函数,而不是一个具体的值。其作用就是使代码更加简洁

def out_func(out_param):
  def inn_func(inn_param):
    return out_param ** inn_param
  return inn_func # 返回一个函数

square = out_func(2) # 计算一个数的平方
cube = out_func(3) # 计算一个数的平方

print(square)
print(cube)
#<function out_func.<locals>.inn_func at 0x114e66378>
#<function out_func.<locals>.inn_func at 0x114e66400>

print(square(3))
print(cube(3))
#8
#27
# 看完可能会疑惑这不是很鸡肋嘛。其实闭包一般与装饰器一起使用!
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐