函数
1、为什么使用函数?
答:为了解决重复代码问题!编程大师Martin Fowler曾说过:“代码有很多种坏味道,重复是最坏的一种。”函数的存在就是将代码封装,方便以后遇到相同问题直接调用即可。
2、如何定义函数?
答:使用def name()来定义函数,括号内可以加函数的参数,函数的name命名遵循变量命名的规则。与数学上的函数形式类似,参数相当于自变量,return返回的值相当于因变量。
3、函数参数的使用?
答:当我们给一个函数的参数都设定了默认值,如果调用函数时没有传参,函数使用的默认值。当具体参数个数需要由调用者来决定时,可以使用可变参数,在定义函数时将args(args随便取名,重要的是)放入括号内,那么调用该函数时传入的参数个数就可以是0或者多个,如下:
def add(*args):
total = 0
for val in args:
total += val
return total
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7))
4、函数命名冲突怎么办?
答?由于Python没有函数重载的概念,如果在同一.py文件中定义了2个同名函数,后面的定义会覆盖前面的定义。然而在实际的团队开发中,可能很多程序员都定义了同名函数,这时候可以使用import来导入指定模块调用你真正想使用的函数(每个python文件其实就代表了一个模块modul),如下:
module1.py
def foo():
print('hello, world!')
module2.py
def foo():
print('goodbye, world!')
test.py
from module1 import foo
foo() # 输出hello, world!
from module2 import foo
foo() # 输出goodbye, world!
也可以在调用时对同名函数as命名:
test.py
import module1 as m1
import module2 as m2
m1.foo()# 输出hello, world!
m2.foo()# 输出goodbye, world!
需要说明的是,如果我们导入的模块除了定义函数之外还有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是“main”。
modul3.py
def foo():
pass
def bar():
pass
# __name__是Python中一个隐含的变量它代表了模块的名字
# 只有被Python解释器直接执行的模块的名字才是__main__
if __name__ == '__main__':
print('call foo()')
foo()
print('call bar()')
bar()
test.py
import module3
#此时,不会执行模块中if语句里面的代码,因为模块的名字是module3而不是__main__
5、变量作用域
答:记住:Local -> Enclosed -> Global -> built_in顺序,即局部作用域 ->嵌套作用域 ->全局作用域 ->内置作用域,可以通过下面的例子体会:
def foo():
b = 'hello'
def bar(): # Python中可以在函数内部再定义函数
c = True
print(a)
print(b)
print(c)
bar()
# print(c) # NameError: name 'c' is not defined
if __name__ == '__main__':
a = 100
# print(b) # NameError: name 'b' is not defined
foo()
我们可以使用global关键字来指示foo函数中的变量a来自于全局作用域,如果全局作用域中没有a,那么下面一行的代码就会定义变量a并将其置于全局作用域。同理,如果我们希望函数内部的函数能够修改嵌套作用域中的变量,可以使用nonlocal关键字来指示变量来自于嵌套作用域。
def foo():
global a
a = 200
print(a) # 200
if __name__ == '__main__':
a = 100
foo()
print(a) # 200
在实际开发中,我们应该尽量减少对全局变量的使用,因为全局变量的作用域和影响过于广泛,可能会发生意料之外的修改和使用。事实上,减少对全局变量的使用,也是降低代码之间耦合度的一个重要举措,同时也是对迪米特法则的践行。
建议以后定义函数直接如下写法:
def main():
# Todo: Add your code here
pass
if __name__ == '__main__':
main()