Python开发第三篇

时间:2023-03-09 15:45:53
Python开发第三篇

函数

一、函数参数传值

形参:函数在定义的时候给定的参数

实参:函数在运行时赋给的参数:

 def func(i):#i为定义时的参数,为形参
pass
func(name)#name为运行时的参数,为实参,实参与形参的名字可以相同

传值方式:

位置传值:按照定义时的顺序,用实参给形参赋值

 def func(x,y,z):
print("x->",x)
print("y->",y)
print("z->",z)
func(1,2,3) #按顺序将值一一赋给形参
x-> 1
y-> 2
z-> 3

关键字传值:形参1 = xxx,形参2 = xxx

 def func(x,y,z):
print("x->",x)
print("y->",y)
print("z->",z)
func(x = 1,z = 2,y = 3)#将x赋值为1,y赋值为3,z赋值为2
#关键字传参,没有位置对应关系 x-> 1
y-> 3
z-> 2

混合传值:要注意混合传值时,关键字传值必须放到位置传值的右边

 def func(x,y,z):
print("x->",x)
print("y->",y)
print("z->",z)
func(1,2,z = 3)
'''关键字传值,必须在最右边,并且不能对已经有位置传参的形参进行传值''' x-> 1
y-> 2
z-> 3

万能的传值方式(可变长参数传值方式):

*args:传值接受后组成元组(位置处传值)

**kwargs:传值后组成字典(用于关键字传值)

使用参数时遍历即可

def func(*args,**kwargs):
print(args)
print(kwargs)
func(1,2,3,x = 4,y = 5) (1, 2, 3)
{'x': 4, 'y': 5}

二、函数的作用域问题

有下面一段简单代码:

 name = "sunqi"
def foo():
name = "tony"
print(name)
foo()

打印输出为“tony”,为什么是tony而不是sunqi?

直接的说是因为python在寻找变量时,是找离它最近的。就是先从函数本地内部开始找,然后去函数外面找,最后再去python内置函数中找。

例如这个输出打印,就是因为先找到了“tony”然后就用他来做为name输出。

那么就有全局变量,和本地变量的区别了

定义在程序最外边的就是全局变量,比如name =“sunqi”

定义在函数内部的变量就是局部变量也叫本地变量,比如name = “tony”

当全局变量与局部变量重名时,本地本地变量会在内部作用域中替换全局变量。从下面的例子就可以看出来,内部变量并没有修改全局变量的值

 name = "sunqi"
def foo():
name = "tony"
print(name)
foo()
print(name) tony
sunqi

当我们要使用并修改全局变量时就需要声明global 属性

 name = "sunqi"
def foo():
global name
name = "tony"
print(name)
foo()
print(name) tony
tony

可以看出全局变量已经被修改

我们来看一下下边的例子

 name = [1,2,3,4]
dic = {"name":"sunqi","age":18}
def foo():
name = [23,44,5,]
print(name)
foo()
print(name) [23, 44, 5]
[1, 2, 3, 4]

和上边的例子一样,foo函数并没有对局部变量产生任何影响

 name = [1,2,3,4]
dic = {"name":"sunqi","age":18}
def foo():
name.append(7)
dic["age"] = 10
print(name)
print(dic.items())
foo()
print(name)
print(dic.items()) [1, 2, 3, 4, 7]
dict_items([('name', 'sunqi'), ('age', 10)])
[1, 2, 3, 4, 7]
dict_items([('name', 'sunqi'), ('age', 10)])

例子中列表和字典局均为全局变量,foo函数引用的也是全局变量,但是为声明global。却修改了列表和字典。

原因是,既然没有声明global属性,就不能对全局变量进行赋值,但是对于可修改的全局变量来说,可以修改他们的内部元素。

比如字典,列表。

 def foo():
count = 0
def boo():
nonlocal count# 省略掉这句话会报定义前引用的错误
count+=1
print(count)
boo()
print(count)
foo() 1
1

nonlocal用于声明非全局变量的外部变量,当不需要对上层变量进行修改时不必声明nonlocal

上边的例子没有nonlocal的话会报错:计数前未声明

 def foo():
count = 0
def boo(): print(count)
boo()
print(count)
foo() 0
0

不修改上层变量

三、高阶函数

函数就是变量,可以被当做返回值,也可以作为参数传给另一个函数

 def foo():
count = 0
def boo():
print(count)
print(boo)
return boo
f = foo()
print(f) <function foo.<locals>.boo at 0x0000020248CC4AE8>
<function foo.<locals>.boo at 0x0000020248CC4AE8>

函数被return返回的是函数的地址上面的例子可以通过f()直接运行就相当于运行boo()

函数也可以作为参数传递给另一个函数:

 #函数作为参数传递
num = [1,2,3,4]
def add(i,sum = 0):
"""
sum加法初始值,默认值为零
:param sum:
:param i:
:return:
"""
sum = sum +i
return sum
def test(func,num):
res = 0
for i in num:
res = res + func(i)
print(res)
test(add,num)#add函数作为参数传递给了test函数 10

四、lambda表达式,map,reduce,filter

lambda表达式的意义就是对函数的简洁表示

lambda函数也叫匿名函数

冒号前是参数,冒号后是返回值

lambda函数经常与map,reduce,filter一起使用

map():对一个可迭代对象进行遍历,并交由lambda处理,返回一个与传入的对象长度相同,顺序相同的object对象

reduce():对一个可迭代对象的元素进行遍历并运算,返回一个计算后的值

filter():传入一个可迭代对象,通过设置条件筛选出满足 条件的元素,组成新的object对象,可以用列表转换后遍历输出

 func = lambda x:x+1
print(func(10))
func = lambda x,y,z:(x+1,y+1,z+1)
print(func(1,2,3))
func = lambda x:x+"DE"
print(func("ABS")) 11
(2, 3, 4)
ABSDE
 from functools import reduce

 foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print(list(map(lambda x: x + 1, foo)))
print(reduce(lambda x, y: x + y, foo))
print(list(filter(lambda x: x > 10, foo))) [3, 19, 10, 23, 18, 25, 9, 13, 28]
139
[18, 22, 17, 24, 12, 27]

五、内置函数

1、简单内置函数

 abs()绝对值
'''
all()函数对所有元素进行布尔运算,如果每个元素的布尔值都为True则返回True。
如果传入的参数为空,返回True
'''
all() li = [1,2,3,"suqni","",(),{},[]]
li_1 = [1,2,3,"suqni",]
li_2 = [] print(all(li))
print(all(li_1))
print(all(li_2)) False
True
True bin()转换二进制
bool()布尔值判断
bytes()转换成字节,#指定编码utf-8保存中文,一个汉字三个字节,gbk保存中文两个字节
chr() ascii 转换数字与字符
divmod()取商得余数

2、eval()

   提取字符串内容

      对提取的内容进行数学运算

 a = "[1,2,3],{'name':'sunqi'}"#提取并返回元组
s = "1+2*(3-1/2)%2"
print(eval(a))
print(eval(s)) ([1, 2, 3], {'name': 'sunqi'})
2.0

3、hash()

  返回对象的哈希值

  可哈希的数据类型就是不可变数据类型

不可哈希的数据类型就是可变的数据类型(列表,字典类型需要转换成字符串类型才可哈希)

4、globals()打印全局变量

  locals() 打印局部变量

 name = "sunqi"
# print(globals())
print("globals-->",globals())
def func():
name = "tony"
print("locals-->",locals())
func()
 globals--> {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001F81766D240>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Python_project/python_kaifa/day17_day8/test_17.py', '__cached__': None, 'name': 'sunqi'}
 locals--> {'name': 'tony'}

5、zip()

  要求参数必须为序列,比如,列表,元组,字符串

  返回两个序列的元素的一对一组合的元组形式

  当两个序列的长度不相同时,就会根据较短的元素进行组合 

 li = [1,2,3]
li_1 = ["sunqi","tony","tom"]
print(list(zip(li,li_1))) [(1, 'sunqi'), (2, 'tony'), (3, 'tom')]
 li = [1,2,3,4]
li_1 = ["sunqi","tony","tom"]
print(list(zip(li,li_1))) [(1, 'sunqi'), (2, 'tony'), (3, 'tom')]

长度不同

  实现字典键值对的反转

 dic = {
"name":"sunqi",
"age":18
}
print(list(zip(dic.values(),dic.keys()))) [('sunqi', 'name'), (18, 'age')]

字典反转

6、max()

  比较大小,返回最大的

  要求参数支持for循环

  要求参数内元素数据类型相同

  从元素的第一个位置开始比较,字母,字符按照ASCII码比较

 li = [
{'name':"sunqi",'age':''},
{'name':"tony",'age':''},
{'name':"tom",'age':''}
]
print(max(li,key=lambda dic:dic['age']))

 8{'name': 'tony', 'age': '20'}

9#根据age的值选出最大的,内部也是调用for循环
10#然后将值传给lambda,就是一个字典,返回字典的age

7、sorted()

  sorted是内置方法,排序后返回新的序列,原序列不会被修改

  sort是列表的方法,不返回排序后的序列,而是之久替换原序列

 li = [1,3,4,2,6,5,25,14]

 print(sorted(li))
print(li)
print(li.sort())
print(li) [1, 2, 3, 4, 5, 6, 14, 25]
[1, 3, 4, 2, 6, 5, 25, 14]
None#不返回新序列
[1, 2, 3, 4, 5, 6, 14, 25]#原序列改变

8、__import__()

  导入包名是字符串的包

  m = __import__("test")

9、format()

#字符串可以提供的参数 's' None
>>> format('some string','s')
'some string'
>>> format('some string')
'some string' #整形数值可以提供的参数有 'b' 'c' 'd' 'o' 'x' 'X' 'n' None
>>> format(3,'b') #转换成二进制
''
>>> format(97,'c') #转换unicode成字符
'a'
>>> format(11,'d') #转换成10进制
''
>>> format(11,'o') #转换成8进制
''
>>> format(11,'x') #转换成16进制 小写字母表示
'b'
>>> format(11,'X') #转换成16进制 大写字母表示
'B'
>>> format(11,'n') #和d一样
''
>>> format(11) #默认和d一样
'' #浮点数可以提供的参数有 'e' 'E' 'f' 'F' 'g' 'G' 'n' '%' None
>>> format(314159267,'e') #科学计数法,默认保留6位小数
'3.141593e+08'
>>> format(314159267,'0.2e') #科学计数法,指定保留2位小数
'3.14e+08'
>>> format(314159267,'0.2E') #科学计数法,指定保留2位小数,采用大写E表示
'3.14E+08'
>>> format(314159267,'f') #小数点计数法,默认保留6位小数
'314159267.000000'
>>> format(3.14159267000,'f') #小数点计数法,默认保留6位小数
'3.141593'
>>> format(3.14159267000,'0.8f') #小数点计数法,指定保留8位小数
'3.14159267'
>>> format(3.14159267000,'0.10f') #小数点计数法,指定保留10位小数
'3.1415926700'
>>> format(3.14e+1000000,'F') #小数点计数法,无穷大转换成大小字母
'INF' #g的格式化比较特殊,假设p为格式中指定的保留小数位数,先尝试采用科学计数法格式化,得到幂指数exp,如果-4<=exp<p,则采用小数计数法,并保留p-1-exp位小数,否则按小数计数法计数,并按p-1保留小数位数
>>> format(0.00003141566,'.1g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点
'3e-05'
>>> format(0.00003141566,'.2g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留1位小数点
'3.1e-05'
>>> format(0.00003141566,'.3g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留2位小数点
'3.14e-05'
>>> format(0.00003141566,'.3G') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点,E使用大写
'3.14E-05'
>>> format(3.1415926777,'.1g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留0位小数点
''
>>> format(3.1415926777,'.2g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留1位小数点
'3.1'
>>> format(3.1415926777,'.3g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留2位小数点
'3.14'
>>> format(0.00003141566,'.1n') #和g相同
'3e-05'
>>> format(0.00003141566,'.3n') #和g相同
'3.14e-05'
>>> format(0.00003141566) #和g相同
'3.141566e-05'