Python-100-Days/Jax_code/Day6/Note.md

4.1 KiB
Raw Blame History

函数的参数

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


def add(a=0, b=0, c=0):
    """三个数相加"""
    return a + b + c

print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
# 传递参数时可以不按照设定的顺序进行传递
print(add(c=50, a=100, b=200))

用模块管理函数

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

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

module3.py

def foo():
    pass

def bar():
    pass

# __name__是Python中一个隐含的变量它代表了模块的名字
# 只有被Python解释器直接执行的模块的名字才是__main__
if __name__ == '__main__':
    print('call foo()')
    foo()
    print('call bar()')
    bar()

变量的作用域

Python查找一个变量时会按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索

我们可以使用global关键字来指示foo函数中的变量a来自于全局作用域,如果全局作用域中没有a,那么下面一行的代码就会定义变量a并将其置于全局作用域。同理,如果我们希望函数内部的函数能够修改嵌套作用域中的变量,可以使用nonlocal关键字来指示变量来自于嵌套作用域,请大家自行试验。

def foo():
    global a
    a = 200 #全局作用域
    b = 100 #嵌套作用域
    
    def bar():
        nonlocal b
        global c #全局作用域
        b = 200
        c = 200       
    bar()
    print(b)
        
if __name__ == '__main__':
    a = 100
    c = 100

    foo()
    print(a, c)

在实际开发中,我们应该尽量减少对全局变量的使用,因为全局变量的作用域和影响过于广泛,可能会发生意料之外的修改和使用,除此之外全局变量比局部变量拥有更长的生命周期,可能导致对象占用的内存长时间无法被垃圾回收。事实上,减少对全局变量的使用,也是降低代码之间耦合度的一个重要举措,同时也是对迪米特法则的践行。减少全局变量的使用就意味着我们应该尽量让变量的作用域在函数的内部,但是如果我们希望将一个局部变量的生命周期延长,使其在定义它的函数调用结束后依然可以使用它的值,这时候就需要使用闭包,这个我们在后续的内容中进行讲解。

def main():
    # Todo: Add your code here
    pass


if __name__ == '__main__':
    main()