python学习笔记(三)函数和模块的使用

在编程解决问题时,会有很多问题重复,这样的话我们使用的代码也是重复的,如果我们再把代码全部重写一遍的话,这样是非常不明智的,因此我们可以将这些重复功能的函数封装到一个代码块中,当我们要解决相应的问题再去调用这个代码块,即调用相应的函数。
简而言之,一个函数就是将一些语句集合在一起的部件,它们能够不止一次地在程序中运行。
我们定一函数的时候,会用到def关键字,函数的基本结构如下所示:

def <name> (arg1,arg2,...,argn):
	<statements>

在python中使用def来定义函数,后面name的部分就是函数的名字,括号里的arg1,arg2…argn为传入的参数。当函数中的内容执行完成后,如果需要就是用return关键字返回相应的值,如果不需要返回值,可以不用return。
下面是有关函数的几个例子:

'''
例1:求阶乘并打印
'''
def factorial(num):
    result = 1
    for n in range(1,num+1):
        result = result*n
    return result
    
n = int(input())
# 直接调用已经定义好的阶乘函数
print(factorial(n))

说明:说明: Python的math模块中其实已经有一个factorial函数了,事实上要计算阶乘可以直接使用这个现成的函数而不用自己定义。

函数的参数

在python中,函数的参数可以有默认值,也可以使用可变参数,所以Python并不需要像其他语言一样支持函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式。

'''
例2:函数参数默认值小例子
'''
from random import randint

#摇色子
def roll_dice(n=2):
    total = 0
    for _ in range(n):
        total = total + randint(1,6)
    return total

#返回求和
def add(a=0, b=0, c=0):
    return a+b+c

#如果没有指定,则默认摇色子摇两次
print(roll_dice())
#指定要几次色子
print(roll_dice())
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
# 传递参数时可以不按照设定的顺序进行传递
print(add(a=50, c=100, b=200))

但是,有很多时候存在需要传入几个参数个数不确定的情况,因此这个时候就需要使用可变参数,如例3

'''
例3:使用可变参数求和
'''
#参数名字前加*表示为args是一个可变参数
def add(*args):
    total = 0
    for val in args:
        total = total + val
    return total

#在调用add函数时可以传入0个或多个参数
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7, 9))

使用模块管理函数

在实际的开发过程中,会遇到函数重名的情况,上边说过在python中函数不能重载,所以遇到函数重名的情况,我们会用模块化的方法来解决。

def foo():
    print('hello, world!')
def foo():
    print('goodbye, world!')
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()

也可以采用以下方法:
test.py

import module1 as m1
import module2 as m2

m1.foo()
m2.foo()

在python中也有像C语言中main函数,如下所示

def foo():
    pass

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

一些小例子

'''
例4:定义函数求两个数的最大公因数和最小公倍数
'''
#求最大公因数
def gcd(x,y):
    if y > x:
        temp = x
        x = y
        y = temp
    for i in range(x, 0, -1):
        if x%i==0 and y%i==0:
            return i

#求最小公倍数
def lcm(x,y):
    m = x*y // gcd(x,y)
    return m

print(gcd(30,45))
print(lcm(30,45))

在这里有一个公式:两个数的成绩=两个数的最大公因数*最小公倍数

'''
例5:定义函数判断一个数是否为素数
'''
def is_prime(num):
    for i in range(2,num):
        if num % i == 0:
            return False
    return True

if is_prime(5):
    print('Yes')
else:
    print('No')

当我们将代码中重复出现的和相对独立的功能抽取成函数后,我们可以组合使用这些函数来解决更为复杂的问题,这也是我们为什么要定义和使用函数的一个非常重要的原因。

变量作用域

def foo():
    b = 'hello'

    # Python中可以在函数内部再定义函数
    def bar():
        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()

对于以上的程序,主函数中的a变量为全局变量(global variable),属于全局作用域,因为它没有定义在任何一个函数中。在foo()函数中的b变量这是一个定义在函数中的局部变量(local variable),属于局部作用域,在foo函数的外部并不能访问到它;但对于foo函数内部的bar函数来说,变量b属于嵌套作用域,在bar函数中我们是可以访问到它的。bar函数中的变量c属于局部作用域,在bar函数之外是无法访问的。事实上,Python查找一个变量时会按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索。

def foo():
    a = 200
    print(a)  # 200


if __name__ == '__main__':
    a = 100
    foo()
    print(a)  # 100

对于上面这段代码,由于foo函数中定义的a属于局部变量,只在该函数的内部能够访问,而main中的函数属于全局变量,所以在给全局变量a赋值后调用foo函数无法改变全局变量a的值。两者只是名字相同,但实质上根本就是两个不同内存空间。

def foo():
    global a
    a = 200
    print(a)  # 200


if __name__ == '__main__':
    a = 100
    foo()
    print(a)  # 200

我们可以使用global关键字来指示foo函数中的变量a来自于全局作用域,如果全局作用域中没有a,那么下面一行的代码就会定义变量a并将其置于全局作用域。
注意:在开发过程中应该避免全局变量的使用(迪米特法则)
以下为python函数的最基本框架:

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


if __name__ == '__main__':
    main()

参考资料:
[1]https://github.com/jackfrued/Python-100-Days
[2]《Python学习手册(第4版)》

发布了20 篇原创文章 · 获赞 0 · 访问量 754

猜你喜欢

转载自blog.csdn.net/LeavingBook/article/details/104289261