语法进阶
引用
def test(num):
print("在函数内部 %d 对应的内存地址是 %d" % (num, id(num)))
# 1> 定义一个字符串变量
result = "hello"
print("函数要返回数据的内存地址是 %d" % id(result))
# 2> 将字符串变量返回,返回的是数据的引用,而不是数据本身
return result
# 1.定义一个数字的变量
a = 10
# 数字的地址本质上就是一个数字
print("a 变量保存数据的内存地址是 %d" % id(a))
# 2.调用test函数,本质上传递的是参数保存数据的引用,而不是实参保存的数据的引用
# 注意:如果函数有返回值,但是没用定义变量接受
# 程序不会报错,但是无法获得返回结果
r = test(a)
print("%s 的内存地址是 %d" % (r, id(r)))
- 输出
a 变量保存数据的内存地址是 140712361203648
在函数内部 10 对应的内存地址是 140712361203648
函数要返回数据的内存地址是 2397674202672
hello 的内存地址是 2397674202672
可变和不可变类型
# 不可变类型,地址不变,内存中的数据不允许被修改
# 数字类型int bool float complex long(2, x)
# 字符串 str
# 元组 tuple
# 可变类型,地址不变,内存中的数据可以被修改
# 列表 list
# 字典 dict
# 列表
a = [1, 2, 3]
print(id(a))
a.append(999)
print(a)
print(id(a))
a.remove(2)
print(a)
print(id(a))
a.clear()
print(a)
print(id(a))
a = []
print(id(a))
# 字典
# 注意:字典中的key只能使用不可变类型的数据
d = {"name": "xiaoming"}
print(d)
d["age"] = 18
print(d)
print(id(d))
d.pop("age")
print(d)
print(id(d))
d = {}
print(id(d))
- 输出
2850887492864
[1, 2, 3, 999]
2850887492864
[1, 3, 999]
2850887492864
[]
2850887492864
2850887492928
{'name': 'xiaoming'}
{'name': 'xiaoming', 'age': 18}
2850887446592
{'name': 'xiaoming'}
2850887446592
2850887446656
局部变量和全局变量
局部变量
def demo1():
# 定义一个局部变量
# 局部变量是在函数内部定义的变量,只能在函数内部使用
# 不同的函数,可以定义相同的名字的局部变量,但是彼此之间不会产生影响
# 1> 出生:执行了下方的代码之后,才会被创建
# 2> 死亡:函数执行完成之后
num = 10
print("在demo1函数内部的变量是 %d" % num)
def demo2():
num = 99
print("demo2 ==> %d" % num)
pass
# 在函数内部定义的变量,不能在其他位置使用
# print("%d" % num)
demo1()
demo2()
- 输出
demo1 ==> 10
demo2 ==> 99
修改全局变量
num = 10
def demo1():
# 希望修改全局变量的值
# 在python中,是不允许直接修改全局变量的值
# 如果使用赋值语句,会在函数内部,定义一个局部变量
# 希望修改全局变量的值--使用global声明一下变量即可
# global关键字会告诉解释去后面的变量是一个全局变量
# 再使用复制语句时,就不会创建局部变量
global num
num = 99
print("demo1 ==> %d" % num)
def demo2():
print("demo2 ==> %d" % num)
demo1()
demo2()
- 输出
demo1 ==> 99
demo2 ==> 99
全局变量的位置及命名
# 注意:在开发时,应该把模块中的所有全局变量定义在所有函数的上方
# 就可以保证所有的函数都能够正常的访问到每一个全局变量了
num = 10
title = "aixuexideamelia"
name = "amelia"
def demo():
print("%d" % num)
print("%s" % title)
print("%s" % name)
demo()
# 全局变量命名
# 如果局部变量的名字和全局变量的名字相同
# pycharm会在局部变量下方显示一个灰色的虚线
- 输出
10
aixuexideamelia
amelia
函数返回类型为元组,处理办法
def measure():
"""
测量温度和湿度
"""
print("测量开始...")
temp = 39
wetness = 50
print("测量结束...")
# 元组-可以包含多个数据,因此可以使用元组让函数一次返回多个值
# 如果函数返回的类型时元组,小括号可以省略
# return (temp, wetness)
return temp, wetness
result = measure()
print(result)
# 需要单独的处理温度或者湿度-不方便
print(result[0])
print(result[1])
# 如果函数返回的类型时元组,同时希望单独的处理元组中的元素
# 可以使用多个变量,一次接收函数的返回结果
# 注意:使用多个变量接受结果时,变量的个数应该和元组中的个数保持一致
gl_temp, gl_wetness = measure()
print(gl_temp)
print(gl_wetness)
- 输出
测量开始...
测量结束...
(39, 50)
39
50
测量开始...
测量结束...
39
50
交换数字的方法–三种解法
# 交换数字
a = 6
b = 100
# 解法1:使用其他变量
# c = a
# a = b
# b = c
# 解法2:不适用其他变量
# a = a + b
# b = a - b
# a = a - b
# 解法3:python专有
# a, b = (b, a)
# 提示:等号右边是一个元组,只是把小括号省略了
a, b = b, a
print(a)
print(b)
- 输出
100
6
在函数内部,针对参数使用赋值语句
def demo(num, num_list):
print("函数内部的代码")
# 在函数内部,针对参数使用赋值语句,不会修改外到外部的实参变量
num = 100
num_list = [1, 2, 3]
print(num)
print(num_list)
print("函数执行完成")
gl_num = 99
gl_list = [4, 5, 6]
demo(gl_num, gl_list)
print(gl_num)
print(gl_list)
- 输出
函数内部的代码
100
[1, 2, 3]
函数执行完成
99
[4, 5, 6]
函数中传递的参数为可变类型
# 如果传递的参数是可变类型,在函数内部,使用方法修改了数据的内容,同样会影响到外部的数据
def demo(num_list):
print("函数内部的代码")
# 使用方法修改列表的内容
num_list.append(9)
print(num_list)
print("函数执行完成")
gl_list = [1, 2, 3]
demo(gl_list)
print(gl_list)
- 输出
函数内部的代码
[1, 2, 3, 9]
函数执行完成
[1, 2, 3, 9]
+=的使用
def demo(num, num_list):
print("函数开始")
# 有了赋值的语句就不会影响外部的结果
# num = num + num
num += num
# 列表变量使用 + 不会做相加再赋值的操作!
num_list = num_list + num_list
# 本质上是在在调用 extend 方法
# num_list += num_list
# num_list.extend()
print(num)
print(num_list)
print("函数完成")
gl_num = 9
gl_list = [1, 2, 3]
demo(gl_num, gl_list)
print(gl_num)
print(gl_list)
# 总结:+= 针对字符串都是先相加再赋值,
# 而针对列表变量 += 是在执行列表变量的extend方法,不会改变变量的引用
- 输出结果
函数开始
18
[1, 2, 3, 1, 2, 3]
函数完成
9
[1, 2, 3]
缺省参数
# 缺省参数
# 定义函数时,可以给某个参数指定一个默认值,具有默认值的参数就叫做缺省参数
# 调用函数时,如果没用传入缺省参数的值,则在函数内部使用定义函数时指定的参数默认值
# 函数的缺省参数,将常见的值设置为参数的缺省值,从而简化函数的调用
gl_list = [6, 3, 9]
# 默认按照升序排序 - 可能会多!
gl_list.sort()
print("升序:", gl_list)
# 如果需要降序排序,需要执行reverse参数
gl_list.sort(reverse=True)
print("降序:", gl_list)
- 输出结果
升序: [3, 6, 9]
降序: [9, 6, 3]
指定函数的缺省参数
# 指定函数的缺省参数
def print_info(name, gender=True):
"""
:param name: 班上同学的姓名
:param gender: True 男生 False 女生
"""
gender_text = "男生"
if not gender:
gender_text = "女生"
print("%s 是 %s" % (name, gender_text))
# 假设班上的同学,男生居多!
# 提示:在指定缺省参数的默认值时,应该使用最常见的值作为默认值!
# 如果一个参数的值不能确定,则不应该设置默认值,具体的数值在调用函数时,由外界传递!
print_info("小明")
print_info("amelia", gender=False)
- 输出结果
小明 是 男生
amelia 是 女生
缺省函数注意点
# 缺省函数注意点
def print_info(name, title="", gender=True):
"""
:param title: 职位
:param name: 班上同学的姓名
:param gender: True 男生 False 女生
"""
gender_text = "男生"
if not gender:
gender_text = "女生"
print("[%s]%s 是 %s" % (title, name, gender_text))
# 假设班上的同学,男生居多!
# 提示:在指定缺省参数的默认值时,应该使用最常见的值作为默认值!
# 如果一个参数的值不能确定,则不应该设置默认值,具体的数值在调用函数时,由外界传递!
print_info("小明")
print_info("amelia", gender=False)
- 输出结果
[]小明 是 男生
[]amelia 是 女生
多值参数
# 多值参数 *args--存放元组参数
# **args--存放字典参数
def demo(num, *nums, **person):
print(num)
print(nums)
print(person)
print("1.demo(1)")
demo(1)
print("-" * 50)
print("2.demo(1, 2, 3, 4, 5, name=\"小明\", age=18)")
demo(1, 2, 3, 4, 5, name="小明", age=18)
- 输出结果
1.demo(1)
1
()
{}
--------------------------------------------------
2.demo(1, 2, 3, 4, 5, name="小明", age=18)
1
(2, 3, 4, 5)
{'name': '小明', 'age': 18}
多值参数求和
def sum_numbers(*args):
num = 0
print(args)
# 遍历循环
for n in args:
num += n
return num
result = sum_numbers(1, 2, 3, 4, 5)
print(result)
- 输出结果
(1, 2, 3, 4, 5)
15
元组变量和字典变量拆包
def demo(*args, **kwargs):
print(args)
print(kwargs)
# 元组变量/字典变量
gl_nums = (1, 2, 3)
gl_dict = {"name": "小明", "age": 18}
# 没有拆包
print("1.输出demo(gl_nums, gl_dict):")
demo(gl_nums, gl_dict)
# 拆包语法,简化元组变量/字典变量的传递
# 将一个字典变量直接传递给args ,在元组变量前,增加一个*
# 将一个字典变量直接传递给kwargs ,在字典变量前增加两个*
print("2.输出demo(*gl_nums, **gl_dict):")
demo(*gl_nums, **gl_dict)
print("3.输出demo(1, 2, 3, name=\"小明\", age=18):")
demo(1, 2, 3, name="小明", age=18)
- 输出结果
1.输出demo(gl_nums, gl_dict):
((1, 2, 3), {'name': '小明', 'age': 18})
{}
2.输出demo(*gl_nums, **gl_dict):
(1, 2, 3)
{'name': '小明', 'age': 18}
3.输出demo(1, 2, 3, name="小明", age=18):
(1, 2, 3)
{'name': '小明', 'age': 18}
递归
# 递归--一个函数内部调用自己
# 函数内部的代码是相同的,只是针对参数不同,处理的结果不同
# 当参数满足一个条件时,函数不再执行。被称为递归的出口,否则会出现死循环
def sum_number(num):
print(num)
# 递归的出口,当参数满足某个条件时,不再执行函数
# 递归的出口很重要,否则会出现死循环
if num == 1:
return
# 自己调用自己
sum_number(num - 1)
sum_number(3)
- 输出结果
3
2
1
使用递归从1加到100
# 定义一个函数sum_numbers
# 能够接受一个num的整数参数
# 能计算 1 + 2 + ... num 的结果
def sum_numbers(num):
# 1.出口
if num == 1:
return 1
# 2.数字的累加
# 假设sum_numbers 能够正确的处理 1...num - 1
temp = sum_numbers(num - 1)
# 两个数字的相加
return num + temp
result = sum_numbers(100)
print(result)
- 输出结果
5050