python函数基础(二)

1.变量的作用域

变量起作用的范围成为变量的作用域,分为全局变量, 局部变量

1. 全局变量:
  • 在函数和类定义之外声明的变量. 作用域为定义的模块,从定义位置开始知道模块结束
  • 全局变量降低了函数的通用性和可读性,尽量避免
  • 全局变量一般做常量使用
  • 函数内想改变全局变量用global声明一下
2. 局部变量
  • 在函数体重声明的变量(包括形式参数)
  • 局部变量较全局变量,优先考虑使用
  • 如果同名,在函数体内隐藏全局变量,只使用局部变量
# 打印全局变量a的值
a = 100
def f1():
    print(a)  # --打印全局变量a的值

f1()
# 优先打印局部变量的值
a = 100
def f1():
    a = 300
    print(a)  # --打印局部变量a的值

f1()
# 改变全局变量的值
a = 100
def f1():
    global a
    a = 300

f1()
print(a)  # --在函数内改变全局变量的值
# 打印输出局部 全局变量
a = 100
def f1():
    b = 20
    global a
    a = 300
    print(locals())   # --打印局部变量
    print(globals())   # --打印全局变量
f1()
print(a)
3. 局部连梁和全局变量效率测试
import math
import time
def f1():
    start = time.time()
    for i in range(10000000):
        math.sqrt(300)
    end = time.time()
    print('耗时:{}'.format(end - start))

def f2():
    b = math.sqrt   # -- 设置局部变量
    start = time.time()
    for i in range(10000000):
        b(30)
    end = time.time()
    print('耗时:{}'.format(end - start))
f1()
f2()

2.参数传递

函数参数传递本质上是:从实参到形参的赋值操作,python中一切是"引用的赋值",python不是'值传递'
1.对"可变对象"进行写操作,直接用于原对象本身
2.对不可变对象进行写操作,会产生一个新的对象空间,并用新的值填充这块空间
  • 可变对象:列表 字典 集合 自定义对象
  • 不可变对象:字符串 数字 元组 function等
1. 传递可变对象引用

实际传递还是对象的引用,在函数中不创建新的对象拷贝,而是可以直接修改传递的对象

# 地址一直没有变化

a = [10, 11]
print(id(a))


def f1(m):
    print(m, id(m))
    m.append(12)
    print(m, id(m))


f1(a)
print(a, id(a))
2. 传递不可变对象引用

在赋值操作时,由于不可变对象无法被修改,系统会创建一个新对象

a =100
print(id(a))

def f1(m):
    print(id(m))  # -- 与a id相同
    m += 20
    print(id(m))  # --创建新id
f1(a)
print(id(a))	# -- 与a id相同,函数内部变化不影响外部

3.浅拷贝和深拷贝

内置函数copy()浅拷贝 deepcopy()深拷贝

1.浅拷贝copy()
  • 不拷贝子对象的内容,只拷贝子对象的引用
IN:
import copy

a = [10, 20, [5, 6]]
b = copy.copy(a)
b.append(30)
b[2].append(7)

print(a, b, sep='\n')

OUT:
[10, 20, [5, 6, 7]]
[10, 20, [5, 6, 7], 30]
2.深拷贝deepcopy()
  • 会连子对象的内存也一起拷贝,对子对象的修改不会影响原对象
IN:
import copy

a = [10, 20, [5, 6]]
b = copy.deepcopy(a)
b.append(30)
b[2].append(7)

print(a, b, sep='\n')

OUT:
[10, 20, [5, 6]]
[10, 20, [5, 6, 7], 30]
3.用 ‘=’ 进行赋值
IN:
a = [10, 20, [5, 6]]
c = a
c.append(30)
c[2].append(7)
print(c)
print(a)

OUT:
[10, 20, [5, 6, 7], 30]
[10, 20, [5, 6, 7], 30]
4. 传递不可变对象浅拷贝
a = (10, 20, [5, 6])
print(id(a))
def f1(m):
    print(id(m))
    m[2][0] = 666
    print(m, id(m))  # -- m的id并没有变化
f1(a)

4. 参数种类及用法

函数调用时,参数默认是按照顺序传导,需要个数和形参匹配

1. 位置参数
def f1(a, b, c):  # --形参名字一样会报错
    print(a, b, c)
f1(2, 3, 4) # --个数不一致会报错
2. 默认值参数
def f1(a, b, c=10):  
    print(a, b, c)
f1(2, 3) 
f1(2, 3, 4) # --给c赋值为4
3. 命名参数
def f1(a, b, c):
    print(a, b, c)
f1(a=2, c=3, b=4) # --直接给形参命名
4. 可变参数
  • 可变参数是指’可变数量的参数’,分为两种:
  1. ‘一个星号’,将多个参数收集到一个元组
  2. ‘两个星号’,将多个参数收集到一个字典
IN:
def f1(a, b, *c):
    print(a, b, c)
f1(1, 2, 3, 4, 5)

OUT:
1 2 (3, 4, 5)
IN:
def f1(a, b, **c):
    print(a, b, c)
f1(1, 2, name = 'zs', age = 18 )

OUT:
1 2 {'name': 'zs', 'age': 18}
5. 强制命名参数
def f1(*a, b, c):  #-- *a放前面,则b c需要强制命名
    print(a, b, c)
f1(3, 4 , b=1, c=2)

5. lambda函数

  • lambda可以用来声明匿名函数
  • lambda表达式只允许包含一个表达式,不能包含复杂语句,该表达式的计算结果就是返回值
# 一个lambda
f = lambda a, b, c, d: a * b * c * d
print(f(1, 2, 3, 4))
# 可以多个lambda同时使用
g = [lambda a: a*2, lambda b: b*2]
print(g[1](3), g[0](4))
# 函数也是对象,可以调用
f = lambda a, b, c, d: a * b * c * d

g = [lambda a: a*2, lambda b: b*2]

h = [f, g]
print(h[1][0](3))

6. eval()函数

  • 将字符创当成有效的表达式来求值并计算结果
  • 一般用在从别的平台直接传来的字符串需要计算
s = "print('abcdef')"
eval(s)

7. 递归函数

  • 自己调用自己的函数,常用在数学归纳法
  1. 终止条件:表示递归什么时候结束
  2. 递归步骤:把第n步的值与第n-1相关联
# 求5的阶乘
def f1(n):

    if n == 1:
        return 1
    else:
        return n*f1(n-1)


result = f1(5)
print(result)

8. 嵌套函数(内部函数)

  • 在函数内部定义的函数
  1. 封装 数据隐藏
  2. 贯彻DRY原则
  3. 闭包
def printNmae(isChinese, name, familyName):

    def inner_print(a, b):
        print('{0} {1}'.format(a, b))
    if isChinese:
        inner_print(familyName, name)
    else:
        inner_print(name,familyName)
printNmae(True, '小七', '高')
printNmae(False, '小八', '低')

9. nonlocal global关键字用法

a = 100
def outer():
    b = 10
    def inner():
        nonlocal b  # 声称外部函数的局部变量
        print('inner b:',b)
        b = 20
        global a
        a = 1000
    inner()
    print('outer b:', b)
outer()
print('a:', a)

10. LEGB规则

  • python在查找变量时,是按照LEGB规则查找的
  • local→enclosed(嵌套函数)→global→build in
print(str(30))
str 'global str'

def outer():
    str = 'outer'
    def inner():
        str = 'inner'
        print(str)

    inner()


outer()

个人心得,仅供参考

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值