一、函数的基本使⽤
函数的作⽤,在开发程序时,使⽤函数可以提⾼编写的效率以及代码的重⽤
函数的定义
def 函数名():
函数封装的代码
……
1.def 是英⽂ define 的缩写
2.函数名称 应该能够简单明确的表达 函数功能,以⽅便后续的调⽤
3.函数名称 的命名应该 符合 标识符的命名规则
可以由 字⺟、下划线 和 数字 组成
不能以数字开头
不能与关键字重名
函数调用
调⽤函数很简单的,通过 函数名() 即可完成对函数的调⽤
注意:不能将 函数调⽤ 放在 函数定义 的上⽅,因为在 使⽤函数名 调⽤函数之前,必须要保证 Python 已经知道函数的存在
函数的⽂档注释
在 连续的三对引号 之间编写对函数的说明⽂字
在 函数调⽤ 位置,使⽤快捷键 CTRL + Q 可以查看函数的说明信息
def func_sum(): """求和 1+2""" sum_num = 1 + 2 print(sum_num) func_sum()
二、函数的参数
函数的参数,可以传递数据给函数内部,增加函数的 通⽤性
设置函数的参数
在函数名的后⾯的⼩括号内部填写 参数
多个参数之间使⽤ , 分隔
def sum_2_num(num1, num2): result = num1 + num2 print("%d + %d = %d" % (num1, num2, result)) sum_2_num(50, 20)
形参和实参
形参:定义函数 时设置的参数,是⽤来 代替真实数据 的,在函数内部作为变量使⽤
实参:调⽤函数 时设置的 真实数据,会被传递到 函数内部
a = 5 def test1(a): a += 1 print("%d" % a) test1(2) print("%d" % a)
结果为3、5
形参的作⽤域(起作⽤的范围) 只在定义函数的代码块 中,⼀旦超出该范围再使⽤该形参名,则使⽤的是 同名的⾃定义变量
编程中应该尽量避免 函数的形参 和 同⽂件的变量名 同名
三、函数的返回值
在函数中使⽤ return 关键字可以返回结果
def sum_2_num(num1, num2): """对两个数字的求和""" return num1 + num2 # 调⽤函数,并使⽤ result 变量接收计算结果 result = sum_2_num(10, 20) print("计算结果是 %d" % result)
注意: return 表示返回,后续的代码都不会被执⾏
4种函数的类型
⽆参数,⽆返回值
⽆参数,有返回值
有参数,⽆返回值
有参数,有返回值
四、局部变量
局部变量,就是在 函数内部定义的变量
不同的函数,可以定义相同的名字的局部变量,但是各⽤个的不会产⽣影响
局部变量的作⽤域只在函数内部
局部变量的⽬的是 存储需要临时保存的数据
# 函数中的两个局部变量虽然同名,但互不影响 def test1(): a = 10
print("%d" % a) def test2(): a = 5
print("%d" % a) test1() test2()
五、全局变量
在函数外边定义的变量叫做 全局变量
全局变量能够在所有的函数中进⾏访问
# 定义全局变量 a = 100 def test1(): print(a) def test2(): print(a) # 调⽤函数 test1() test2()
结果:
100 100
函数内修改全局变量
a = 10 def test(): a = 5 print("函数内a:%d" %a) test() print("函数外a:%d" %a)
结果
函数内a:5 函数外a:10
函数内赋值变量 时,默认为定义并赋值局部变量,赋值后获取的也是局部变量的值
如果在函数中修改全局变量,那么就需要使⽤ global 进⾏声明,否则出错
a = 10 def test(): global a a = 5 # 修改全局变量 print("函数内a:%d" %a) test() print("函数外a:%d" %a)
结果如下:
函数内a:5 函数外a:5
六、多个返回值
当返回多个数据时,python会⾃动将数据 组包 成元组
如果使⽤多个变量接收返回值,python会⾃动将元组 拆包 成单个数据
def func2(): return 1, 1.5 a = func2() print(a) a, b = func2() print(a) print(b) a, b, c = 1, 1.5, "hello" print(a) print(b) print(c)
结果
(1, 1.5) 1 1.5 1 1.5 hello
七、默认参数
形参设定默认值 称为 默认参数
调⽤函数时,如果没有传⼊默认参数对应的实参,则实参使⽤默认值。
def printinfo(name, age = 35): # 打印任何传⼊的字符串 print("Name: %s" % name) print("Age: %s" % age) # 调⽤printinfo函数 printinfo("miki") printinfo("miki", 20)
结果
Name: miki Age: 35 Name: miki Age: 20
注意:默认参数⼀定要位于参数列表的最后⾯。
八、关键字参数
调⽤函数时,实参可以指定对应的形参,称为 关键字参数
def printinfo(name, age): # 打印任何传⼊的字符串 print("Name: %s"% name) print("Age: %s" % age) printinfo(age=9,name="miki" )
结果
Name: miki Age: 9
九、可变参数
args
函数可以定义 可变参数,⽤于接收任意数量的参数
使⽤可变参数直接⽤args即可(不需要加*)
可变参数的本质是 将传递的参数包装成了元组
def sum_num(a, b, *args): result = a + b for temp in args: result += temp return result val = sum_num(1, 2, 3, 4, 5) print("值为%d" % val) # 关键字参数⼀旦使⽤,所有实参都要使⽤,除⾮该实参对应的是可变参数 # # sum_num(1, 2, 3, 4, a=5) val1 = sum_num(a=5, b=4) print("值为%d" % val1)
结果
值为15
值为9
kwargs
可变参数还有⼀种形式 可以接收不存在的关键字参数
定义参数时需要在变量名前添加两个*
这种可变参数会将 不存在的关键字参数包装成字典
def sum_num(a, b, *args, **kwargs): print(a) print(b) print(args) print(kwargs) sum_num(1, 2, 3, 4, 5, mm=5, nn=6)
结果
1 2 (3, 4, 5) {'mm': 5, 'nn': 6}
传递可变参数
def sum_num(a, b, *args, **kwargs): print(a) print(b) print(args) print(kwargs) test(*args, **kwargs) def test(*args, **kwargs): print(args) print(kwargs) sum_num(1, 2, 3, 4, 5, mm=5, nn=6)
结果
1 2 (3, 4, 5) {'mm': 5, 'nn': 6} (3, 4, 5) {'mm': 5, 'nn': 6}
十、拆包
拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
除了对元组拆包之外,还可以对列表、字典等拆包
对字典进行拆包,取出来的是key,⽽不是键值对
def get_my_info(): high = 178 weight = 100 age = 18 return high, weight, age # result = get_my_info() # print(result) my_high, my_weight, my_age = get_my_info() print(my_high) print(my_weight) print(my_age)
结果
178 100 18
十一、引⽤
1、普通变量的引用,变量赋值时,赋的是值的内存地址,变量指向的是值所在内存中的地址。
看上去是值传递,实际上是引用地址的传递。传递的是地址,这样就不用去找值,速度会更快,而用的是地址中的值。
2、列表的引用:是引用地址在传递,而不是值在传递。
a = [1,2] b = a a.append(3) print(a) print(b) print(id(a)) print(id(b))
结果:
[1, 2, 3] [1, 2, 3] 2223509095040 2223509095040
3、小数字缓存池:当我们执行Python程序的时候,Python解释器会将 -5~256之间的数全部开辟好空间,
a = 10 b = 10 print(id(a)) print(id(b))
结果:两个地址一样
2963836594768 2963836594768
但是Python解释器为了提升性能,如果之前定义了的值都会缓存起来,
a = 257 b = 257 print(id(a)) print(id(b))
结果:相同
1750546741584 1750546741584
-5~256之间的数,不管你是怎么计算得来的,都是同一个地址,如果超出了这个范围,则不是同一个地址
a = 256 b = int(25.6*10) print(id(a)) print(id(b))
结果:
2493375801744 2493375801744
如果超出了这个范围,则不是同一个地址
a = 257 b = int(25.7*10) print(id(a)) print(id(b))
结果:
2034141329744 2034141329808
4、字符串缓存:最大缓存位数是20位。
str1 = "hello" str2 = "hello" print(id(str1)) print(id(str2))
结果:
2465391472816 2465391472816
总结:
1)、两个变量引用的内存地址相同,那么这两个变量的值肯定相同。
2)、两个变量引用的内存地址不同,变量的值有可能相同。
python中可以使⽤ id函数查看引⽤的是否为同⼀个内存空间,如果返回值相同,说明引⽤相同
在python中,值是靠引⽤来传递的。
>>> a = 1 >>> b = a >>> id(a) 13033816 >>> id(b) # 注意两个变量的id值相同 13033816 >>> a = 2 >>> id(a) # 注意a的id值已经变了 13033792 >>> id(b) # b的id值依旧 13033816
>>> a = [1, 2] >>> b = a >>> id(a) 139935018544808 >>> id(b) 139935018544808 >>> a.append(3) >>> a [1, 2, 3] >>> id(a) 139935018544808 >>> id(b) # 注意a与b始终指向同⼀个地址 139935018544808
十二、可变类型与不可变类型
可变类型:就是可以修改存储空间中的数据,内存地址不变。
不可变类型就是存储空间中的数据不能修改。
a = 1 print(id(a)) a = 2 print(id(a))
结果:
2169985722672 2169985722704
说明数值类型是不可变类型
可变类型,值可以改变:
列表 list(增删改时,值变了,但是地址没变)
字典 dict
dict1 = {"a" : 10} print(id(dict1)) dict1["age"] = 18 print(id(dict1))
结果:
1691438038336 1691438038336
不可变类型,值不可以改变:
数值类型 int, long, bool, float
字符串 str
元组 tuple
函数的默认参数尽量不要使用可变类型。
tuple = (1,2) tuple[1] = 3 print(tuple)
结果:
但是如果对tuple中的list进行修改,则没问题。
list1 = [1,2] tuple = (list1,3) tuple[0].append(3) print(tuple)
结果:
([1, 2, 3], 3)