函数
print('zhangtao')
print('zhang')
print('tao')
普通的三行代码不算一个函数,无法重复构造。怎样才能使他重复使用?
进行函数构造,放在函数块(代码块)中
定义函数
- 定义函数的语法格式 def 函数名称 (): def代表函数的关键字
- 操作函数 例如:给函数赋值、给函数定义变量、常量等。调用函数必须有
- 作用:可以将代码重复利用,必须很大大量的中复代码的实现,并且利用函数代码容易维护。可以降低软件间的耦合度。–解耦性
def Num():
print('zhangtao')
print('zhang')
print('tao')
# 调用函数
Num()
1. 定义规则
- 任何传入参数和自变量必须放在圆括号内
def Num1(a):
print('a的值:',a)
# 调用函数Num1
Num1(3) # 通过函数给变量a赋值。操作效率高!
- 函数的第一行语句可以选择性的使用文档字符串–用于存放函数说明
def sum(a,b):
"""
注释:此函数是项目中用于XXXX工作的函数()
"""
print('a的值:',a)
print('b的值:',b)
# 通过函数名称给变量a b赋值
sum(100,1000)
备注:通过以上代码可知,函数可以带多个参数甚至N个
2. 调用函数
内置函数可以直接调用。调用一个函数需要知道函数的名称和函数的参数。
语法 函数名([参数列表])
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋值给一个变量,相当于给这个函数起了一个别名
# 给函数其别名
def Num3(a):
pri = Num3(a) # 将函数给一个变量
print(pri)
Num3(1000)
函数参数
1、参数类型
形参 实参
2、 函数参数分类
- 必备参数
函数定义中允许拥有多个形参,因此函数在调用的时候,也可能包含多个实参。向函数传递参数的方式有很多,通过实参和形参的顺序对应,这就是位置实参。只有位置一致,才能被正确匹配。位置实参是最简单也最常用的关联方式。
# 位置参数: 实参和形参位置一一对应
def Num4(a = 10, b = 1, c =3):
print('a', a)
print('b', b)
print('c', c)
Num4(1, 2, 3)
- 关键字参数
关键字实参是传递给函数的名称-值对。直接在实参中将名称和值关联起来,因此向函数传递实参时不会混淆。函数调用使用关键字参数来确定传入的值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
# 关键字参数:python解释器根据参数名匹配参数值,可以解决实参、形参顺序不一致问题
def Num5(a, b):
print('a', a)
print('b', b)
Num5(a='aaa',b='bbb')
- 默认参数
函数定义的时候,设置的参数是形参。那么也可以给每个形参指定一个默认值。当调用函数时,如果没有传入实参,就使用形参的默认值。如果调用的时候传入了实参,那么程序将使用传入的实参。
"""
参数默认值: 通过pet1赋值将pet2的值指定了一个位置或者具体的值,这个值称为默认值。
不建议使用,python解释器解释时会将实参形参混淆。
"""
def animal(pet2,pet1='dog'):
print('pet2', pet2)
print('pet1', pet1)
animal('cat')
animal('cat','mouse') # 实参可以是任意类型
- 不定长参数
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数。
*表示一个通配符,表函数里面可有多个不确定的形参。 *的类型时tuple元组
** 表示在函数调用处直接赋值、定义实参,不需要函数名括号内定义实参。 **的类型是dict字典
# 不定长参数
def getMessage(name,address,*tup_args,**dict_args):
print('name:',name)
print('address:',address)
print('tup_args',tup_args,type(tup_args))
print('dict_args',dict_args,type(dict_args))
getMessage('zt','beijing',1,'c',age = 18)
def PName(name): # name为形参
print('姓名是:',name)
PName('张涛') # 张涛为实参
# 定义了形参,必须有实参,没有实参报空指针异常!
3、 可变对象与不可变对象
- strings, tuples, 和 numbers 是不可更改的对象
- list,dict,set等则是可以修改的对象。
- 区别:
- 不可变对象,传递的是对象的值,不是对象本身,如果修改值,修改的是另一个复制的对象,不会影响原来对象的本身
- 可变对象,传递对象自己。函数内部如果修改值会影响对象本身。
def args1(a):
a = 'zhangtao'
print('a',a)
str = '4'
args1(str)
print('值不变:',args1(str)) # 值不变: None
函数返回值
1、return语句
def max(x,y):
if x > y:
return x
else:
return y
print(max(3,4))
2、接收返回值
def re(a,b):
return a+b
# 函数在内存的地址
print(re)
# 调用函数看结果
print(re(1,2))
# 保存函数返回值
sum1 = re(1,2)
print(sum1)
3、 Return和print区别
- print是将结果输出到控制台,不是数据
- return语句返回客户端浏览器的一行数据
- return返回的是一个程序所控制的一个数据结果集
- print没什么程序价值
- return以后的代码不执行
def returnMany(sum1,sum2,sum3):
return sum1,sum2,sum3
sum1,sum2,sum3 = returnMany(1,2,3)
# 一次性返回单个值
print(sum1,type(sum1))
print(sum2)
print(sum3)
# 一次性返回多个值
sum1 = 11
sum2 = 22
sum3 = 33
print(returnMany(sum1,sum2,sum3),type(returnMany(sum1,sum2,sum3)))
- python的返回值的id地址可以是同一个(变量的值相同,变量的名称可以不同)。
- 这样的目的为了节省内存空间,python的return可以返回海量数据,Java不行
- return一次性可返回多个值,但是会保存到元组中,但不建议使用。
4、生成器 yield
yield 的作用
- 把一个函数变成一个generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个生成器
yield的核心
-
实际就是next方法和iter方法 此方法不建议使用,没有next方法的效率高。不管是next还是iter,它们最后返回的都是一个’迭代器’对象,next方法更加接近迭代器的迭代原理。
-
yield和生成器的next方法可以返回多个值,python中此方法返回多个值是独一无二的!
def Xun(max):
n=0
b=1
while n < max:
yield b
print(b)
b+=1
n = n + 1
Xun(5)
print(next(Xun(5))) # 1
print(next(Xun(5))) # 1
print(next(Xun(5))) # 1
"""
每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。
并在下一次从当前位置继续运行。所以只会返回1
"""
5、 迭代器 iterator
迭代器的作用和特性
- 通过iter()方法将数据从内存里面取到。获取后交给next方法去执行遍历结果集
- 先有iter再有next iter()和内存数据有关,next无关所以通过next方法操作数据是安全的。
- 迭代器有start开始必须有end结束! 中途不能中断(因为传递的是数据)
- 生成器send方法表示将当前的yield的值返回,不执行next方法,但next本身可以执行到最后,程序结束。所以这样send方法是安全的!
变量的作用域
- Java中权限关键字:protected private public default
- python没有关键字
1、 局部变量
- 局部变量只能在本函数内使用。
- 对于局部变量来说,不同/同变量名变量值相同,内存地址相同。相同变量名变量值不同,内存地址不同。
def test1():
a=100
print('a',a)
print('a的内存地址:',id(a))
def test2():
a=10
print('调用啊',a)
print('a的内存地址:',id(a))
test1()
test2()
2、全局变量
- 全局变量是声明在函数外部的变量,定义在函数外的拥有全局作用域
修改全局变量的值
global关键字
要想在函数内部修改全局变量的值,需要使用grobal关键字声明
# 修改全局变量
a = 100
print('全局变量a:',a)
print(id(a))
def test3():
global a
a=200
print('使用global修改全局变量a',a)
print(id(a))
def test4():
print('不使用global修改全局变量a',a)
print(id(a))
test3()
test4()
"""
结果:
全局变量a: 100
1383954544
使用global修改全局变量a 200
1383957744
不使用global修改全局变量a 200
1383957744
"""