首页 > 编程语言 >python 函数(解包、互相调用、作用域、函数的封装、内置函数:eval()、zip()、open())

python 函数(解包、互相调用、作用域、函数的封装、内置函数:eval()、zip()、open())

时间:2024-03-21 15:58:08浏览次数:25  
标签:函数 title 作用域 offer 解包 param print 字典

函数解包

"""
1、函数的注释:参数和返回值 在注释里可以自动添加显示,只需手动加说明。

2、函数的解包【拆包】:函数的参数要传递数据有多个值的时候,中间步骤拿到数据 保存在元组或者列表 或者字典里。
- 传递参数的时候 加一个*  或者  ** 解包
  - 一次拿到元组 列表 字典的里数据 直接传递给函数的参数接受。
- 定义参数的额*args **keargs == 定义函数
"""
def send_offer(salary,bonus,subsidy=500):
    """
    这是一个发送offer的函数
    :param salary: 底薪
    :param bonus: 提成
    :param subsidy: 补助
    :param args: 不定长参数  薪资其他的组成
    :param kwargs: 不定长参数  薪资其他的组成
    :return: 返回薪资总共
    """
    smoney = salary + bonus + subsidy
    return smoney  # 定义smoney为函数返回值

# 参数数据保存在元组里,依次获取里面每一个数据 传参
param = (18000,3000,200)
# 传统方式 麻烦。
print('传统方式',send_offer(param[0],param[1],param[2]))
# 元组解包传参 : 元组前面加一个* 可以依次获取元组里每一个数据 按照位置顺序的传递给函数参数
print('元组解包传参'+str(send_offer(*param)))

# 列表解包
param = [18000,3000,200]
print(send_offer(*param))

# 字典解包 --键值对 : 字典跟顺序没关系,字典的key跟关键字名字【形参】对应就可以。
param = {"salary":17000,"bonus":2000,"subsidy":300}
# 传统方式 -- 多麻烦
print(send_offer(salary=param["salary"], bonus=param["bonus"], subsidy=param["subsidy"]))
# 字典解包
print(send_offer(**param))

函数的调用

函数里调用其他的函数:
注意: 函数执行原理顺序

  • 顶格代码 同级别: 从上到下依次执行。
  • 缩进代码: 函数体代码 ,只有在函数调用的时候的才会执行。

debug新用法:

  • step over : 第一个单步,不会进入函数或者方法里面执行
  • step into : 第二个【进入所有的函数和方法】 和第三个【只会自己定义函数和方法】

问题: 函数可以调用自己么?
= 会出现递归错误 函数不要调用自己。


# def get_offer(name):
#     """拿offer函数: 某个人 拿到x钱offer"""
#     # 调用send_offer函数
#     money = send_offer(16000,2000,800)
#     return f'{name}拿到了一个{money}工资的offer!'
#
# def send_offer(salary,bonus,subsidy=500):
#     smoney = salary + bonus + subsidy
#     return smoney
#
# print(get_offer("芒果"))

def get_offer(name):
    """拿offer函数: 某个人 拿到x钱offer"""
    # 调用send_offer函数
    money = get_offer("我")
    print(money)
    return f'{name}拿到了一个{money}工资的offer!'

get_offer("我")

如上自己调用自己就会报错:
在这里插入图片描述

函数的作用域

函数的作用域: 函数内部 和函数外部

  • 局部变量: 函数里定义的变量,不能在外面的调用。 【买的苹果】 私有财产 不能给别人使用
  • 全局变量:在函数外面定义的变量,在函数里面可以调用。 【小区的公共苹果】 所有人都可以拿
  • 全局变量函数可以调用,但是不能在函数内部去修改 【苹果可以吃 但是苹果树砍了不行】
  • 如果提前申明了 是可以修改 【但是跟物业申请了 可以砍了】
  • 在局部修改了全局变量值 生效。
    – 注意: 不建议在局部修改全局变量,容易造成别人调用了全局变量会被影响。

# add函数里的ab 变量 是局部还是全局的? -局部变量
c = 3  # 全局变量

def add(a,b):
    global c  # 申明全局变量  -- 用得很少
    c += 1
    return a + b -c

# print(a)  # 局部变量不能在函数外面使用的
print(add(2,3))
print(c)  # 在局部修改了全局变量值 生效。

运行结果如下:

1
4

函数的封装

函数是不是基本上所有功能代码都可以被封装成函数?-- 可以。但是并不是所有的都需要封装。
– 只有哪些需要多次 重复使用功能代码。–调用。

封装函数步骤:
1、先分析求 把功能代码写好
2、def 封装 [功能代码缩进变成函数体]
3、函数参数化:变化的数据 或者用户控制输入的数据 定义为形参
4、判断函数是否需要定义返回值:获取数据 有就返回; 没有不定义返回值。

def buy(price):
    discount = "0"
    if price.isdigit(): # 判断是否输入的是数字
        if 50 <= int(price) <= 100:
         price = int(price) * 0.9
         discount = "10%"
        elif int(price) > 100:
         price = int(price) * 0.8
         discount = "20%"
        return f"折扣为:{discount},最终要付的金额为:{price}"
    else:
        return "请输入数字"


print(buy("200"))

运行结果如下:

折扣为:20%,最终要付的金额为:160.0

内置函数

总结内置函数:安装Python软件的时候,已经内部定义好的 可以直接使用的函数。

  • ctrl + 点击函数名字 == =builtin 描述文件,参数 使用方法和功能等信息。 底层是c语言封装的。
  • 内置函数有很多,不需要目前全掌握 先掌握用的频率较高。
    常用的内置函数
  • print input
  • len
  • type isinstance
  • range()
  • str int float list tuple set dict
  • 字符串的方法: str.find , .index .lower .upper .join .strip .replace .split .endswith .startswith 。。。
  • 列表方法: .append .extexd .insert .pop .remove ,.count
  • 字典方法: .update .get .keys .values .item() .pop

print: 参数: * args可以接受多个参数;

  • sep=’ ’ : 默认值是空格,所以多个参数之间用这个字符隔开 ,可以传参
  • end=‘\n’,每个print语句最后都会换行 默认换行符;–也可以修改 传参
    print(“乖乖”,“余”,“芒果”,sep=“–”,end=“*”)
    print(“乖乖”,“余”,“芒果”,sep=“–”)

eval()

eval(): 函数用来执行一个字符串表达式,并返回表达式的值。 == 脱引号获取及运行字符串里的Python表达式。
字符串表达式可以包含变量、函数调用、运算符和其他 Python 语法元素。

使用场景1 : 接口测试的时候,测试数据存在excel里【文本-字符串】;代码读取出来,存在字典和列表。-- 脱引号 转化字典
使用场景2 : 接口测试数据参数化,excel表格里数据生成,在excel表格里调用数据生成函数。

eval不是万能的,有些字符串不能用的 只要那些字符串里的表达式符合Python语法的才可以。

# eval()
a = "1 + 4"  # 字符串
print(a)  # 结果 "1 + 4"
print(eval(a)) # 脱引号 运算引号里的Python表达式 1+4

a = '{"name":"itop","age":18}'  #在字典外面加了一对引号  字符串
print(a,type(a))
print(eval(a),type(eval(a)))
# 接口测试的时候,测试数据存在excel里【文本-字符串】;代码读取出来,存在字典和列表。-- 脱引号 转化字典

# 函数调用
def p_test():
    print("hello world")

# "test()"  # 这样不行调用函数
# eval执行字符串里函数调用
eval("p_test()")

# 异常场景  --有一个null 在Python里是不能被识别的  异常符合。None
a = '{"name":"itop","age":18,"hobby":null}'
print(eval(a),type(eval(a)))

运行结果如下:

1 + 4
5
{"name":"itop","age":18} <class 'str'>
{'name': 'itop', 'age': 18} <class 'dict'>
hello world
Traceback (most recent call last):
  File "D:\BaiduNetdiskDownload\1-Python基础\20231110_py65基础第六节课-函数和文件处理\day06_函数和文件处理\day06_函数和文件处理\d5_内置函数和eval函数.py", line 54, in <module>
    print(eval(a),type(eval(a)))
  File "<string>", line 1, in <module>
NameError: name 'null' is not defined

zip()

zip(): 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

  • 如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。

使用场景: 接口测试测试用例保存在字典里,方便数据读取。{“id”:1,“title”:“注册成功”}

a = ["a","b","c"]
b = [1,2,3,4]
print(list(zip(a, b))) #压缩并转化为列表嵌套元组 [('a', 1), ('b', 2), ('c', 3)]
print(dict(zip(a, b))) # 压缩成为键值对 的字典 key value {'a': 1, 'b': 2, 'c': 3} ==这种用更多

# 用例 == 压缩成为字典
title = ["id","title","testdata"] # 作为保存用例的字典的key
case1 = ["1","注册成功","123456"]
case2 = ["2","注册失败","123456"]
print(dict(zip(title, case1))) # {'id': '1', 'title': '注册成功', 'testdata': '123456'}
print(dict(zip(title, case2)))

# 项目里实战: 二维数据 --模拟excel里存储 行列
# 所有的用例放在大列表里,每条用例存在字典里 [{},{},{},{}]
testcases = [["id","title","testdata"],
            ["1","注册成功","123456"],
            ["2","注册失败","123456"]]
title = testcases[0]  # 先获取标题 用来作为字典的key
new_list = []
for case in testcases[1:]:  # 从第二行开始读取 不需要标题行
    dict_case = dict(zip(title,case))  # 一条用例 字典
    new_list.append(dict_case)
print(new_list)

# 优化写法: 列表推导式
testcases = [["id","title","testdata"],
            ["1","注册成功","123456"],
            ["2","注册失败","123456"]]
title = testcases[0]
new_case = [dict(zip(title,case)) for case in testcases[1:]]
print(new_case)

运行结果如下:

[('a', 1), ('b', 2), ('c', 3)]
{'a': 1, 'b': 2, 'c': 3}
{'id': '1', 'title': '注册成功', 'testdata': '123456'}
{'id': '2', 'title': '注册失败', 'testdata': '123456'}
[{'id': '1', 'title': '注册成功', 'testdata': '123456'}, {'id': '2', 'title': '注册失败', 'testdata': '123456'}]
[{'id': '1', 'title': '注册成功', 'testdata': '123456'}, {'id': '2', 'title': '注册失败', 'testdata': '123456'}]

open()

open(): 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写。

  • 数据存储到文件里-- 写入文件数据
  • 配置文件: 数据库 项目的地址等 放在文本里进行统一管理,读取里面数据-- 文件的读取
  • UI自动化-- 截图保存图片

文件处理的操作:

  • 打开文件
  • 读取文件内容
  • 写入内容到文件
  • 关闭文件 :文件打开了 一定要记得关闭。不关闭再次使用的时候 容易冲突 报错。

文件里有中文: UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x86 in position 47: illegal multibyte sequence

  • 打开文件的时候 加上编码 UTF8编码。
  • 语言默认只能处理英文,编码ASCII编码,国际编码通用-UTF8。 加上参数: encoding=“UTF8” 默认加上。

mode :

  • r 读取
  • w: 覆盖之前内容 写入
  • a: 追加写入 == 更常用 更安全
  • x: 写入 写入新文件 不能是已经存在的文件,直接生成新的文件并写入内容
  • b: 写入文件不是文本,图片 视频等 二进制流的格式 ; 不单独用,配合以上读写模式一起用
    • rb
    • wb
    • ab
      注意: 不能加encoding=“UTF8”。

读取

demo文本内容如下:我希望名可以继续捡10块钱我希望名可以继续捡10块钱我希望明天可以继续捡10块钱

# open 打开文件 读取里面内容
f = open("demo",encoding="UTF8")
# print(f)  # 对象,通过他可以进行后续操作
data = f.read()  # 读取数据 赋值给data变量
print(data)
# 关闭文件
f.close()

运行结果如下:

我希望名可以继续捡10块钱我希望名可以继续捡10块钱我希望明天可以继续捡10块钱

写入

# open 写入数据--  mode 默认是读的模式 不能写入。 修改mode为w 【write】
# f = open("demo",encoding="UTF8",mode="a")
# f.write("我希望明天可以继续捡10块钱")

# f = open("demo",encoding="UTF8",mode="w")
# f.write("我希望明天可以继续捡10块钱")

# f = open("demo1",encoding="UTF8",mode="x")
# f.write("我希望明天可以继续捡10块钱")

f = open("tricy.png",mode="rb")
data = f.read()  # 图片内容 是十六进制格式
print(data)
f.close()

# 复制一张图片 --把写入内容
f = open("tri2.png",mode="wb")
f.write(data)
f.close()

标签:函数,title,作用域,offer,解包,param,print,字典
From: https://blog.csdn.net/qq_35283902/article/details/136882452

相关文章

  • Jmeter的元件作用域和执行顺序
    一、元件的基本介绍元件:多个类似功能组件的容器(类似于类) 取样器 逻辑控制器 前置处理器 后置处理器 断言 定时器 测试片段 配置元件 监听器 组件:实现独立的某个功能(类似于方法)2、元件作用域在JMeter中,元件的作用域是靠测试计划的树形结构中元件的父子关......
  • C++ 合成默认构造函数
    问题:C++面向对象编程时,如果我们没有声明任何构造函数constructor,按照以前最初学习,说编译器会自动合成一个默认的无参构造函数defaultconstructor,但是事实确实是这样吗,存不存在例外呢,即使有合成构造函数,那么它又将对类数据进行怎样的初始化呢?1.问题一如果我们没有声明任何构造......
  • 复变函数,启动!计应数番外编~对冒险主义的姚发起华丽叛逆的说!!!
    \[\newcommand{\Arg}{\operatorname{Arg}}\newcommand{\i}{\mathbfi}\newcommand{\d}{\mathrmd}\newcommand{\p}{\part}\newcommand{\Ln}{\operatorname{Ln}}\newcommand{\Arccos}{\operatorname{Arccos}}\newcommand{\Arcsin}{\operatorname{A......
  • gin框架函数语法
    引擎类:gin.Default()带中间件路由引擎gin.New()不带中间件路由引擎路由类:r.GET()查询接口r.POST()创建接口r.PUT()更新接口r.DELETE()删除接口r.Run()运行端口r.Static()模糊路径配置静态文件r.StaticFS()API路径配置静态文件r.StaticFile()精确路径配置静态文件r.L......
  • React函数组件Hook
    问题:相对于类组件,函数组件的编码更简单,效率也更高,但函数组件不能有state(旧版)解决:React16.8版本设计了一套新的语法来让函数组件也可以有stateHook是React16.8的新增特性。它可以让你在不编写class的情况下使用state以及其他的React特性Hook也叫......
  • Python函数每日一讲11 - isinstance()
    引言在Python编程中,我们经常需要检查一个对象是否属于某个特定的类或类型。为了实现这个目的,Python提供了isinstance()函数。通过本文的介绍,你将了解isinstance()函数的基本语法、用法示例以及在实际工作中的应用场景,帮助你更好地理解和应用这一函数。语句概览isinstance()函数......
  • C++基础入门(命名空间,函数,引用)
    文章目录前言1,命名空间2,函数函数重载缺省参数内联函数3,引用尾声前言欢迎来到这篇关于C++的入门博客!C++是一门强大而又广泛应用的编程语言,作为一门面向对象的编程语言,C++可以让你更好地组织和管理代码,提高代码的重用性和可维护性。它广泛应用于游戏开发、嵌入式系......
  • atoi函数模拟实现
    用法:将字符串里的数字字符转化为整型数,返回整型值。转化时会跳过前面的空白字符,遇到正负号和数字字符再进行转换,如果遇到其他字符,就结束。intmy_atoi(char*s){ assert(s);//先断言,判断指针S是否为空指针 intsum=0; char*s1=NULL; char*s2=NULL; char*s3......
  • C++ 函数模板
    C++函数模板函数模板在C++中,函数模板是一种允许函数以一种类型无关的方式来操作的工具。它们使得函数能够处理不同类型的数据而不需要为每种类型编写重复的代码。函数模板的核心思想是“参数化类型”,这意味着在定义函数时,可以使用一个或多个通用类型参数,而在函数被调用时......
  • qsort实现函数排序(2)
    qsort实现结构体排序#include<stdio.h>#include<stdlib.h>#include<string.h>structstu{ charname[20]; intage;};intcmp_by_name(void*p1,void*p2){ returnstrcmp(((structstu*)p1)->name,((structstu*)p2)->name);}voidprint(s......