为什么需要函数?

先使用目前的知识点实现一个需求:

    """
三个功能
  1.登录
  2.购物车
  3.收藏夹
   
  收藏夹和 购物车 需要先登录才能使用!
  """
# 表示当前用户
current_user = None
while True:
   print("""
  1.登录
  2.购物车
  3.收藏夹
  """)

   choice = input("请选择功能:").strip()

   if choice == "1":
       print("登录!")
       name = input("name:").strip()
       pwd = input("pwd:").strip()
       with open("user.txt",encoding="utf-8") as f:
           for line in f:
               ls = line.split("|")
               if ls[0] == name and ls[1] == pwd:
                   print("登录成功!")
                   current_user = ls[0]
                   break
           else:
               print("用户名或密码不正确!")


   elif choice == "2":
       print("购物车")
       # 判断是已经登录过了
       # print(current_user)
       if not current_user:
           print("请先登录!")
           name = input("name:").strip()
           pwd = input("pwd:").strip()
           with open("user.txt", encoding="utf-8") as f:
               for line in f:
                   ls = line.split("|")
                   if ls[0] == name and ls[1] == pwd:
                       print("登录成功!")
                       current_user = ls[0]
                       break
               else:
                   print("用户名或密码不正确!")
       else:

           with open("购物车.txt",encoding="utf-8") as f:
               print("你购买了 <<%s>>" % f.read())
   elif choice == "3":
       print("收藏夹")
       if not current_user:
           print("请先登录!")
           name = input("name:").strip()
           pwd = input("pwd:").strip()
           with open("user.txt", encoding="utf-8") as f:
               for line in f:
                   ls = line.split("|")
                   if ls[0] == name and ls[1] == pwd:
                       print("登录成功!")
                       current_user = ls[0]
                       break
               else:
                   print("用户名或密码不正确!")
       else:
           with open("收藏夹.txt",encoding="utf-8") as f:
               print("你收藏了了 <<%s>>" % f.read())
   else:
       print("输入错误")

目前程序中存在的问题:

"""
1.代码的组织结构不清晰,可读性差
2.代码冗余度高
3.管理维护难度大,扩展性极差
"""

解决上述问题的方案就是函数

在生活中也有类似的场景

例如,安装网线时,电信公司会派一个安装师傅到你家来给你接通网线,通常这个安装师傅都会自带一个工具箱,到你家后打开工具箱就开始干活,要接网线拿一个网线钳,要测试网络就拿出电脑,试想一下,如果他不自己带上工具来,会是什么情况,要接网线还得一根一根线去接,要测试网络还得用舌头舔一舔!就像程序里面每次登陆都要把一堆代码重写一遍!

什么是函数?

函数是实现某个功能的代码的集合体,其具备一个名称即函数名,通过函数名就可以访问到函数,并执行内部的代码块

相当于现实生活中的工具,例如扳手,当我们需要拧螺丝时拿出扳手就能很方便的搞定!

需要强调的是:要想使用扳手,则必须先制造扳手。

同理:要想使用函数,则必须先定义函数

所以使用函数时必须遵循 先定义,再调用

定义函数

语法:

def 函数名称(参数1,参数2...):
   """
  文档注释
  可以被help函数提取
  """
   代码1
   代码2
   代码n
   return 值

def:定义函数得关键字

函数名:用于 查找/调用 函数,函数名必须能够体现函数所实现的功能,函数名也是名字,与变量名一样,需遵循命名规范,并且都是用来绑定内存地址

文档注释:用于描述该函数的详细信息,可以被help函数提取

代码块:称之为函数体,即函数功能的具体实现代码

return:函数的返回值

#需求:打印如下内容
"hello world!"
"hello world!"
"hello world!"
# 1.定义阶段
def print_hello_world():
  for i in range(3):
   print("hello word!")
# 2.调用阶段
#print(print_hello_world)
print_hello_world()#
print_hello_world()

函数的三种类型

1.无参函数

当函数体代码的执行不需要依赖外部的传入数据时

# 需求 输出python的描述信息
def print_py_info(): # 不需要依赖任何外部的值
print("==================)
   print("python is good language!")
   print("==================)
print_py_info() # 定义时没有参数 调用时也不需要且不能传参数
#print_py_info(1) #报错

# 需求2 接收用户名和 密码
def input_user_info():
name = input("name:").strip()
   pwd = input("password:").strip() print(name,pwd)

2.有参函数

当函数体的代码逻辑需要依赖外部传如入数据时

#需求 比较两个数的大小    
def max_two(a,b):
   if a > b:
print(a)
   else:
       print(b)
#需求2 求列表中最大值
def max_list(li):
   max = li[0]
   for i in li:
       if i > max:
      max = i
   print(max)
# 需求2 实现登录

不要为了定义函数而定义函数,当程序代码结构混乱时就必须要拆分到不同函数中,减少代码冗余,提高维护性扩展性,使代码结构更清晰

一个函数的功能应该尽可能的独立完整,例如接收输入就干接收输入,验证用户就干验证用户,读取文件就干读取文件

生活中一个的反例就是多功能折叠刀

3.空函数

函数中只有pass时就是空函数,pass表示略过,什么也不干

def func():
pass
func()# 什么也不干

调用空函数是没有任何意义的,空函数仅用于编写程序初期定义程序结构

正常开发中在拿到一个项目时不是立即开始编写代码,而是先分析项目具备哪些功能,将功能列表先定义出来,这时就可以用空函数了,例如要实现,购物车项目

def login():
   """
  这是登录功能
  """
   pass
def register():
   """
  这是注册功能
  """
pass
def shop_car():
   """
  这是购物功能
  """
   pass

定义阶段与调用阶段

定义阶段发生的事情:

  1. 申请内存空间存储函数体代码

  2. 将内存地址与函数名称进行绑定

需要注意的是,函数的定义阶段不会执行函数体代码,但是会检测语法

def print_hello_world(): # print_hello_world = <function print_hello_world at 0x1047efe18>
   abcdassaas
   1 / 0
   print(100)
   for i in range(3):
       print("hello world!")
a = 10
print(a)
# 正常秩序不报错

调用阶段发生的事情:

  1. 通过名称找到函数的内存地址

  2. 加括号触发函数体代码的执行

函数的调用

函数的使用必须遵循先定义,后调用

常见错误

案例1:

func()# 报错:NameError: name 'func' is not defined
def func():
   print("func run!")
# 违反了先定义后调用

案例2:

def func1():
   print("func1 run")
   func2()
func1() #报错:NameError: name 'func2' is not defined
def func2():
   print("func2 run")

# 代码自上而下 顺序执行
# func2的定义还没有执行到,就在调用func1时被调用了,不报错是pycharm检测到文件中的确有func2函数,但是pycharm是无法检测代码执行顺序的
   
# 正确写法
def func1():
   print("func1 run")
func2()
def func2():
   print("func2 run")
func1()

三种调用方式

# 直接调用
def func():
   print(1)
func()
# 表达式中调用
def max(a,b):
   if a > b:
       return a
   else:
       return b
print(max(1,2) * 10)
# 将函数得返回值作为参数
print(max(10,max(20,30)))

函数的返回值

在函数体中使用return关键字来返回值给调用者

当一个功能的执行会产生一个明确的值时,需要使用返回值

案例1:制作面包的机器,需要一堆面粉作为参数,制作完的面包要返回给使用者

def make_bread(mf):
   print("揉",mf)
   print("烤",mf)
   print("烤完了")
   return "金黄的大面包!"
res = make_bread("面粉")
print(res)

案例2:获取列表的平均值

def max_list(li):
   max = li[0]
   for i in li:
       if i > max:
      max = i
   return max
res = max_list([1,23,4,12,12,1212])

其他用法

1.返回多个值

会把多个值打包成元组类型

def func():
   return 1,2,3
res = func()
print(res)
# 小技巧
# 对返回值进行解压
a,b,c = func()
2.返回空(None)

仅有一个return关键字

def func():
   return
res = func()
print(res)

# 需要注意的是 如果函数中没有出现return关键字,默认返回None
def func2():
1 + 1
res = func2()
print(res)
3.多个return

函数中出现了多个return关键字

def func():
   print(1)
   return 1
   print(2)
   return 2
func()

可以发现无论有几个return都只有一个会执行

只要函数执行时遇到了return立即结束函数执行,无论下面是否有代码

基于这个特点,我们可以将之前的比较大小进行改写

def max(a,b):
   if a > b:
       return a
   return b
print(max(10,20))

最后改造之前写的练习

def login():
   name = input("name:").strip()
   pwd = input("pwd:").strip()
   with open("user.txt", encoding="utf-8") as f:
       for line in f:
           ls = line.split("|")
           if ls[0] == name and ls[1] == pwd:
               print("登录成功!")
               return ls[0]
       else:
           print("用户名或密码不正确!")

def read_file(file):
   with open(file, encoding="utf-8") as f:
       return f.read()

# 表示当前用户
current_user = None

while True:
   print("""
  1.登录
  2.购物车
  3.收藏夹
  """)

   choice = input("请选择功能:").strip()

   if choice == "1":
       print("登录!")
       current_user = login()

   elif choice == "2":
       print("购物车")
       # 判断是已经登录过了
       # print(current_user)
       if not current_user:
           current_user = login()
       else:
           print("你购买了 <<%s>>" % read_file("购物车.txt"))
   elif choice == "3":
       print("收藏夹")
       if not current_user:
           print("请先登录!")
           current_user = login()
       else:
           print("你收藏了了 <<%s>>" % read_file("收藏夹.txt"))
   else:
       print("输入错误")

day10 函数2的更多相关文章

  1. day10.函数进阶

    函数的命名空间 从python解释器开始执行之后,就在内存中开辟了一个空间,每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来. 但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存, ...

  2. day10函数作业详解

    1.day10题目 2,写函数,接收n个数字,求这些参数数字的和.(动态传参) 3,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么? a=10 b=20 def test5(a,b): ...

  3. python全栈学习--day10(函数进阶)

    一,引言 现在我有个问题,函数里面的变量,在函数外面能直接引用么? def func1(): m = 1 print(m) print(m) #这行报的错 报错了:NameError: name 'm ...

  4. day10 函数的定义及函数语法详解

    """ 今日内容: (1)函数的定义及特点 (2)函数的语法及函数的四部分 (3)函数的分类 (4)函数的调用 (5)函数的return详解 一.函数的定义 1.什么是函 ...

  5. DAY10函数

    函数 函数就是可以重复利用的工具 函数可以完成指定代码块,函数就是是存放代码块的容器 函数的有点: 1.避免出现重复冗余的代码 2.让程序代码结构更清晰增加可读性 3 定义函数的语法 1. 函数名:使 ...

  6. Python—day10 函数的参数分类

    一.实参与形参 1.形参:定义函数,在括号内声明的变量名,用来接受外界传来的值 def fn(形参们):                pass def fn(a,b,c):# 形参就是考虑实参的值, ...

  7. python学习day10 函数Ⅱ(参数&作用域)

    函数Ⅱ(参数&作用域) 知识小结: py2与py3的区别 逻辑运算()>not>and>or 字符串翻转切片翻转 is与==区别 git相关 数据类型判断 操作系统:cent ...

  8. day10函数,函数的使用,函数的分类,函数的返回值

    函数 # ***** # 函数:完成 特定 功能的代码块,作为一个整体,对其进行特定的命名,该名字就代表函数 # -- 现实中:很多问题要通过一些工具进行处理 => 可以将工具提前生产出来并命名 ...

  9. python学习Day10 函数的介绍(定义、组成、使用)

    今日学习内容: 1.什么是函数 :函数就是一个含有特定功能的变量,一个解决某问题的工具 函数的定义:通过关键字def + 功能名字():代码体(根据需求撰写代码逻辑) 2.为什么要用函数:可以复用:函 ...

  10. python day10 函数(第二篇)

    2019.4.10 S21 day10笔记总结 一.内容回顾 1.面试题相关: 1.py2和py3的区别 2.运算符的计算 :3 or 9 and 8 3.字符串的反转 4.is和==的区别 5.v1 ...

随机推荐

  1. Python文件打包成exe

    1. 安装pyinstaller pip install pyinstaller 2.如果有外部依赖包 将外部依赖包放到你的python安装的site-packages D:\Python27\Lib ...

  2. 实现两线程的同步二(lockSupport的park/unpark)

    1.使用LockSupport的part/unpark实现 package com.ares.thread; import java.util.concurrent.locks.LockSupport ...

  3. F - Auxiliary Set HDU - 5927 (dfs判断lca)

    题目链接: F - Auxiliary Set HDU - 5927 学习网址:https://blog.csdn.net/yiqzq/article/details/81952369题目大意一棵节点 ...

  4. poi读取Excel模板并修改模板内容与动态的增加行

    有时候我们可能遇到相当复杂的excel,比如表头的合并等操作,一种简单的方式就是直接代码合并(浪费时间),另一种就是写好模板,动态的向模板中增加行和修改指定单元格数据. 1.一个简单的根据模板shee ...

  5. Vue & webpack

    在webpack构建的项目中使用vue进行开发 在入口文件中 import Vue from 'vue' 导入的构造函数,功能不完整,只提供了runtime-only的方式,并没有提供网页中那样的使用 ...

  6. 20165231 2017-2018-2 《Java程序设计》第8周学习总结

    教材学习内容总结 进程与线程 程序是一段静态的代码,它是应用软件执行的蓝本. 进程是程序的一次动态执行过程,它对应了从代码加载.执行至执行完毕的一个完整过程,这个过程也是进程本身从产生.发展至消亡的过 ...

  7. 20165231 2017-2018-2 《Java程序设计》第4周学习总结

    教材学习内容总结 第五章 子类与父类: 所谓的子类,必须是一个类继承了另一个类,这个类才是子类:比如:public class A extend B这就是说A类继承了B类,那么A就是B的子类:B是A的 ...

  8. WinRAR代码执行漏洞CVE-2018-20250

    0x01 分析思路 利用https://github.com/googleprojectzero/winafl 漏洞分析框架模糊测试WinRAR. 几个存档格式的崩溃,例如RAR,LZH和ACE,这些 ...

  9. Linux网络 - 数据包的接收过程【转】

    转自:https://segmentfault.com/a/1190000008836467 本文将介绍在Linux系统中,数据包是如何一步一步从网卡传到进程手中的. 如果英文没有问题,强烈建议阅读后 ...

  10. python3+selenium入门13-操作cookie

    可以把cookie理解为自己账户的身份证.因为http协议是无状态的,上一个请求和下一个请求没有关系.但是有时需要有关联.比如登录之后,才能进行操作这样的设置.这个就是cookie在起作用.登录成功时 ...