Python学习(四)

python函数与代码的复用

掌握python函数的使用方法
编写带有函数和复用代码的程序

函数的定义与使用

函数的理解与定义

函数指带有特定功能的语句组。
降低编程的难度同时可以对函数进行复用。
函数就是一个完整的IPO类型的代码块。只定义函数代码并不会执行,只有调用了函数代码才会被执行。

def<函数名>(参数表):
	<代码块>
	return <返回值>

函数的使用及调用过程

调用特指运行函数。
调用的过程即将给定参数替换形式参数,然后执行函数体的内容,最后返回返回值。

def fact(x):
	s = 1;
	for i in range(1,x+1):
		s*=i
	return s
a = fact(10)

以上例说明,使用fact时调用其函数,然后把10赋值给x执行代码块内容,最后返回值s赋值给a,这就是函数的执行过程。

函数的参数传递

函数可以有也可以没有参数,但是无论有没有都有括号。
函数的参数也有许多种。
1.可选参数传递
可选参数即可以指定默认值的参数,调用时可以不给,那么使用默认值,默认参数必须放在必选参数之后。

def fact(x,m=1):	#不给m时,则默认m为1
	s = 1;
	for i in range(1,x+1):
		s*=i
	return s//m 

2.可变参数传递
可变参数指的是参数的个数是不确定的参数,使用*<参数名>的方式进行定义。

def fact(x,*b):	#不给m时,则默认m为1
	s = 1;
	for i in range(1,x+1):
		s*=i
	for item in b:
		s*=item
	return s
a = fact(10,3)
a = fact(10,3,5,8)	#参数可以是多个

3.参数传递的两种方式
可以使用位置对应fact(5, 10)或者名字对应fact(m=5, n=10)两种方式来传递参数。

函数的返回值

函数可以使用return来返回值,但是也可以不返回值。同样也可以返回多个值。

def fact(x,m=1):	#不给m时,则默认m为1
	s = 1;
	for i in range(1,x+1):
		s*=i
	return s//m, x, m
a, b, c = fact(10)  #用元组返回(s//m, x, m)

局部变量和全局变量

局部变量就是在函数内部使用的变量,全局变量就是在整个程序中使用的变量。
在使用过程中,需要遵循一些规则。
1.局部变量和全局变量是不同的变量
局部变量可以和全局变量重名,但是他们本质上还是不同的,同时局部变量在函数调用结束后自动就被释放了。在函数中可以使用global来使用全局变量。

n = 1,s = 10
def fact(x,m=1):	#不给m时,则默认m为1
	global s = 1;
	for i in range(1,x+1):
		s*=i
	return s//m, x, m
print(fact(n), s)  #这里的s不再是10了,已经在函数内被修改了。

2.局部变量如果是组合数据类型,且未在内部创建,则等同于全局变量

ls = ['F','f']
def f(x):
	ls.append(x)	#内部没有创建ls
	return
f('C')
print(ls)
#>>>F,f,C

lambda函数

lambda函数是一种特殊的函数。
可以用来定义只有一行代码的函数其返回值就是函数名。
在一些特殊情况下才会使用,一般不建议使用。

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

实例:七段数码管绘制

基本思路:绘制一个数字的数码管,绘制一串数字的数码管;获得系统时间来绘制数码管。

import turtle
import time
def drawGap():
    turtle.pu()
    turtle.fd(5)
def drawline(draw):
    drawGap()
    if draw:
        turtle.pd()
    else:
        turtle.pu()
    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.pu()
    turtle.left(180)
    turtle.fd(20)

def drawdate(date):
    for i in date:
        if i=="-":
            turtle.write("年",font=("Arial",18,"normal"))
            turtle.color("green")
            turtle.penup()
            turtle.fd(40)
        elif i=="=":
            turtle.write("月",font=("Arial",18,"normal"))
            turtle.color("blue")
            turtle.penup()
            turtle.fd(40)            
        elif i=="+":
            turtle.write("日",font=("Arial",18,"normal"))
        else:
            drawdigit(eval(i))

def main():
    turtle.setup(800, 350, 200, 200)
    turtle.pensize(5)
    turtle.pu()
    turtle.fd(-300)
    turtle.color("red")
    date = time.strftime("%Y-%m=%d+",time.gmtime())
    drawdate(date)
    turtle.hideturtle()
    turtle.done()
    
main()

模块化思维:将每个功能写好,然后进行封装,再去调用
规则化思维:把绘制数变成统一的一类规则,从而进行标准化

代码的复用与函数的递归

代码复用与模块化思想。同时理解递归。

代码复用与模块化设计

函数和对象是代码复用的两种形式。
函数在代码层面进行了初步抽象,对象则是更高级的抽象,对象统合了函数和属性。
模块化设计:将想要实现的功能分为不同的模块,分而治之。
紧耦合:代码之间联系紧密,无法独立存在。
松耦合:代码之间联系宽松,可以独立存在。
函数之间期待松耦合,内部应该紧耦合。

函数递归的理解

在函数中调用自身即为递归。
递归过程中有两个重要的特性,链条和基例。
链条:计算过程中的递归链条
基例:存在一个或多个不需要继续递归的基例

递归的实现

递归本身是一个函数,需要调用自身;
分支语句:递归需要区分是否到达了基例。
在调用的时候,会不断地开辟新的内存,然后在新的内存中去执行函数,直到函数结束。如果在执行中遇到新的函数,那么就会继续开辟新的内存继续去执行。

def fact(n):
	if n==0:
		return 1
	else:
		return n*fact(n-1)

递归的实例解析

1.字符串的反转
显然[:-1]倒序遍历就可以实现,但是这里需要考虑新的方法。
分析:基例,当字符串为空的时候返回自身;链条,字符串非空时,将首字符放最后。

def reverse(s):
    if s =='':
        return s
    else:
        return reverse(s[1:])+s[0]

2斐波那契数列
当n为1或者2是值为1,否则为前两项之和。

def Fibonacci(n):
	if n==1 or n==2:
		return 1
	else:
		return Fibonacci(n-1)+Fibonaccit(n-2)

3.汉诺塔问题
典型的,类似于数学归纳法,解决n规模的问题需要先解决n-1规模的问题。

count = 0
def hanoi(n, src, dst, mid):
    global count
    if n==1:
        print("{}:->{}".format(n, src, dst))
        count = count+1
    else:
        hanoi(n-1, src, mid, dst)#要先把n-1个块移到中间
        print("{}:->{}".format(n, src, dst))
        count = count+1
        hanoi(n-1, mid, dst, src)#要把n-1个块移到dst

hanoi(3, 'A', 'B', 'C')
print(count)

Pyinstall库的使用

Pyinstaller是一个第三方库,用于把文件源代码打包为可执行文件。
主要参数

参数 作用
-h 查看帮助文件
--clean 清理打包时的临时文件
-d 默认值,生成dist文件夹
-F 在dist文件夹中只生成独立的打包文件
-i 在打包文件中使用指定的图标文件(icon)
例如: pyinstaller -i curve.ico -F sevendigittube.py
图标文件必须是ico类型的文件

实例:科赫雪花小包裹

科赫雪花:科赫雪花是一种分形图形,即一种迭代的几何图形,它广泛存在于自然界中。
科赫曲线:取一段直线,三等分,将中间部分变为一个等边三角形的突起部分,这就完成了一阶的科赫曲线。可以对其中的直线部分继续进行分割,从而得到更高阶的科赫曲线。

import turtle
def koch(n, lenth):
    if n==0:
        turtle.fd(lenth)
    else:
        koch(n-1, lenth/3)
        turtle.left(60)
        koch(n-1, lenth/3)
        turtle.right(120)
        koch(n-1, lenth/3)
        turtle.left(60)
        koch(n-1, lenth/3)
def main():
    turtle.setup(600, 600)
    turtle.pensize(2)
    turtle.pu()
    turtle.goto(-200, 100)
    turtle.pd()
    turtle.hideturtle()    
    koch(3, 400)
    turtle.right(120)
    koch(3, 400)
    turtle.right(120)
    koch(3, 400)

main()

课后习题

1.任意累积

# 请在...补充一行或多行代码
def cmul(*num):
    mul = 1
    for i in num:
        mul*= i
    return mul

print(eval("cmul({})".format(input())))

注意,这一题考察了一个非定长输入问题。
2.斐波那契数列

# 请在...补充一行或多行代码

def fbi(n):
    if n==1 or n==2:
        return 1
    else:
        return fbi(n-1)+fbi(n-2)

n = eval(input())
print(fbi(n))

3.汉诺塔问题

# 请在...补充一行或多行代码
steps = 0
def hanoi(src, des, mid, n):
    global steps
    if n == 1:
        steps+=1
        print("[STEP{:>4}] {}->{}".format(steps, src, des))
    else:
        hanoi(src, mid, des, n-1)
        steps+=1
        print("[STEP{:>4}] {}->{}".format(steps, src, des))
        hanoi(mid, des, src, n-1)

N = eval(input())
hanoi("A", "C", "B", N)

以上内容为学习嵩天老师的python语言程序设计第五周内容的笔记。感谢嵩天老师的团队给我们带来这样优质的课程。

中国大学生MOOC《Python语言程序设计》,嵩天 、黄天羽 、礼欣

posted @ 2021-04-08 15:46  黑衣の甘铃儿  阅读(261)  评论(0)    收藏  举报