python学习笔记:局部变量与全局变量、返回多个返回值、缺省/不定长参数、引用传参、递归函数与匿名函数(二)

一、局部变量与全局变量

1.1、局部变量

局部变量:

  • 定义:局部变量,就是在函数内部定义的变量。
  • 特点:不同函数中的局部变量可以是相同的名字,它们之间不会相互影响。(C语言的语法相似)
  • 作用:临时保存数据需要在函数中定义变量来进行存储

示例:

def test1():
    a = 1
    print("修改前:%d" % (a))
    a = 2
    print("修改后:%d" % (a))


def test2():
    a = 3
    print("修改前:%d" % (a))


test1()
test2()

"""
运行结果为:
修改前:a = 1
修改后:a = 2
修改前:a = 3
"""

1.2、全局变量

全局变量:

  • 定义:在函数外面定义的变量是全局变量,每一个函数都可以使用。
  • 特点:相同变量名称的时候,函数在调用的时候先使用局部变量。

C语言中全局变量必须定义在函数定义之前声明,在编译的时候告诉编译器,这个变量已经定义过了,而python的全局变量,对于变量定义的前后位置不做要求。python函数必须要在函数使用前定义(同C语言的规则相同),因为在编译时,要做正确性检查。

示例:

a = 10

def test1():
    a = 20   # 局部变量
    print("修改前a = %d" % a)
    a = 30
    print("修改后a = %d" % a)


def test2():
    print("a = %d" % a) # 使用了全局变量

test1()
test2()

"""
运行结果为:
修改前a = 20
修改后a = 30
a = 10
"""

1.3、修改全局变量

全局变量在脚本中均可使用,但是在函数内无法进行修改。(除列表和字典数据类型的+=操作外)

在python中,定义一个变量和给变量赋值是相同的语法(这是与C语言的一个不同)。所以在函数内想要对全局变量进行赋值时,发现它就定义了一个局部变量。为了使得在函数内对全局变量进行修改,这时候就需要使用一个关键字global通过global关键字对变量的声明,告诉解释器这个变量是全局变量

a = 10 # 定义变量 or 变量赋值?

示例:

a = 10

def test1():
    global a        # 声明变量 a 是全局变量
    print("a = %d" % a)
    a = 20
    print("a = %d" % a)


def test2():
    print("a = %d" % a)

test1()
test2()

"""
运行结果为:
a = 10
a = 20
a = 20
"""

注意:int或者str型全局变量在函数内修改时,需要global修饰;如果是list或者dict,则在函数可以直接修改(仅限于单个元素修改)。

示例:

list1 = [1, 2]        # 全部变量
list2 = [11, 22]      # 全部变量

def test1():
    list1[0] = 2      # 全部变量
    return list1


def test2():
    list2 = [33, 22]  # 局部变量
    return list2

print(test1())
print(list1)

print(test2())
print(list2)


"""
运行结果为:
[2, 2]
[2, 2]
[33, 22]
[11, 22]
"""

nonlocal与global的作用是相似的,不同点在于,global针对于全局变量在函数可被修改,nonlocal针对于函数内的变量在其嵌套的函数中可被修改。

示例:

def test1():
    a = 1
    def demo():
        nonlocal a
        print("a = %d" % a)
        a = 20
        print("a = %d" % a)

    demo()
    print(a)

test1()

"""
运行结果为:
a = 1
a = 20
20
"""

二、返回多个返回值

return 的作用是,函数执行到return时,立即跳出函数,函数后面的程序不执行

示例:

def num(a, b):
    c = a + b
    d = a - b
    return c
    print("---") # 为了测试第二个return是否被执行了
    return d

c = num(20, 10)
d = num(20, 10)

print(c)
print(d)

"""
运行结果为:
30
30
"""

python中可以返回多个值:

# 格式
def 函数名(参数名1, 参数名2, .....):
	函数执行代码
	函数执行代码
	.........
	return 返回值1, 返回值2, ......
# 调用
依次存返回值变量1, 变量2, ... = 函数名(参数值1, ........)

示例:

def test1(a, b):
    c = a + b
    d = a - b
    return c, d

num1, num2 = test1(20, 10)
print(num1, num2)

"""
运行结果为:
30 10
"""

三、缺省/不定长参数与引用传参

3.1、缺省参数

缺省参数:调用函数时,缺省参数的值如果没有传入,则被认为是默认值。
格式:def 函数名(参数名1,参数2=默认值,…参数n=默认值):
调用时:函数名(值1)

注意:带有默认值的参数一定要位于参数列表的最后面。

示例:

def user_info(name, age = 16):
    print("name = %s" % name)
    print("age = %d" % age)

user_info("小李")
user_info("小李", 20)

"""
运行结果为:
name = 小李
age = 16
name = 小李
age = 20
"""

3.2、不定长参数

格式:def 函数名(参数名1, *args, **kwarg):
调用时:函数名(值1)

注意:

  • * 表示args可以存放所有未命名的变量参数,args为元组。
  • ** 表示kwarg可以存放命名参数,即形如key=value的参数, kwargs为字典。

示例:

def num(a, b, *args, **kwargs):
    print(a)
    print(b)
    print(args)
    print(kwargs)


num(1, 2, 3, 4, 5, m = "1", n = 2)

"""
运行结果为:
1
2
(3, 4, 5)
{'m': '1', 'n': 2}
"""

3.3、引用传参

3.3.1、可变类型与不可变类型的数据类型

可变类型,值可以改变:

  • 列表 (list)
  • 字典 (dict)

不可变类型,值不可以改变:

  • 数值类型 (int、long、bool、float)
  • 字符串 (str)
  • 元组 (tuple)

3.3.2、a += a 与 a = a + a 的区别

示例一:可变类型

a = [1,2,3]
print(id(a)) #打印内存地址
a += a
print(a)
print(id(a))

"""
运行结果为:
39060800
[1, 2, 3, 1, 2, 3]
39060800
"""
a = [1,2,3]
print(id(a)) #打印内存地址
a = a + a
print(a)
print(id(a))

"""
运行结果为:
38929728
[1, 2, 3, 1, 2, 3]
38941248
"""

可变类型:
+= :内存地址相同。
= : 内存地址不相同。

示例二:不可变类型

a = 10
print(a)
print(id(a))


a += a
print(a)
print(id(a))

"""
10
8791384971200
20
8791384971520
"""
a = 10
print(a)
print(id(a))


a =a + a
print(a)
print(id(a))

"""
10
8791348991936
20
8791348992256
"""

不可变类型:
+= :内存地址不相同。
= : 内存地址不相同。

小结:

  • 如果a是一个可变类型,那么a += a 是在a指向的内存中直接修改,a = a+a 是指向了一个新的内存。
  • 如果a是一个不可变类型,那么a += a 和a = a+a 的效果一样即:a指向了一个新的内存。

3.3.3、引用传参

python中函数参数是引用传递(注意不是值传递)。

  • 对于可变类型来说,函数体中的运算有可能会更改传入的参数变量。
  • 对于不可变类型,因变量不能修改,所以运算不会影响到变量自身。

示例一:可变类型

# a += a
def num(a):
    print("函数内:")
    print(id(a))  # 内存地址
    
    a += a
    
    print("a = %s" % a)
    print(id(a))
    print("函数外:")


a = [1, 2]

num(a)
print("a = %s" % a)
print(id(a))

"""
运行结果为:
函数内:
31196480
a = [1, 2, 1, 2]
31196480
函数外:
a = [1, 2, 1, 2]
31196480
"""
# a = a + a
def num(a):
    print("函数内:")
    print(id(a))  # 内存地址
    
    a = a + a
    
    print("a = %s" % a)
    print(id(a))
    print("函数外:")


a = [1, 2]

num(a)
print("a = %s" % a)
print(id(a))

"""
运行结果为:
函数内:
38995264
a = [1, 2, 1, 2]
39006784
函数外:
a = [1, 2]
38995264
"""

可变类型:
+= :实参与形参内存地址相同。
= : 实参与形参内存地址不相同。

示例二:不可变类型

# a += a
def num(a):
    print("函数内:")
    print(id(a))  # 内存地址
    
    a += a
    
    print("a = %d" % a)
    print(id(a))
    print("函数外:")


a = 10

num(a)
print("a = %d" % a)
print(id(a))

"""
运行结果为:
函数内:
8791384971200
a = 20
8791384971520
函数外:
a = 10
8791384971200
"""
# a = a + a
def num(a):
    print("函数内:")
    print(id(a))  # 内存地址
    
    a = a + a
    
    print("a = %d" % a)
    print(id(a))
    print("函数外:")


a = 10

num(a)
print("a = %d" % a)
print(id(a))

"""
运行结果为:
函数内:
8791384971200
a = 20
8791384971520
函数外:
a = 10
8791384971200
"""

不可变类型:
+= :内存地址不相同。
= : 内存地址不相同。

引用传参小结:

  • 如果a是一个可变类型,那么a += a 是传引用,a = a+a 是传值。
  • 如果a是一个不可变类型,那么a += a 和a = a+a 的效果一样即:传值。

四、递归函数与匿名函数

4.1、递归函数

递归函数:如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。

示例:

def cal_num(n):
    if n >= 1:
        result = n * cal_num(n-1)
    else:
        result = 1
    return result

ret = cal_num(3)
print(ret)

"""
运行结果为:
6
"""

4.2、匿名函数

匿名函数:用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。
特点:节省行数,用完就可以扔掉,简便。

注意:lambda函数的语法只包含一个语句。

格式:

lambda [arg1, [arg2,.....argn]]:expression

示例:

c = lambda a, b: a + b
print(c(1, 2))

"""
运行结果为:
3
"""

五、参考资料

[1]:Python笔记之nonlocal语句
[2]:Python当中的a += a 与 a = a + a 的区别,可变类型与不可变类型的数据类型,引用传参
[3]:python中a+=a与a=a+a的区别
[4]:python函数传参是传值还是传引用?
[5]:Python中的引用传参

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值