Python基础学习笔记(四)函数和代码复用

Python基础学习笔记(四)函数和代码复用

函数的定义和使用

1、函数理解与定义
函数是一段具有特定功能的、可重用的语句组,是一种功能的抽象,基本作用是降低编程难度和代码复用。

def <函数名>(<参数>)<函数体>
	return <返回值>

2、函数使用和调用
调用时要给出实际参数,实际参数会替换掉定义中的参数,函数调用后得到返回值。

函数参数传递:
可以有参数也可以没有,但是必须保留括号。可以指定默认值,构成可选参数。非可选参数意味着调用该函数时必须有这个参数,放在所有可选参数前面。可选参数意味着可以不给出这个参数,如果给出按给出参数执行函数,如果不给按默认参数执行函数。

def <函数名>(<非可选参数>, <可选参数>)<函数体>
	return <返回值>

def fact(n, m = 1):
	s = 1
	for i in range(1, n+1):
		s *= i
	return s//m

>>> fact(10)
3628800
>>> fact(10, 5)
725760

可变参数定义:设计函数接收的参数是可变数量的。先确定要给的参数放在最前面,用*b表达不确定的参数。

def <函数名>(<参数>, *b)<函数体>
	return <返回值>

def fact(n, *b):
	s = 1
	for i in range(1, n+1):
		s *= i
	for item in b:
		s *= item
	return s

调用函数时,可以按照位置(默认方式)或者名称方式传递:

def fact(n, m = 1):
	s = 1
	for i in range(1, n+1):
		s *= i
	return s//m

>>> fact(10, 5)
>>> fact(m=5, n=10)

函数返回值
可以返回0或者多个结果,使用return传递返回值。可以有返回值也可以没有。

def fact(n, m = 1):
	s = 1
	for i in range(1, n+1):
		s *= i
	return s//m, n, m

>>> fact(10, 5)
(725760, 10, 5) #元组类型
>>> a, b, c = fact(10, 5)

3、局部变量和全局变量
局部变量:是函数内部使用的变量,仅在函数内部使用
全局变量:整个程序中都在使用的变量

使用规则:
局部变量和全局变量是不同的变量:对于基本的数据类型,无论重名与否,两者就是不同的变量。函数运算结束后其内部的局部变量被释放,可以使用global在函数内部使用全局变量。

n, s = 10, 100
def fact(n):
	s = 1
	for i in range(1, n+1):
		s *= i
	return s
print(fact(n), s)
>>>
3628800 100

n, s = 10, 100
def fact(n):
	global s
	for i in range(1, n+1):
		s *= i
	return s
print(fact(n), s)
>>>
3628800 3628800

局部变量如果是组合数据类型而且未在函数内部创建,它等同于全局变量。

ls = ["F", "f"] #创建列表
def func(a):
	ls.append(a)
	returen
func("C")
print(ls)
>>>
["F", "f", "C"]

ls = ["F", "f"] #创建列表
def func(a):
	ls = []
	ls.append(a)
	returen
func("C")
print(ls)
>>>
["F", "f"] 

4、lambda函数
lambda函数返回函数名作为结果,是一种匿名函数,仅用于定义简单的、能够在一行内表示的函数。谨慎使用,主要用作一些特定函数或者方法的参数,还有一些固定的使用方式。

<函数名> = lambda<参数>: <表达式>

>>> f = lambda x, y : x + y
>>> f(10, 15)
25

>>> f = lambda : "调用成功"
>>> print(f())
调用成功

示例

#七段数码管绘制
'''问题拆解:
首先应该学会绘制一条线,
接着就可以绘制七条线,
然后如何组合得到数字显示,
最后如何获取时间并且将它显示出来。'''
import turtle
import time

def drawGap():#希望数码管之间有一定的间隔
	turtle.penup()
	turtle.fd(5)

def drawLine(draw): #绘制单段数码管
	drawGap()
	turtle.pendown() if draw else turtle.penup()
	turtle.fd(40) 
	drawGap()
	turtle.right(90)

def drawDigit(digit):#根据数字绘制七段数目管
#核心思想是拆分每一个笔被那些数字需要,需要时落下画线,不需要时抬起画笔
	drawLine(True) if digit in [2, 3, 4, 5, 6, 8, 9] else drawLine(False)
	drawLine(True) if digit in [0,1,3,4,5,6,7,8,9] else drawLine(False)
	drawLine(True) if digit in [0,2,3,5,6,8,9] else drawLine(False)
	drawLine(True) if digit in [0,2,6,8] else drawLine(False)
	turtle.left(90)
	drawLine(True) if digit in [0,4,5,6,8,9] else drawLine(False)
	drawLine(True) if digit in [0,2,3,5,6,7,8,9] else drawLine(False)
	drawLine(True) if digit in [0,1,2,3,4,7,8,9] else drawLine(False)
	turtle.left(180)
	turtle.penup()
	turtle.fd(20)#为后续数字确定位置

def drawDate(data):
#做出约定标记年月日 例如 %Y-%m*%d&
	turtle.pencolor("red")#规定年份颜色
	for i in data:
		if i == '-'
			turtle.write('年', font=("Arial", 18, "normal"))
			turtle.pencolor("green")#规定月份颜色
			turtle.fd(40)
		elif i == '*'
			turtle.write('月', font=("Arial", 18, "normal"))
			turtle.pencolor("blue")#规定日期颜色
			turtle.fd(40)
		elif i == '&'
			turtle.write('日', font=("Arial", 18, "normal"))
		else:
			drawDigit(eval(i))

def main():
	turtel.setup(800, 350, 200, 200)
	turtel.penup()
	turtle.fd(-300)
	turtle.pensize(5)
	drawDate(time.strftime('%Y-%m*%d&', time.gmtime())) #获得时间并格式化
	turtle.hideturtle()
	turtle.done()
main()

代码复用和函数递归

把代码当成资源进行抽象:
代码资源化:程序代码是一种用来表达计算的“资源”
代码抽象化:使用函数等方法对代码赋予更高级别的定义
代码复用:同一段代码在需要的时候可以被重复使用,一般使用函数或者对象实现代码复用,函数在代码层面建立了初步抽象,而对象则是在函数之上再次进行组织进行抽象。

模块化设计的核心思想是分而治之,也就是通过函数或者对象封装将程序分为模块以及模块间的表达,包括主程序、子程序和子程序之间的关系。
紧耦合:两个部分之间的交流很多,无法独立存在
松耦合:两个部分之间的交流很少,可以独立存在
函数之间的参数和返回值就是程序与程序之间的交流通道。这样的交流通道越清晰,代码就越容易被复用。所以我们希望模块内部紧耦合,模块之间松耦合。

函数递归:在函数设计中调用函数自身的方式。递归有两个关键的特征:
链条:计算过程中存在递归链条
基例:存在一个或者多个不需要再次递归的基例(基础的实例)

实现递归需要结合函数和分支语句,递归本身是一个函数,需要函数定义方式描述;在函数内部,需要利用分支语句判断输入参数是否属于基例。

#计算n的阶乘
def fact(n):
	if n == 0
		return 1
	else:
		return n*fact(n-1)
#字符串反转:将字符串s反转后输出
>>> s[::-1]

def rvs(s):
	if s == "":
		return s
	else:
		return rvs(s[1:]+s[0])

#费布拉切数列
def F(n):
	if n == 1 or n == 2:
		return 1
	else:
		return F(n-1) + F(n-2)

#汉诺塔问题
count = 0
def hanoi(n, src, dst, mid):
	global count
	if n == 1 #如果只有一个圆盘
		print("{}:{}->{}".format(1, src, dst))#直接将1号圆盘从起始搬运到目标
		count += 1
	else:
	#假设我们将n-1个圆盘搬运到中间圆盘,就能将最后一个圆盘搬运到目标圆盘
		hanoi(n-1, src, mid, dst)
		print("{}:{}->{}".format(n, src, dst))
		count += 1
		hanoi(n-1, mid, dst, src)

示例

#科赫雪花
'''
用于分形的曲线,本身就是迭代过程。
'''
#KochDrawV1.py
import turtle
def koch(size, n):
	if n == 0:
		turtle.fd(size)#n=0则绘制直线
	else:
		for angle in [0, 60, -120, 60]:
			turtle.left(angle)
			koch(size/3, n-1)
def main():
	turtle.setup(600, 600)
	turtle.penup()
	turtle.goto(-200, 100)
	turtle.pendown()
	turtle.pensize(2)
	level = 3
	koch(400, level)
	turtle.right(120)
	koch(400, level)
	turtle.right(120)
	koch(400, level)
	turtle.hideturtle()
main()	

打包小程序形成可执行文件:打开cmd

pyinstaller -i curve.ico -F KochDrawV1.py

附-PyInstaller库

将.py源代码转换成无需源代码的可执行文件。他是一个第三方库,需要额外安装(http://www.pyinstaller.org)

安装:打开cmd,执行 pip install pyinstaller

使用:
在源代码所在目录,通过cmd(windows的命令行)执行pyinstaller -F <文件名.py>。完成后会生成三个文件夹,dist中有同名exe文件。

常用参数:

参数描述
-h查看帮助
–clean清理打包过程中的临时文件
-D, --onedir默认值,生成dist文件夹
-F, --onefile在dist文件夹中只生成独立的打包文件
-i<图标文件名.ico>指定打包程序使用的图标(icon)文件
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值