编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种! ”,要写出高质量的代码首先要解决的就是重复代码的问题。函数能提高应用的模块性,和代码的重复利用率。
1.函数
在Python中可以使用def关键字来定义函数,和变量一样每个函数也有名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,这一点和数学上的函数非常相似,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。
-
想要定义一个自己的想要功能的函数,需要遵守以下规则:
- 函数代码块用
def关键词开头,后接函数标识符名称和圆括号() - 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明
- 函数内容以冒号
:起始,并且缩进 return [表达式]结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None
- 函数代码块用
说明:图片与函数定义规则引用于python菜鸟教程,如有侵权,请告知我,我会删除。
1.1 函数语法
python自定义函数使用def关键字,一般格式如下:
def 函数名(参数列表):
函数体
默认情况下,参数值和参数名称是按照函数声明中定义的顺序匹配起来的。
无参实例:
def hello():
"""无参函数"""
print("hello world")
hello() # hello world
1.2 函数的参数
Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持
函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式。
函数带上参数实例:
def add(a: int, b: int) -> int:
"""
求和函数
@param a: a参数
@param b: a参数
@return: 参数相加值
"""
total = a + b
return total
print(add(a=3, b=4)) # 7
函数参数含默认值的实例:
def add(a: int = 0, b: int = 0, c: int = 0) -> int:
"""
三个数相加
@param a: a参数
@param b: a参数
@param c: a参数
@return: 参数相加值
"""
total = a + b + c
return total
# 调用方法不传参
print(add()) # 0
# 调用参数传参
print(add(1)) # 1
print(add(1, 2)) # 3
print(add(1, 2, 3)) # 6
# 传递参数时可以不按照设定的顺序进行传递
print(add(c=50, a=100, b=200)) # 350
上面的函数的参数设定了默认值,这也就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,所以在上面的代码中我们可以用各种不同的方式去调用add函数,这跟其他很多语言中函数重载的效果其实是一致的。
Tips:其实上面的add函数还有更好的实现方案,因为我们可能会对0个或多个参数进行加法运算,而具体有多少个参数是由调用者来决定,我们作为函数的设计者对这一点是一无所知的,因此在不确定参数个数的时候,我们可以使用可变参数。实例:
P.S. : 听我JAVA开发同学说JAVA好像不推荐使用不定长参数,有没有懂的大佬解答一下~
# 在参数名前面的*表示args是一个可变参数
def add(*args):
"""
求和函数
@param args: 可变参数(实际就是一个元祖)
@return: 参数相加值
"""
total = 0
for val in args:
total += val
return total
# 在调用add函数时可以传入0个或多个参数
print(add()) # 0
print(add(1)) # 1
print(add(1, 2)) # 3
print(add(1, 2, 3)) # 6
print(add(1, 3, 5, 7, 9)) # 25
2.模块管理函数
对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。例如:
def foo():
print('hello, world!')
def foo():
print('goodbye, world!')
# 后面定义的同名函数会覆盖前面的定义
foo() # goodbye, world!
Tips:实际我们在定义同名函数的情况,工具会给出相应提示:Redeclared 'foo' defined above without usage(重新声明了上面定义的“foo”,但未使用),平时开发过程多注意就好了~
当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为foo的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过import关键字导入指定的模块就可以区分到底要使用的是哪个模块中的foo函数,例如:
module1.py
def foo():
print('hello, world!')
module2.py
def foo():
print('goodbye, world!')
test.py
from module1 import foo
# 输出hello, world!
foo()
from module2 import foo
# 输出goodbye, world!
foo()
也可以按照如下所示的方式来区分到底要使用哪一个foo函数。
test.py
import module1 as m1
import module2 as m2
m1.foo() # hello, world!
m2.foo() # goodbye, world!
但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个foo,因为后导入的foo覆盖了之前导入的foo。
test.py
from module1 import foo
from module2 import foo
foo() # goodbye, world!
test.py
from module2 import foo
from module1 import foo
foo() # hello, world!
个人学习记录笔记,非商业用途,如有侵权,请告知我,我会删除。