#Python函数和模块使用
一、函数
1、函数定义:
我们可以把程序中相对独立的功能模块抽取出来。这样做的好处一是减少重复代码的编写,二是将来可以使用重复的使用这些功能模块。python中的函数就是代表了这样的功能模块。
2、语法:def f (x):
例如:y = f (x) 其中f是函数名,x是自变量,y是因变量。
# 定义求阶乘的函数 - 将求阶乘的功能抽取出来放到函数中
# 注意:在前面有代码的情况下:定义函数时需要与前、后代码空格两行
def f(x):
y = 1
for z in range(1, x + 1):
y *= z
return y
if __name__ == '__main__':
m = int(input('m = '))
n = int(input('n = '))
print(f(m) // f(n) // f(m - n))
#通过上面的if条件可以在导入模块使用时,直接让新的数据在函数中执行
3、调用函数:函数名 + (自变量)
函数定义过程中,可以赋予函数一个默认值。
在文件hello.py下写一个函数:
def foo():
print('hello, world!')
在hi.py文件引用foo函数:
from hello import foo
foo() # 输出hello, world!
4、参数传递:
在 python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a="Runoob"
以上代码中,[1,2,3] 是 List 类型,“Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是 List 类型对象,也可以指向 String 类型对象。
# 在参数前使用*表示args是可变参数
# 调用f函数时传入的参数个数可以是0个或多个
def f(*args):
total = 0
for val in args:
total += val
return total
mylist = [1, 2, 3, 4, 12, 20]
print(f(*mylist))
# 列表mylist在函数f(*args)中拆散后相加。
- 1).随机参数(可变参数)(*args) – *args是可变参数,args接收的是一个tuple;
随机参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
def my_sum(*args):
total = 0
for x in args:
total += x
return total
def main():
my_list = [1, 2, 3, 4, 5]
# 如果希望将元组或列表作为可变参数传入,需要在参数名前面加*
print(my_sum(*my_list))
if __name__ == '__main__':
main()
- 2).关键字参数(**kwargs) – kwargs接收的是一个dict。 – 根据参数名来决定如何执行
关键字参数可以直接传入:person(‘Jack’, 24, city= ‘Beijing’, job=‘Engineer’),又可以先组装dict,再通过**kwargs传入:person(‘Jack’, 24, **extra)
def person(name, age, **kwargs):
return ('name:', name, 'age:', age, 'other:', kwargs)
def main():
extra = {'city': 'Beijing', 'job': 'Engineer'}
print(person('Jack', 24, **extra))
if __name__ == '__main__':
main()
- 3).命名关键字参数 – 定义命名的关键字参数不要忘了写分隔符*,否则定义的将是位置参数。
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。如果要限制关键字参数的名字,就可以用命名关键字参数,例如,上面person函数中只接收city和job作为关键字参数,添加一个特殊分隔符"*",后面的参数被视为命名关键字参数。命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:命名关键字参数可以有缺省值,从而简化调用:
def person(name, age, *, city, job):
print(name, age, city, job)
def main():
person('Jack', 24, city='Beijing', job='Engineer')
if __name__ == '__main__':
main()
5、函数的递归调用:
函数的递归调用需满足以下两个条件
1、收敛条件 – 让递归在有限次数完成或者回溯
(如果递归条件无法在有限次数内收敛就有可能导致RecursionError)
2、递归公式
# 1到100求和
def f(n):
if n == 1:
return 1
return (n + f(n - 1))
if __name__ == '__main__':
print(f(100))
6、作用域—LEGB
局部变量(local veriable) 全局变量(global veriable)
局部作用域:函数只在函数作用域内使用 (嵌套作用域、全局作用域、内置作用域)
注意:python搜索一个变量的方式是从局部作用域到嵌套作用域再到全局作用域。
Local — Enclosed — Global。
**如果想改变搜索范围,可以使用Global和nonlocal关键字 **
注意:开发过程中减少全局变量的使用,能不使用全局变量就一定不能使用。
a = 100
def f():
global a
a = 200
# 此处执行出的a为100,因为赋值说明了global a,否则执行结果为200
b = 'hello'
def g():
nonlocal b
b = 'good'
# 此处执行结果为good,????
6、装饰器 / 包装器 – decorator
通过装饰器修饰函数 让函数在执行过程中可以做到更多额外的操作
7、高阶函数 y = f(g(x)) – λ Lambda函数(匿名函数) / 闭包 / 偏函数 / 柯里化
嵌套函数
#通过向函数中传入函数,可以写出更通用的代码
#calc函数中的第二个参数是另一个函数 它代表一个二元运算
#这样的calc函数就不需要根某一种特定的二元运算耦合在一起
#所以calc函数变得通用性更强,可以由传入的第二个参数来决定到底做什么
def calc(my_list, op):
total = my_list[0]
for index in range(1, len(my_list)):
total = op(total, my_list[index])
return total
##二、模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你能够有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。(用import导入模块来使用)
模块能定义函数,类和变量,模块里也能包含可执行的代码。
用as命名代替长名字的函数。
单一职责原则:模块,函数,
import module1 as m1
import module2 as m2
m1.foo()
m2.foo()
# as让m1、m2分别代替module1和module2
内存管理
栈 - 变量 - 地址 - 对象的引起 堆 - 真正的对象 id() is() 静态区
# 用sys.getrefcount() 查看内存量占用
import sys
list1 = [0] * 10
list2 = list1
list3 = list2
print(sys.getsizeof(list1))
print(sys.getrefcount(list1))
del list2
del list3
del list1[0]
print(sys.getrefcount(list1))
三、练习
约瑟夫环:
def main():
persons = [True] * 30
counter = 0 # 死去的人数
index = 0 # 下标
number = 0 # 报数
while counter < 15:
if persons[index]:
number += 1
if number == 9:
persons[index] = False
counter += 1
number = 0
index += 1
# index %= 30
if index == 30:
index = 0
for person in persons:
print('基' if person else '非', end=' ')
if __name__ == '__main__':
main()
模拟双色球机选出号双色球:
from random import randrange,randint
def display(balls):
for index, ball in enumerate(balls):
if index == len(balls) - 1:
print('|', end=' ')
print('%02d' %ball, end=' ')
print()
def random_select():
red_balls = list(range(1, 34))
selected_balls = []
for _ in range(6):
index = randrange(len(red_balls))
selected_balls.append(red_balls[index])
del red_balls[index]
selected_balls.sort()
selected_balls.append(randint(1, 16))
return selected_balls
def main():
n = int(input('机选几注:'))
for _ in range(n):
display(random_select())
if __name__ == '__main__':
main()