python测试(9)

1.函数的调用

一般来说在python中代码的读取顺序是从上到下,但是那是一种大体的趋势,并不是所有的代码都是从上往下。如果全部都是那种顺序,那么if,for等就会失去意义

判断以下代码能否成立:

def get_offer(name,money):
    print(f"{name}拿到了{money}一个月的工资")
    eat(name,'辣条')
def eat(name,food):
    print(f"{name}喜欢吃{food}")
get_offer('王小进和王小丹','50k')

结果:

王小进和王小丹拿到了50k一个月的工资
王小进和王小丹喜欢吃辣条

该代码是可以执行的,之前虽然提到过函数的要先定义再执行,但是是先执行函数名就是先执行顶格的代码,函数体会在所有的顶格代码执行完后再执行

代码的执行流程:首先会到get_offer函数,但是会先执行他的名称(知道了有这么一个函数),不会执行函数体。然后到eat函数(知道了这个函数),也不会先执行函数体,最后执行最后一行,调用get_offer函数,得到name和money的值。完成后就会回到第一个函数的函数体,打印name拿到了money一个月的工资,然后在第一个函数体内知道了要使用eat函数,最后跳转到第二个函数体内,因为在第一个函数体内已经得到了name和’辣条‘,所以第二个函数体就可以执行,最后打印name喜欢吃food

也可以不进行函数的调用来测试代码的执行顺序:

def get_offer(name,money):
    print(f"{name}拿到了{money}一个月的工资")
    eat(name,'辣条')
def eat(name,food):
    print(f"{name}喜欢吃{food}")

如果是硬性从上往下执行代码,那么结果就会打印两行代码,但是上述代码并不会打印出任何东西,因为函数体内根本就没有执行

再进行判断:

def get_offer(name,money):
    print(f"{name}拿到了{money}一个月的工资")
    eat(name,'辣条')
get_offer('王小进和王小丹','50k')
def eat(name,food):
    print(f"{name}喜欢吃{food}")

该代码会报错

执行过程:先认识get_offer函数,然后到get_offer的调用,得到了name和money,接着就会去执行get_offer函数体,先打印第二行的内容,然后就会到eat函数的调用,因为之前计算机还没有知道eat函数的定义,所以在此处会违背规则就会报错

ps:调试代码的时候,第一个小格是表示下一步,第二个小格表示进入函数内部,当不知道某个函数如何运行时,可以使用该功能

函数可以调用他自己吗?

def get_offer(name,money):
    print(f"{name}拿到了{money}一个月的工资")
    get_offer(name,money)
get_offer('王小进和王小丹','50k')

结果:一直循环,然后程序报错

过程:

先执行函数名称,然后就跳到最后一行,进行函数的调用,得到name和money的值,然后进入函数体,不断地调用,就会不断地打印,一直到程序报错为止

ps:递归:函数自己调用自己

2.函数的作用域

函数的作用域包括局部作用域和全局作用域

函数里面的为局部变量,函数外面的为全局变量

局部变量不可以被使用在全局作用域中

全局变量可以使用在局部作用域中,但是不能在局部变量中被修改,有一种特殊的方式可以修改,就是在局部作用域中用

global,他可以在局部变量中把全局变量修改掉,但是不建议使用global,因为不断的修改全局变量,当代码行数比较多的时候就搞不清某个全局变量到底是多少

例如:

全局变量使用在局部作用域中

y = 5
def add():
    return y
print(add())

结果:5

当在局部作用域中想要修改全局变量时

y = 5
def add():
    y+=6
    return y
print(add())

结果:报错

当在全局作用域中想要使用局部变量时

def add():
    y = 5
add()
print(y)

结果:报错

使用global修改全局变量

y =7
def add():
    global y
    y +=7
    return y
print(add())
print(y)

结果:

14

14

使用了global之后,全局变量就已经被修改了

3.内置函数

内置函数是指当下载好python软件后,内部就已经定义好的函数,直接调用即可,不需要再定义

例如print()函数、input()函数、len()函数等,内置函数有很多,应该加以理解后再使用

如果不是内置函数,函数就要先进行定义再使用

enumerate()函数:

enumerate()函数是内置函数

用for循环逐个打印数组里面的数据

a =[1,2,3,4,5,6]
for e in a :
    print(e)

结果:

1

2

3

4

5

6

但是在加了enumerate函数之后:

a =[1,2,3,4,5,6]
for e in enumerate(a) :
    print(e)

结果:

(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)

a =[(1,2),"haha",'猪八戒',4.7,5,6]
for e in enumerate(a) :
    print(e)

结果:

(0, (1, 2))
(1, ‘haha’)
(2, ‘猪八戒’)
(3, 4.7)
(4, 5)
(5, 6)

用了enumerate()函数之后,会以元组的形式被打印出来,前面的相当于序号,后面的即为数组里面每一个数据

使用enumerate()函数之后如果不想要结果以元组的形式出现,可以用两个不同的新变量来接收两个值

例如:

a =[(1,2),"haha",'猪八戒',4.7,5,6]
for e,c in enumerate(a) :
    print(e,c)

结果:

0 (1, 2)
1 haha
2 猪八戒
3 4.7
4 5
5 6

eval()函数:

eval函数的作用是把字符串两边的引号去掉:

没使用eval函数之前

a = '1+5'
print(a)

结果:

1+5

因为a是一个字符串

使用eval函数之后:

a = '1+5'
print(eval(a))

结果:

6

用eval函数去掉字符串两边的引号之后,数据类型发生了变化,变成了int类型,就会进行运算,所以答案为6

sum()、min()、max()函数:

sum函数用来计算多个数字之和,min函数用来判断多个数字中最小的一个数,max函数用来判断多个数字中最大的一个数

a = [1,2,3,4,5,6,7,8,9]
print(sum(a))
print(min(a))
print(max(a))

结果:

45

1

9

zip()函数:

zip函数是用来打包的

例如:

a = [0,1,2]
b = ['a','b','c']
c = [1.2,'hh',[]]
for e in zip(a,b,c):
    print(e)

结果:

(0, ‘a’, 1.2)
(1, ‘b’, ‘hh’)
(2, ‘c’, [])

可以对多个数组进行打包,最后放在一个元组里面

如果在打包操作中几组数据里面的元素个数是不对等的,他会把前面对等的先配对,后面不对等的就会省略掉

a = [0,1,2]
b = ['a','b','c']
c = [1.2,'hh']
for e in zip(a,b,c):
    print(e)

结果:

(0, ‘a’, 1.2)
(1, ‘b’, ‘hh’)

zip函数有一个特别重要的作用:可以把两组数据转变成为可读性更高的字典,其步骤是先打包成为元组,再用一个空列表将所获得的元组存起来,将该新列表转化成为字典

a = [0,1,2]
b = ['hh','xixi',[]]
new = list(zip(a,b))
print(dict(new))

结果:

{0: ‘hh’, 1: ‘xixi’, 2: []}

例如:

title = ['id','title','step']
date1 = [1,'abc','1,2,3']
date2 = [2,'efg','4,5,6']
print(dict(zip(title,date1)))
print(dict(zip(title,date2)))

结果:

{‘id’: 1, ‘title’: ‘abc’, ‘step’: ‘1,2,3’}
{‘id’: 2, ‘title’: ‘efg’, ‘step’: ‘4,5,6’}

如果想将二维数组转变成为可读性更高的字典:

[

[]

[]

]

变成:

[{},{},{}…]

a = [
    ['id', 'title', 'step'],
    [1, 'abc', '1,2,3'],
    [2, 'def', '4,5,6']
]
new_a = a[0]
c = [dict(zip(new_a, i)) for i in a[1:]]
print(c)

结果:

[{‘id’: 1, ‘title’: ‘abc’, ‘step’: ‘1,2,3’}, {‘id’: 2, ‘title’: ‘def’, ‘step’: ‘4,5,6’}]

因为a[0]是每一个数据前面都要标记的,而后面是具体的数据,后面的因为是同样的操作所以使用了列表推导式(即dict(zip(new_a,i)for i in a[1:]),如果不使用列表推导式会增加代码行数,让代码变得更加复杂,写成a[1:]是因为a[0]是前缀,不需要再重新写

4.open打开文件以及相关的操作

创建一个新的文件,在本文件内可以通过一些操作对新文件进行修改、读取等

创建一个名为demo.txt的新文件

f =open('demo.txt')

在本文件内用一个变量存,后面使用open函数,里面加新文件名称,就能够打开新文件

如果想阅读文件中的内容就要用到read函数

在新文件中加入hhh内容

f =open('demo.txt')
date = f.read()
print(date)

结果:hhh

先打开文件再阅读内容再打印出来

当一个文件阅读等操作完成之后,要记得要用close函数关掉

f =open('demo.txt')
date = f.read()
print(date)
f.close()

如果在新文件中还有中文,那么在open中还要加入 encoding=‘UTF-8’,这样就可以阅读到新文件中的中文

f =open('demo.txt',encoding='UTF-8')
date = f.read()
print(date)
f.close()
写入文件:
f =open('demo.txt',mode = 'w',encoding='UTF-8')
f.write('我是超人')
f.close()

写入文件有几个需要注意的点:必须加入mode=‘w’,这个代表要写入文件,因为默认是mode=‘r’,是阅读文件,所以读取的时候可以省略,写入不可以,写入中文也要写utf-8,不能省略,并不能同时写两个字符串或者说是内容

但是这种方式有一个缺点,当输入完前面的内容之后,后面再去加,会覆盖掉前面的内容,相当于内容是一次性的,但是如果写成mode='a’就可以不断地增添文本的内容

例如:

f =open('demo.txt',mode = 'a',encoding='UTF-8')
f.write('\n是的没错我不仅是美女也是一个超级大英雄')
f.close()

结果:

我是超人

是的没错我不仅是美女也是一个超级大英雄

这样就可以在之前的基础上继续写内容,而且对前面的内容没有什么影响,后面的内容是紧跟前面的,所以说如果想要另起一行,需要在前面加上换行符

这个a模式相对于w模式来说更加的安全

还有一个b模式,叫做二进制模式,可以将新文件中的文字,图片,视频等解析成为二进制

f =open('demo.txt',mode = 'rb')
date = f.read()
print(date)
f.close()

结果:

b’\xe6\x88\x91\xe6\x98\xaf\xe5\xa4\xa7\xe7\xbe\x8e\xe5\xa5\xb3’ (因为光用二进制的话,会特别的长,所以加了x等)

当然也可以用wb模式

f =open('demo.txt',mode = 'wb')
f.write(b'\xe6\x88\x91\xe6\x98\xaf\xe5\xa4\xa7\xe7\xbe\x8e\xe5\xa5\xb3')
f.close()

这样可以将二进制代码代表的文字、图片或者视频传入到新文件中

如果觉得二进制码太多,可以提前存到一个变量里面

readlines函数:
f =open('demo.txt',encoding='utf-8')
date = f.readlines()
print(date)
f.close()

结果:

[‘我是大美女\n’, ‘我是小英雄\n’, ‘我是超人’]

readlines函数就是一行一行读取新文件里面的内容,然后将内容存到一个列表中

你可能感兴趣的:(python,java,开发语言,功能测试,pycharm)