Python基础篇——Day6

变量的作用域

变量起作用的范围称为变量的作用域,不同作用域内同名变量之间互不影响,变量分为:

  1. 全局变量
  2. 局部变量

全局变量

  1. 在函数和类定义之外的变量,作用域为定义的模块,从定义开始的位置直到模块结束
  2. 全局变量降低了函数的通用性和可读性,故应尽量避免全局变量在函数定义过程中的使用
  3. 全局变量一般作常量使用
  4. 函数内要使用全局变量的值,可使用global声明

局部变量

  1. 在函数体内(包含形参)声明的变量
  2. 局部变量的查询和访问比全局变量快,故可优先考虑使用,尤其是在循环的时候
  3. 若局部变量与全局变量同名,则在函数内隐藏全局变量,只使用同名的局部变量

操作示例:

a=3 #全局变量
def test1():
	b=1 #局部变量
	print(b)
>>>print(a)
3
>>>print(b)
NameError: name 'b' is not defined
a=3 #全局变量
def test1():
	b=1 #局部变量
	a=300 # 在函数体中,优先使用与全局变量a同名的局部变量
	print(a)
>>>test1()
300
>>>print(a)
3
a=3 #全局变量
def test1():
	global a # 若想使用全局变量a的值,则需global声明
	a=300
	print(a)
>>>print(a)
300
>>>test1()
300

底层逻辑:
个人理解,在Python执行def命名时,在堆空间中创建了一个函数对象(包含所有相关的函数信息),随后将该对象的地址赋予栈空间中的函数名变量test1,即,test1指向堆空间中对应的函数对象,当用()调用函数时,Python会在栈空间中创建栈帧(Stack Frame),仅在栈帧内部放置局部变量,并执行函数体相关语句,在调用完毕后,栈帧被丢弃,等下一次调用时再次建立新的栈帧,以此往复

参数传递

函数参数传递的本质是从实参到形参的赋值操作,Python中一切皆对象,所有的赋值操作都是“引用的赋值”,所以,参数传递的过程是“引用传递”的过程,而不是“值传递”的过程

传递可变对象的引用

传递参数是可变对象(列表、字典、集合、自定义对象等),实际传递的还是对象的引用。在函数体中不创建新的对象拷贝,而是直接修改所传递的对象

操作示例:

'''
传递可变对象的引用
'''
b=[10,20]
def f2(m):
	print("m:",id(m)) # b和m指向同一个对象
	m.append(30) # 由于m是可变对象,不创建对象拷贝,直接修改这个对象(即列表)

f2(b)
print("b:",id(b)) # id(b)与id(m)的结果一致

传递不可变对象的引用

传递参数是不可变对象(例如字符串,元组,布尔值,数字等),实际传递的还是对象的引用,在传递时,由于不可变对象无法修改,系统会创建一个新的对象

操作示例:

'''
传递不可变对象的引用
'''
a=100
def f1(n):
	print("n:",id(n)) # 传递的是a所指向的对象的地址
	n=n+200 # 由于100是不可变对象,因此会创建新的对象
	print("n:",id(n)) # n指向新的对象,对象值为300

f1(n)
print("a:",id(a))
'''
结果为:
1663816464
46608592
1663816464
'''

参数的几种类型

位置参数

函数调用时,实参默认按位置顺序传递,需要个数和形参匹配,按照位置传递的参数,称为位置参数

操作示例:

'''
位置参数
'''
def f(a,b,c):
	print(a,b,c)
	
>>>f(2,3,4) # 位置匹配
>>>f(2,3) # 报错,位置不匹配

默认值参数

我们可以为某些参数设置默认值,这些参数在传递时就是可选的,称为默认值参数,默认值参数必须位于其它参数后面

操作示例:

'''
默认值参数
'''
def f(a,b,c=10): # c就是默认值参数
	print(a,b,c)

>>>f(8,9)
8 9 10
>>>f(8,9,19)
8 9 19

命名参数

我们也可以按照形参的名称传递参数,称为命名参数,也称关键字参数

操作示例:

'''
命名参数(关键字参数)
'''
def f1(a,b,c):
	print(a,b,c)

>>>f1(7,7,8) # 按位置传递,位置参数
7 7 8
>>>f1(c=9,b=1,a=3) # 按形参的名称传递,命名参数
3 1 9

可变参数

可变参数称为可变数量的参数,分两种情况:

  1. *param,将多个参数收集到一个元组对象中
  2. **param,将多个参数收集到一个字典对象中

操作示例:

'''
可变参数
'''
def f(a,b,*c):
	print(a,b,c)
>>>f(8,9,29,2)
8 9 (29, 2)
'''
可变参数
'''
def f(a,b,**c):
	print(a,b,c)
>>>f(8,9,i=100,j=200)
8 9 {'i': 100, 'j': 200}

强制命名参数

在带星号的可变参数后面增加新的参数,必须是强制命名参数

操作示例:

'''
强制命名参数
'''
def f(*a,b,c):
	print(a,b,c)
>>>f(2,3,4) # 报错,因为a是可变参数,会把实参全部收集为元组,导致b,c没有赋值
>>>f(2,b=3,c=4)
(2,) 3 4

lambda表达式和匿名函数

  1. lambda表达式可用来声明匿名函数,lambda表达式是一种简单的,在同一行中定义函数的方式。lambda表达式实际生成的是一个函数对象
  2. lambda表达式只允许包含一个表达式,不能包含复杂的语句,该表达式的计算结果就是函数的返回值

基本语法:
lambda arg1,arg2,arg3…: <表达式>
arg是函数的参数,<表达式>相当于函数体,运算结果就是函数的返回值

操作示例:

'''
lambda表达式
'''
f=lambda a,b,c:a+b+c
>>>f(2,3,4)
9

递归

这一块内容在此只做简单阐释,具体内容将在数据结构与算法篇呈现。
递归函数指的是:自己调用自己的函数,在函数体内部直接或间接地自己调用自己。递归需要包含两个部分:

  1. 终止条件
    即什么时候结束,一般结束的时候直接返回值而不再自己调用自己
  2. 递归步骤
    把第n步的值和n-1步相关联

递归函数会创建大量函数对象,大量消耗内存和运算能力,处理大量数据时应谨慎使用

操作示例:

'''
递归计算阶乘
'''
def factorial(n):
	if n==1:
		return 1
	else:
		return n*factorial(n-1)
>>>factorial(5)
120
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值