定义函数

在Python中可以使用def关键字来定义函数,和变量一样每个函数也有一个响亮的名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,这一点和数学上的函数非常相似,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。

重构,所谓重构就是在不影响代码执行结果的前提下对代码的结构进行调整

函数的参数

函数是绝大多数编程语言中都支持的一个代码的”构建块”,但是Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式

函数的作用

函数的作用就是复用

用模块管理函数

对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。

  1. def foo():
  2. print('hello, world!')
  3. def foo():
  4. print('goodbye, world!')
  5. # 下面的代码会输出什么呢?
  6. foo()


当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为foo的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过import关键字导入指定的模块就可以区分到底要使用的是哪个模块中的foo函数,代码如下所示。

module1.py

  1. def foo():
  2. print('hello, world!')


module2.py

  1. def foo():
  2. print('goodbye, world!')


test.py

  1. from module1 import foo
  2. # 输出hello, world!
  3. foo()
  4. from module2 import foo
  5. # 输出goodbye, world!
  6. foo()


也可以按照如下所示的方式来区分到底要使用哪一个foo函数。

test.py

  1. import module1 as m1
  2. import module2 as m2
  3. m1.foo()
  4. m2.foo()


但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个foo,因为后导入的foo覆盖了之前导入的foo。

test.py

  1. from module1 import foo
  2. from module2 import foo
  3. # 输出goodbye, world!
  4. foo()


test.py

  1. from module2 import foo
  2. from module1 import foo
  3. # 输出hello, world!
  4. foo()


需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是”main“。

module3.py

  1. def foo():
  2. pass
  3. def bar():
  4. pass
  5. # __name__是Python中一个隐含的变量它代表了模块的名字
  6. # 只有被Python解释器直接执行的模块的名字才是__main__
  7. if __name__ == '__main__':
  8. print('call foo()')
  9. foo()
  10. print('call bar()')
  11. bar()

test.py

  1. import module3
  2. # 导入module3时 不会执行模块中if条件成立时的代码 因为模块的名字是module3而不是__main__