Python函数的定义和调用(非常详细,附带实例)
在 Pyhton 中,函数是一段组织好的、可重复使用的、用来实现特定功能的代码。把常用的功能封装成函数,并在需要时调用,可以提高代码开发效率。
例如,封装一个名为 backup_config 的函数,用于登录设备、执行命令,并将回显写入指定文本文件。当需要对成百上千台网络设备进行配置备份时,只需要循环读取设备列表,调用 backup_config 函数即可。
函数不仅可以提高开发效率,函数的定义与调用也可以让代码更加简洁、可读性更高。
例如,定义一个端口描述配置的函数:
函数定义的参数被称为形参,调用时传入的参数被称为实参,将实参赋值给形参,即完成函数的参数赋值。
函数的参数赋值主要有按参数名赋值和按位置赋值两种方式。
例如:
例如:
调用函数时,有默认值的参数可以不赋值,这时函数会将对应参数自动赋值为默认值。例如:
当参数比较少时,多使用按位置赋值的方式,这样代码更加简洁,可读性更好。当函数的参数比较复杂时,可以将两种传参方式结合使用,第一个参数使用按位置赋值的方式,不写参数名,其余的参数显式地使用按参数名赋值的方式。
例如,下面的实例程序演示了按位置和按参数名赋值结合使用的方法:
在主函数中调用其他函数,不仅可以提高代码可读性,也方便后续代码的维护,同时体现了分而治之的编程思想。
在编写函数时,函数名、参数名、主干代码的逻辑和返回值的结构也需要读者仔细推敲:
例如,封装一个名为 backup_config 的函数,用于登录设备、执行命令,并将回显写入指定文本文件。当需要对成百上千台网络设备进行配置备份时,只需要循环读取设备列表,调用 backup_config 函数即可。
函数不仅可以提高开发效率,函数的定义与调用也可以让代码更加简洁、可读性更高。
Python函数的定义
完整的函数由函数名、参数、文档字符串、代码块、返回值 5 部分组成。函数定义的语法规则如下:def function_name(参数1,参数2,..,参数N): 代码块 return 返回值
- 函数的定义以 def 关键字开头,后接函数名和参数;
- 函数名一般采用蛇形命名法,参数通过圆括号紧随函数名之后,参数的个数为任意个,包括 0 个;
- 函数的内容通过冒号开始,需要换行并控制缩进(一般为 4 个空格);
- 然后就可以编写实现特定功能的核心代码块,定义的参数也可以在代码块中被使用;
- 函数最后可通过 return 关键字提供返回值。return 语句是可选项,如果没有 return 语句,那么函数默认返回 None。
例如,定义一个端口描述配置的函数:
def gen_intf_desc_configs(intf_name,description='NetDevOps'): ''' 生成端口描述的配置 :param intf_name:端口名称 :param description: 端口描述的内容,默认值为 NetDevOps :return: 端口描述配置文本 ''' # 模板字符串 intf_desc_config_tmpl = '''interface {intf_name} description {description} ''' # 通过format函数格式化配置 config = intf_desc_config_tmpl.format(intf_name=intf_name, description=description) return config函数中的参数可以设置默认值,在上面的程序中,端口描述的参数 description 设置了默认值 NetDevOps,用户在调用函数的时候,可以不给此参数赋值,函数体内部使用此参数的默认值。在通过字符串的 format() 方法生成标准的配置后,将其赋值给变量 config。最后通过 return 语句将值返回给调用方。
Python函数的调用
函数定义完成之后,就可以对其进行调用。调用函数时可以直接使用函数名,后接圆括号,圆括号内填写传递的参数,这样就可以完成一次函数的调用。函数定义的参数被称为形参,调用时传入的参数被称为实参,将实参赋值给形参,即完成函数的参数赋值。
函数的参数赋值主要有按参数名赋值和按位置赋值两种方式。
1) 按参数名赋值
形参名通过等号赋值为实参,形参名的位置可以调整,但建议尽量按原有顺序赋值,并显式地写明每个形参的赋值。例如:
intf_name = 'Eth1/1' description = 'configed by python' # 通过等号对参数进行顺序赋值 config = gen_intf_desc_configs(intf_name=intf_name,description=description) # 可以适当调整顺序,但不建议调整 config = gen_intf_desc_configs(description=description,intf_name=intf_name)
2) 按位置赋值
需要按照形参的位置一一对应传入实参,无须填写参数名称,Python 解释器会根据形参的位置与用户传入的实参(赋值)自动对应。例如:
intf_name = 'Eth1/1' description = 'configed by python' config = gen_intf_desc_configs(intf_name,description)
调用函数时,有默认值的参数可以不赋值,这时函数会将对应参数自动赋值为默认值。例如:
intf_name = 'Eth1/1' # 按参数名进行赋值 config = gen_intf_desc_configs(intf_name=intf_name) # 按位置进行赋值 config = gen_intf_desc_configs(intf_name)
当参数比较少时,多使用按位置赋值的方式,这样代码更加简洁,可读性更好。当函数的参数比较复杂时,可以将两种传参方式结合使用,第一个参数使用按位置赋值的方式,不写参数名,其余的参数显式地使用按参数名赋值的方式。
例如,下面的实例程序演示了按位置和按参数名赋值结合使用的方法:
intf_name = 'Eth1/1' description = 'configed by python' configs = gen_intf_desc_configs(intf_name,description=description)
总结
函数的编程思想需要在实践中不断练习形成:- 如果遇到一段功能在多个代码中反复出现就要考虑将其封装成函数;
- 如果某个模块为实现一个较为复杂的功能而存在多行代码,应该考虑将其拆解成几个函数。
在主函数中调用其他函数,不仅可以提高代码可读性,也方便后续代码的维护,同时体现了分而治之的编程思想。
在编写函数时,函数名、参数名、主干代码的逻辑和返回值的结构也需要读者仔细推敲:
- 函数名和参数名可读性要好,要言之有物,用户从名称就可以了解函数的功能和参数的意义;
- 参数设计要合理,每个参数的数据类型相对是单一的;
- 函数的功能要相对单一、目标明确,不将太多功能放在一个函数中;
- 主干代码的逻辑清晰,注释量适中,缩进整齐,可读性好;
- 尽量让代码有返回值,返回值的结构清晰、意义明确。