Python系统学习1-8-函数

一、函数

1、定义函数

    ① 用于封装一个特定的功能,表示一个功能或者行为。

    ②  函数是可以重复执行的语句块 , 可以重复调用。

(1) 语法:
      def 函数名(形式参数):
          函数体
(2) 说明:
      def 关键字:全称是define,意为”定义”。
      函数名:对函数体中语句的描述,规则与变量名相同。
      形式参数:函数定义者要求调用者提供的信息。
      函数体:完成该功能的语句。
(3) 函数的第一行语句建议使用文档字符串描述函数的功能与参数。

2、调用函数

(1) 语法:函数名(实际参数)
(2) 说明:根据形参传递内容。

3、返回值

  (1) 定义:
      函数定义者告诉调用者的结果。
  (2) 语法:
      return 数据
  (3) 说明:
      return后没有语句,相当于返回 None。
      函数体没有return,相当于返回 None。
      return执行后,退出函数
      return可以退出函数中多层循环嵌套,其实是退出函数
      break 只能退出一层循环

     return 返回多个值,可以打包成列表,字典等,默认为元组。

def func01():
print("func01执行了")
return 100
# 1. 调用者,可以接收也可以不接收返回值
func01()
res = func01()
print(res)
# 2.在Python语言中,
# 函数没有return或return后面没有数据,
# 都相当于return None
def func02():
print("func02执行了")
return
res = func02()
print(res) # None
# 3.return可以退出函数
def func03():
print("func03执行了")
return
print("func03又执行了")
func03()
# 4. return 可以退出多层循环嵌套
def func04():
while True:
while True:
while True:
# break 只能退出一层循环
print("循环体")
return
func04()

4、函数内存图

注意
        (1)当函数名相同时,第二个函数会覆盖第一个函数。
                         不存在C++里的函数重载之类的说法
        (2)先定义所有函数,定义各个函数之间没有顺序,然后进行调用函数
        (3)函数名用动词
        (4)参数就是为了让函数体中的算法更灵活
        (5)return可以让结果保存在函数外部的变量中、

        (6)函数内部也可修改传入的可变数据(列表,字典)
                 无需return也能返回结果

                 使用形式:

                        def 函数名(参数):
                               参数[索引或切片] = 结果
                        列表名 = [数据]        
                        函数名(列表名)
                        print(列表名)

设计理念
            函数体崇尚小而精,拒绝大而全
                    获取数据
                    逻辑计算
                    显示结果
            建议:可以先写出大而全的功能,再重构小而全的代码

Python系统学习1-8-函数_第1张图片

Python系统学习1-8-函数_第2张图片

Python系统学习1-8-函数_第3张图片

5、函数变量作用域

作用域分类

        (1) Local局部作用域:函数内部。

        (2) Enclosing 外部嵌套作用域 :函数嵌套。

        (3) Global全局作用域:模块(.py文件)内部。

        (4) Builtin内置模块作用域:builtins.py文件。

在访问变量时,先查找本地变量,然后是包裹此函数外部的函数内部的变量,之后是全局变量,然后是内置变量。

①局部变量

        (1) 定义在函数内部的变量(形参也是局部变量)

        (2) 只能在函数内部使用

        (3) 调用函数时才被创建,函数结束后自动销毁

②全局变量

        (1) 定义在函数外部,模块内部的变量。

        (2) 在整个模块 (py 文件 ) 范围内访问(但函数内不能将其直接赋值)。
③global语句
        作用: 在函数内部修改全局变量; 在函数内部定义全局变量 ( 全局声明 )
        语法:global 变量 1, 变量 2, …
        说明: 在函数内直接为全局变量赋值,视为创建新的局部变量。
                    不能先声明局部的变量,再用 global 声明为全局变量。
函数内存图

Python系统学习1-8-函数_第4张图片

6、函数参数 

可变/不可变类型在传参时的区别
(1)不可变类型参数有 : 数值型( 整数,浮点 ) 、布尔值bool 、None 空值 、字符串str 、元组tuple
(2)可变类型参数有:列表list,字典dict
(3)传参说明:
                        不可变类型的数据传参时,函数内部不会改变原数据的值。
                        可变类型的数据传参时,函数内部可以改变原数据。
形参定义方式parameter
(1)默认形参,实参可选
                         def 函数名 ( 形参名 1= 默认值 1, 形参名 2= 默认值 2, ...):
                              函数体
       说明:默认参数必须自右至左依次存在,如果一个参数有默认值,则其右侧的所有参数都必须有默认值。
def func01(p1 =0, p2="", p3=100):
    print(p1)
    print(p2)
    print(p3)
func01(p2=2)
func01(p2=2,p3=3)
# 支持同时使用位置实参与关键字实参
func01(1,p3=3)
# 注意1:先位置实参,后关键字实参
# func01(p1 =1,2,3) # 错误
(2)位置形参,实参必填
                def 函数名( 形参名 1, 形参名 2, ...):
                        函数体 
# 位置形参,每个实参都是必填
def func01(p1,p2,p3):
    print(p1)
    print(p2)
    print(p3)
# 位置实参,实参中按照顺序与形参顺序之对应
func01(1, 2, 3)
# func01(1,2)  报错
# func01(1,2,3,4)  报错
(3)命名关键字形参
        def 函数名 (*args, 命名关键字形参 1, 命名关键字形参 2, ...):
                函数体
 
        def 函数名(*, 命名关键字形参 1, 命名关键字形参 2, ...):
                函数体
        说明: 强制实参使用关键字传参
# 命名关键字形参p2:要求实参必须是关键字实参
def func01(p1=0, *args, p2=0):
    print(p1,end=" ")
    print(args,end=" ")
    print(p2)
func01() # 不报错
func01(1,2)
func01(1,2,3)
func01(1,2,p2=3)
def func02(p1=0, *, p2=0):  # *不传参
    print(p1,end=" ")
    print(p2)
func02(p2=3)
func02(1,p2=3)
# func02(1,2,3,4,p2=1)  错误
# 因为end在*values后面,属于命名关键字形参
# 所以必须写上end
print("*", end=" ")
(4)星号元组形参
        def 函数名(*元组形参名):
                函数体
        作用:可以将多个位置实参合并为一个元组
        
        说明: 一般命名为 'args', 形参列表中最多只能有一个
# 位置实参数量可以无限
def func01(*args):
    print(args)
func01() # 空元组
func01(1, 2, 34) # (1, 2, 34)
# 不支持关键字实参
# func01(args = 1,a=1)
(5)双星号字典形参 
        def 函数名 (** 字典形参名 ):
                函数体  
        作用:可以将多个关键字实参合并为一个字典
        说明:  一般命名为 'kwargs', 形参列表中最多只能有一个
# 关键字实参数量无限
def func01(**kwargs):
    print(kwargs) # {'a': 1, 'b': 2}
func01(a=1,b=2)
# func01(1,2,3) # 报错
(6)形参自左向右的顺序

        位置形参 --> 星号元组形参 --> 命名关键字形参 --> 双星号字典形参

def func01(list_target):
    print(list_target)# ?
def func02(*args):
    print(args)# ?
def func03(*args,**kwargs):
    print(args)# ?
    print(kwargs)# ?
def func04(p1,p2,*,p4,**kwargs):
    print(p1)# ?
    print(p2)# ?
    print(p4)# ?
    print(kwargs)# ?
func01([1,2,3])  #[1,2,3]
func02(*[1,2,3]) #[1,2,3]错误,应该为(1,2,3)
func03(1,2,3,a=4,b=5,c=6) #(1,2,3)  {"a":4,"b":5,"c":6}
func04(10,20,p4 = 30,p5 = 40) # 10 20 30 {"p5":40}
 ③实参传递方式argument
(1)位置实参:实参与形参的位置依次对应
def fun01(p1, p2, p3):
    print(p1)
    print(p2)
    print(p3)
# 位置实参:根据顺序与形参进行对应
fun01(1, 2, 3)
(2)关键字实参:实参根据形参的名字进行对应。

def fun01(p1, p2, p3):
    print(p1)
    print(p2)
    print(p3)
# 关键字实参:根据名字与形参进行对应
fun01(p1=1, p2=2, p3=3)
fun01(p2=2, p1=1, p3=3)
def func03(p1, p2="", p3=0.0):
    print(p1)
    print(p2)
    print(p3)

# 关键字实参:按照名字与形参对应,可以实现跳过参数列表中左侧参数
func03(p2=1,p3=2)
(3) 序列实参:实参用*将序列拆解后与形参的位置依次对应。

                             将一个序列拆分为多个元素

def func01(p1, p2, p3):
    print(p1, p2, p3)
# 序列实参:拆,按照顺序与形参对应
list01 = [1, 2, 3]
name = "孙悟空"
tuple01 = (4, 5, 6)
# func01(list01)
func01(*list01) # 拆 1, 2, 3
func01(*name) # 拆 孙 悟 空
func01(*tuple01) # 拆 4, 5, 6
 (4)字典关键字实参:实参用**将字典拆解后与形参的名字进行对应

                                    将一个字典拆分为多个变量

          作用:配合形参的缺省参数,可以使调用者随意传参。

def func01(p1, p2, p3):
    print(p1, p2, p3)
# 字典实参:拆,按照名称与形参对应
dict01 = {"p2":"B","p1":"A","p3":"C"}
func01(**dict01)

7、函数参数总结

形式参数

        位置形参:实参必填

                def 函数名(参数1,参数2)

        默认形参:实参可选

                def 函数名(参数1=数据,参数2=数据)

        星号元组形参:多个位置实参合并为一个元组

                def 函数名(*args)

        双星号字典形参:多个关键字实参合并为一个字典

                def 函数名(**kargs)

        命名关键字形参:实参必须为关键字实参

                def 函数名(*args,参数)

                def 函数名(*,参数)

实际参数

        位置实参:按顺序

                函数名(数据1,数据2)

        关键字实参:按名称

                函数名(参数2=数据)

        序列实参:一序列拆多个参数,按顺序

                函数名(*序列)

        字典实参:一字典拆多参数,按名称

                函数名(**字典)

 总练习

    重构: 不改变功能,修改内部代码.
    --修改命名
    --修改结构(你想传递的思想是什么?)
    注意:隐藏实现细节,彰显程序过程

"""
    
"""
shang_pin_info = {
    101: {"name": "屠龙刀", "price": 10000},
    102: {"name": "倚天剑", "price": 10000},
    103: {"name": "九阴白骨爪", "price": 8000},
    104: {"name": "九阳神功", "price": 9000},
    105: {"name": "降龙十八掌", "price": 8000},
    106: {"name": "乾坤大挪移", "price": 10000}
}

ding_dan = []


def gou_wu():
    while True:
        item = input("1键购买,2键结算。")
        if item == "1":
            for key, value in shang_pin_info.items():
                print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))
            while True:
                cid = int(input("请输入商品编号:"))
                if cid in shang_pin_info:
                    break
                else:
                    print("该商品不存在")
            count = int(input("请输入购买数量:"))
            ding_dan.append({"cid": cid, "count": count})
            print("添加到购物车。")
        elif item == "2":
            zong_jia = 0
            for item in ding_dan:
                shang_pin = shang_pin_info[item["cid"]]
                print("商品:%s,单价:%d,数量:%d." % (shang_pin["name"], shang_pin["price"], item["count"]))
                zong_jia += shang_pin["price"] * item["count"]
            while True:
                qian = float(input("总价%d元,请输入金额:" % zong_jia))
                if qian >= zong_jia:
                    print("购买成功,找回:%d元。" % (qian - zong_jia))
                    ding_dan.clear()
                    break
                else:
                    print("金额不足.")


gou_wu()
# 体现过程,隐藏实现。

# 数据
dict_commodity_info = {
    101: {"name": "屠龙刀", "price": 10000},
    102: {"name": "倚天剑", "price": 10000},
    103: {"name": "九阴白骨爪", "price": 8000},
    104: {"name": "九阳神功", "price": 9000},
    105: {"name": "降龙十八掌", "price": 8000},
    106: {"name": "乾坤大挪移", "price": 10000}
}

list_order = []


def shopping():
    """
        购物
    """
    while True:
        item = input("1键购买,2键结算。")
        if item == "1":
            buying()
        elif item == "2":
            settlement()


def settlement():
    """
        结算
    """
    print_orders_info()
    total_price = calculate_total_price()
    paying(total_price)


def paying(total_price):
    """
        支付
    :param total_price: 需要支付的金额
    """
    while True:
        money = float(input("总价%d元,请输入金额:" % total_price))
        if money >= total_price:
            print("购买成功,找回:%d元。" % (money - total_price))
            list_order.clear()
            break
        else:
            print("金额不足.")


def calculate_total_price():
    """
        计算总价格
    :return: 总价格
    """
    total_price = 0
    for order in list_order:
        commodity = dict_commodity_info[order["cid"]]
        total_price += commodity["price"] * order["count"]
    return total_price


def print_orders_info():
    """
        打印所有订单信息
    """
    for item in list_order:
        commodity = dict_commodity_info[item["cid"]]
        print("商品:%s,单价:%d,数量:%d." % (commodity["name"], commodity["price"], item["count"]))


def buying():
    """
        购买
    """
    print_commodity_info()
    order = create_order()
    list_order.append(order)
    print("添加到购物车。")


def input_commodity_id():
    """
        获取商品编号
    :return: int类型,商品编号
    """
    while True:
        cid = int(input("请输入商品编号:"))
        if cid in dict_commodity_info:
            return cid
        print("该商品不存在")


def create_order():
    """
        创建订单
    :return: 字典类型的订单
    """
    cid = input_commodity_id()
    count = int(input("请输入购买数量:"))
    order = {"cid": cid, "count": count}
    return order


def print_commodity_info():
    """
        打印商品信息
    """
    for key, value in dict_commodity_info.items():
        print("编号:%d,名称:%s,单价:%d。" % (key, value["name"], value["price"]))


shopping()

你可能感兴趣的:(python基础学习,python,学习)