《金哥百变Python零基础教程4》~函数与模块

本章知识点 :> 函数与模块

  • 预告:我们将用 函数 来优化地铁问题!

在编程的语境下,”函数“ 这个词的意思是对一系列语句的组合,这些语句共同完成一种运算   。 在上一章中,有一个 运算 , 求绝对值算法

a = -1
jueduizhi = a
if a < 0:
    jueduizhi = -a

其实,系统已经提供了 绝对值算法绝对值函数)

a = -1
jueduizhi = abs(a)

试一下 在线Python

abs(变量) 就是求变量绝对值的函数,上面两种写法的效果是一样的。(思考:abs() 函数实现的语句是如何的?思路跟我们自己写应该一样吧。)

print

  • print len str 这几个运算(函数) 还记得吗?

  • 除了 + - * / 这些符号运算之外的,用 print 这样的一个字母命名的 运算 都是 函数
  • print 是这个函数的名字 (函数名)
  • print(s) 我们用 函数名(变量) (两个括号包含要运算的变量) 的语法来 调用 函数,调用 意思其实就是运算
  • abs(a) 语法也一样

  • 易错点:函数的参数(参与运算的变量) 并非只能是一个
  • 比如 : print("a", "bc", 123)
  • 这样的写法是可以的哦,具体函数要多少个参数(参与运算的变量)呢,每一个函数不一样(正如每个运算不一样)
    试一下 在线Python

数学函数

现在我们就用 函数 这个词来表示这种运算了,反正我们理解 函数 就是能做计算的,但不是 + - * / 这类单符号运算。

  • 函数的能力非常强大。
  • 一组相关函数往往会放到一起,组成一个 模块, 比如数学相关函数,都放到 math 模块下
  • math 有哪些函数呢?你能想到的数学相关函数都有!
  • 要用数据函数,需要先import math 引入模块

  • import math
    #然后才能调用数学函数
  • 随机相关的函数 import random

  • 系统相关的函数(文件等等) import os

  • 网络请求相关函数 import requests

  • 机器学习相关函数 import sklearn

  • 我之所以要在这写下一堆的 import 但一个具体函数也不写,其实就是为了表达, 函数 是非常强大的!

  • 挑几个数学函数看一看
  • 1 x的y次方,即x**y
  • import math
    math.pow(3,4)
  • 2 求x的平方根
  • import math
    math.sqrt(100)

    试一下 在线Python

  • 易错点:import math 只要在文件开头写一遍,不用每次调用都写一个import
  • 易错点:有没有注意到 math.pow() 中间有个点 ,表示 模块.函数, 调用模块下的函数不要忘记模块名
    • print len 等函数不需要写模块名
  • 易错点:如果我看到代码里写了一个函数, 但不知道作用怎么办?(比如:math.ldexp(5,5))
    • 请百度:”python 函数名“python math.ldexp)


      image.png

    • 函数很多很多,不认识非常正常!

随机函数

  • 函数 让我们的能力无限扩展
  • 随机 是一类非常重要的函数。

image.png

  • 比如游戏里的 发牌操作
  • 比如抽奖公平性
  • 再比如:用随机决定今天谁请客。

import random
a = random.randint(0,10)

  • randint(a,b) 产生一个 这样将会产生一个a到b之间(包括a和b)的随机整数

    试一下 在线Python

  • 今晚谁请客怎么实现,假设宿舍有5个人,编号1,2,3,4,5

    import random
    a = random.randint(1,5)
    print(str(a) + ’请客‘)

    试一下 在线Python

    易错点:函数(参数1,参数2) 参数请用逗号隔开)

时间函数

image.png

  • 时间类的函数也非常常用,它们在 time 模块下 import time

  • 时间戳函数 t = time.time()

  • 返回当前时间的时间戳(1970纪元后经过的浮点秒数)。
  • 时间戳的意思就是 1970年1月1号0点0分0秒 到当前经过的秒数
  • 所以,每次调用time.time()得到的数值不一样(赶紧试下)
    试一下 在线Python

  • 年月日时间

t = time.time()
t1 = time.localtime(t)
#time.struct_time(tm_year=2016, tm_mon=11, tm_mday=30, tm_hour=14, tm_min=12, tm_sec=49, tm_wday=2, tm_yday=335, tm_isdst=0)

year = t1.tm_year
month = t1.tm.mon

易错点:注意t1 和 tm_year之间的点,这个点表示的是 t1 结构下的 tm_year(先学会这么用,后面细讲 )
试一下 在线Python

  • 非常有意思的 sleep函数 time.sleep(1)

  • 调用time.sleep(1) 会让程序睡1s;(就是停1s再运行下面的语句)

  • 比如:

  • t = time.time()
    print(t)
    t = time.time()
    print(t)
  • 这个程序,很大概率输出的t是同一秒的时间戳

  • 但是:
  • t = time.time()
    print(t)
    time.sleep(1)
    t = time.time()
    print(t)
  • 这个程序,肯定会输出2个时间戳(休息了1s)
    试一下 在线Python

如果定义自己的函数

  • 现在讲比较难的部分:自定义函数
  • 自定义函数 是相对于上面文章里的 print abs math.pow time.time random.randint 等等的系统函数的
  • 自定义函数 就是我们自己把某种 自己的运算 定义成一个自己的函数 (有函数名)
  • 还记得 代码块 吗?

  • 在1-4章里所有 代码块 都是特定的功能代码(不就是运算吗), 比如: ...
    ...
    #代码块
    ...
    #代码块
    ...

  • 有这种情况吧, 其实所有代码块都可以写成自定义函数

  • 语法:

image.png

  • 需要解释一下
  • def(其实就是英文define定义的缩写),表示定义一个函数
  • 函数名不用说了,就是这个函数的名字
  • 参数 ,对应的其实就是 代码块输入
  • return 返回值 ;这里的 返回值 其实就是 代码块输出

  • 举栗子更好:(定义一个自己的abs函数 [绝对值])

  • def my_abs(a):
        jueduizhi = a
        if a < 0:
            jueduizhi = -a
        return jueduizhi
  • 易错点:def后面要空格

  • 易错点:def最后要:冒号
  • 易错点:函数体(就是实现运算的部分),要缩进(4个空格)
  • 易错点:注意这个函数的return,是return计算完的绝对值

  • 现在来调用这个自己的函数my_abs ;

  • a = -1
    print(my_abs(a))
    a = 1
    print(my_abs(a))


    试一下 在线Python
  • 一定要自己在线运行一下。

  • 如果 代码块 就是计算绝对值的,那么刚开始的例子可以改成 ...
    ...
    my_abs(a)
    ...
    my_abs(a)
    ...
  • 想一下,原来用代码块 和现在用函数调用,显然是函数调用更清晰,更不容易出错。

  • 现在我们定义一个sayhello 函数, 我们来看看另外几个易错点

def sayhello():
    print('hello world')

sayhello()

试一下 在线Python

  • 思考一下,这个代码运行结果再屏幕输出几个 ’hello world' (答案是1个)
  • 易错点:注意如果函数只是def 定义,它是不会执行的
  • 改一下:

def sayhello():
    print('hello world')

试一下 在线Python

  • 易错点:只是def定义,不会输出任何东西,函数只有调用是才会执行

  • 再改一下:

def sayhello():
    print('hello world')

sayhello()
sayhello()

试一下 在线Python

  • 这个例子会输出两个 'hello world'
  • 函数只有多次调用才体现出它的用处(复用)

  • 现在思考一下:sayhello 函数的输出是什么?(返回值是什么)

  • def sayhello():
        print('hello world')
    s = sayhello()
    print(s)

    试一下 在线Python
  • 易错点:这个不会输出两个 ‘hello world’ 也不是输出一个 ‘hello world';而是输出 ‘hello world' ’None' 为什么?

  • 当执行 s = sayhello() 的时候,会执行sayhello 里的运算,其实就是输出 ‘hello world'
  • 接着,sayhello没有返回值对吧,那就会默认返回 None (None 是python里的一种数据,后面细讲)
  • 现在 变量 s 等于这个返回值 None,于是print(s) 会打印输出 'None'

  • 我们改一下:

  • def sayhello():
        return 'hello world'
    s = sayhello()
    print(s)

    试一下 在线Python
  • 思考一下:输出什么?(答案:‘hello world')

  • 因为这回 sayhello 没有任何print打印,但是它返回了字符串 ’hello world'
  • 执行 s = sayhello() 的时候,s就等于了 ’hello world'

如果没有完全理解没有关系,后面每一章都在复习 函数

综合运用

其实没有什么综合运用,就是把上一章的地铁2号线代码,用自定义函数实现一次!

地铁2号线

  • 问题:请为地铁2号线,编写问路程序 (要求指出最优路线)
  • 我们为每一个站点写了编号,”前门“ 1号”崇文门“ 2号 ...

  • 思路:先取名 环线最优路径算法
  • 输入:start end 输出 fangxiang zou_num
  • 代码块 定义成函数:

def huanxian(start_num, end_num):
    fangxiang = ''
    zou_num = 0
    #待实现
    return (fangxiang,zou_num) #可以同时返回两个变量哦~

  • ”当前站回答法"

def say_dangqian():
    print("现在出站")

  • "问路回答法"

    def huida(fangxiang, zou_num):
        #待实现

  • 现在来写主程序( 特别短,很好读)

start = '?' #具体执行时填写
start_num = ? #具体执行时填写
end = '?' #具体执行时填写
end_num = ? #具体执行时填写
fangxiang = ''
zou_num = 0
if start_num == end_num:
    say_dangqian()
(fangxiang,zou_num) = huanxian(start_num, end_num)
huida(fangxiang, zou_num)


  • 实现以下回答算法

  • def huida(fangxiang, zou_num):
        #待实现
        a = 0
        while a < zou_num:
            print(fangxiang+'走1站') #一定要4个空格
            a = a + 1
  • 实现以下环线算法(中间用到abs函数)

  • def huanxian(start_num, end_num):
        fangxiang = ''
        zou_num = 0
        #环线最优路径算法
        default = end_num - start_num #默认
        jueduizhi = abs(default) #默认绝对值
        duiying = 18 - jueduizhi #对应的绝对值
        if default > 0:
            duiying = -duiying #反方向

        j1 = abs(default)
        j2 = abs(duiying)
        zuiyou = 0
         if j1 < j2:
            zuiyou = default
        if j2 < j1:
            zuiyou = duiying

        if zuiyou > 0:
            fangxiang = '右'
            zou_num = zuiyou
        if zuiyou < 0:
            angxiang = '左'
            zou_num = -zuiyou
        return (fangxiang, zou_num)

    试一下 在线Python

  • 易错点:一定要注意,在函数里要定义自己的变量如 fangxiang zou_num
  • 因为函数内的变量和外面是不同的范围(现在不好解释,后面再细讲)

下一章会先复习 函数 的知识,不用担心现在没有完全理解~

p4 知识点总结:

image.png

Sorry but the SQLBolt exercises require a more recent browser to run.
Please upgrade to the latest version of Internet Explorer, Chrome, or Firefox!

Otherwise, continue to the next lesson: SQL Lesson 2: Queries with constraints (Pt. 1)
Python小机器人嘴巴会打印东西,还可以拖动
练习 do it — 请完成如下任务
我不会做求助!求助!

继续努力 学下一节