社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
从今天开始,我就不用“学习之路”这个标题了,感觉突出不了重点,都没啥人看啊!前面我们已经学习了Python的基础语法,了解了Python的分支结构,也就是选择结构、循环结构以及函数这些具体的框架,还学习了列表、元组、字典、字符串这些Python中特有的数据结构,还用这些语法完成了一个简单的名片管理系统。下面我就将介绍一下Python的一些进阶语法规则,为后面更复杂的编程打下基础。
引用这个名词相信学过C语言和C++指针的同学应该有点印象,引用和指针还是一个很容易被混淆的概念。简单来说,引用是一个变量,是另外一个你想被引用的变量的别名,就像是你给某个人起的一个外号,你用这个外号来代替他的名字来称呼他,类似于一个副本。在Python中,变量和数据是分开存储的,数据保存在内存中的一个位置,变量中保存数据在内存中的地址。变量中记录数据的地址,就叫做引用。下面是在终端中运行ipython这个Python的交互式窗口,其中id()函数是返回对象的内存地址。
a = 1实际上就是将a这个标签贴在1上,b = a同样也是把b这个标签贴在1上,所以b和a都是1的引用,当a = 2时,a这个标签就会贴在2上,然而b不会因为b = a这个语句发生变化,其任然是1的引用。
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 变量保存数据的内存地址是 10914784
在函数内部 10 对应的内存地址是 10914784
函数要返回数据的内存地址是 139989701883752
hello 的内存地址是 139989701883752
简而言之,局部变量就是在函数内部定义的变量,只能在函数内部使用(后面会学类,在类内部使用),在函数外部不可被发现,不可被使用。全局变量就是定义在模块内,在所有的函数、类的外面。
局部变量:
def demo1():
# 定义一个局部变量
# 1.出生:执行了下方的代码之后,才会被创建
# 2.死亡:函数执行完成之后
num = 10
print("在demo1函数内部的变量是 %d" % num)
def demo2():
num = 99
print("%d" % num)
pass
# 在函数内部定义的变量,不能在其他位置使用
# print(num) 这里如果这样写的话会报错
demo1()
demo2()
# 运行结果
在demo1函数内部的变量是 10
99
全局变量:
# 全局变量
num = 10
def demo1():
print("demo1 ==> %d" % num)
def demo2():
print("demo2 ==> %d" % num)
demo1()
demo2()
# 运行结果
demo1 ==> 10
demo2 ==> 10
函数不能修改全局变量的值,因为函数是处于局部之内,但是如果函数想修改全局变量的话可以将变量前声明成global,这样这个变量就变成了全局变量。global 关键字会告诉解释器后面的变量是一个全局变量,再使用赋值语句时就不会创建局部变量。我们在开发程序时,应该将所有的全局变量放在代码开始的地方,也就是先导入包和模块,再就是定义全局变量,这样在后面使用的时候就不会出问题。
Python函数可以有多个返回值,当有多个返回值时,其返回的数据类型是元组,可以使用多个变量来接收元组里的数据,但要保持数量一致。
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
学C语言的时候肯定遇到过一个题目叫你交换两个变量的值,冒泡排序的时候就会用到,什么t = a[j];a[j] = a[j+1];a[j+1] = t;这样的东西,转来转去是不是贼麻烦。Python中有一种特有的方法来交换两个变量的值:a, b = (b, a) 就这么一个语句就可以交换a,b两个变量的值。
在函数内部,针对参数使用赋值语句,不会修改到外部的实参变量;但是如果使用的是方法,也就是函数,可以修改实参变量。
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]
前面讲列表那一块的时候有介绍到sort()函数,默认是升序排序,如果添加一个参数sort(reverse=True)的话就是降序排序了,这里sort函数中的reverse就是一个缺省参数,默认有缺省值。函数在定义时,如果某个参数设置了默认值,那么在调用这个函数的时候,想默认使用的话就可一不用传递参数,如果传递参数的话,就会修改默认值。在指定缺省参数的默认值时,应该使用最常见的值作为默认值。
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("老王")
print_info("小美", False)
当一个Python函数想要接收不定个数的参数时就可以使用多值参数。多值参数有两种:一种是参数前面加一个*;另一种是参数前面加两个*。例如:*args:存放元组参数;**kwargs:存放字典参数。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200306153243421.png
def demo(num, *nums, **person):
print(num)
print(nums)
print(person)
demo(1)
demo(1, 2, 3, 4, name="小明", age=18)
# 运行结果
1
()
{}
1
(2, 3, 4)
{'name': '小明', 'age': 18}
num是默认是一个数字变量,所以输出一个1;*nums是元组,输出为(2, 3, 4);**person是字典,输出为{‘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)
print(result)
# 运行结果
(1, 2, 3)
6
在调用带有多值参数的函数时,如果希望将一个元组变量传递给args,将一个字典变量传递给kwargs,就可以选择拆包,简化参数传递,也就是告诉函数,我这里的哪一部分是元组,我要你全部输出,那一部分是字典,再全部输出,相当于打了一个包。
def demo(*args, **kwargs):
print(args)
print(kwargs)
# 元组变量/字典变量
gl_nums = (1, 2, 3)
gl_dict = {"name": "小明", "age": 18}
# demo(gl_nums, gl_dict)
# 拆包语法,简化元组变量/字典变量的传递
demo(*gl_nums, **gl_dict)
demo(1, 2, 3,name="小明", age=18)
# 运行结果
(1, 2, 3)
{'name': '小明', 'age': 18}
(1, 2, 3)
{'name': '小明', 'age': 18}
大家学过C语言的应该都了解一点递归,递归函数就是函数自己调用自己,在自己调用自己的时候,要给出递归的出口,不然函数就会一直执行下去,成了个死循环。有时候解决复杂问题时可以选择递归,但是有的时候递归会占用过多的内存和时间。
def sum_number(num):
print(num)
# 递归的出口,当参数满足某个条件时,不再执行函数
if num == 1:
return
# 自己调用自己
sum_number(num-1)
sum_number(3)
# 运行结果
3
2
1
访问量破千,一起加油!
写博客是为了记录和分享自己的学习历程,温故知新!做的不好的地方欢迎指正!!!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!