Python语法进阶 - Go语言中文社区

Python语法进阶


前言

从今天开始,我就不用“学习之路”这个标题了,感觉突出不了重点,都没啥人看啊!前面我们已经学习了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

最后

访问量破千,一起加油!

写博客是为了记录和分享自己的学习历程,温故知新!做的不好的地方欢迎指正!!!

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_43779324/article/details/104693989
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢