2020-09-20学习参数及参数的传递,lambda表达式和匿名函数,eval函数,递归函数

Python学习

函数也是对象,内存底层分析

python中,一切都是对象,实际上,执行def定义函数后,系统就创建了相应的函数对象。

下面是Demo

# 测试函数也是对象

def test01():
    print('sssssss')

test01()
c = test01
c()

print(id(test01))
print(id(c))
变量的作用域(全局变量和局部变量)

变量器作用的范围成为变量的作用域,不同作用域内同名变量之间互相不影响
全局变量:1.在函数和类定义之外生命的变量,作用域为定义的模块,从定义位置开始到模块结束 2.全部变量降低了函数的通用性和可读性,尽量少使用全局变量 3.全部变量一般作为常量使用 4.函数内要改变全部变量的值,使用global声明一下
局部变量:1.在函数体中(包含形式参数)生命的变量 2.局部变量的引用比全部变量快,优先考虑使用 3.如果局部变量和全局变量同名,则在函数内隐藏全局变量,只使用同名局部变量
下面是Demo

#测试全局变量 局部变量
a = 3 #全局变量
def test01():
    b = 4    #局部变量
    global a #如果要在函数内改变全局变量的值,增加global关键字生命
    a = 300
    print(b*10)
    print(locals())   #打印输出的局部变量
    print('#'*22)
    print(globals()) #打印输出的全局变量

test01()
print(a)
#效率测试
import math
import time

def tets01():
    start = time.time()
    for i in range(10000):
        math.sqrt(300)
    end = time.time()
    print('耗时{0}'.format(end-start))
def tets02():
    b = math.sqrt
    start = time.time()

    for i in range(10000):
        b(30)
    end = time.time()
    print('耗时{0}'.format(end - start))
tets02()
tets01()
参数的传递

实参到形参怎么赋值

下面是Demo

#参数的传递,传递可变对象
a = [10,20]

print(id(a))
print(a)

print('----------------------------')
def test01(m):
    print(id(m))
    m.append(300)
    print(id(m))


test01(a)
print(a)
传递不可变对象

传递参数时不可变对象(例如:int ,float,字符串,元组,布尔值),实际传递的还是对象的引用

下面是Demo

a = 100
def f1(n):
    print('n',id(n))
    n = n + 200
    print('n',id(n))
    print(n)

f1(a)
print('a',id(a))

浅拷贝和深拷贝

浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用。copy(浅拷贝)
深拷贝:会连子对象的内存也拷贝一份,对子对象的修改不会影响源对象,deepcopy(深拷贝)

下面是Demo

#测试浅拷贝和深拷贝
import copy
a = [10,20,[5,6]]
b = copy.copy(a)


print('a0',a)
print('b',b)

b.append(30)
b[2].append(7)


print('浅拷贝')
print('a',a)
print('b',b)

def testcopy():
    c = [10,20,[5,6]]
    d = copy.deepcopy(a)

    print('c',c)
    print('d',d)

    d.append(30)
    b[2].append(7)
    print('深拷贝')
    print('c',c)
    print('d',d)

testcopy()
传递不变对象时浅拷贝

下面是Demo

#传递不可变对象时,
# 不可变对象里面包含的子对象是可变的,则方法内修改了这个可变对象,源对象也发生了变化

a = (10,20,[5,6])
print('a',id(a))

def test01(m):
    print('m',id(m))
    m[2][1]= 20
    print(m)
    print('m',id(m))
test01(a)
print(a)

参数的类型

位置参数:函数调用时,实参默认按位置顺序传递,需要个数和形参匹配,按位置传递的参数,称为位置参数
默认值参数:我们可以未某些参数设置默认值,这样这些参数在传递时就是可选的,称为默认值参数,默认值参数放到位置参数后面
命名参数:我们也可以按照形参的名称传递参数,称为命名参数,也称为关键字参数
可变参数:可变参数指的是可变数量的参数分两种情况:1.*param(一个星号),将多个参数收集到一个元组对象中 2.**param(两个星号),将多个参数收集到一个字典对象中
强制命名参数:在带星号的可变参数后面增加新的参数,必须在调用时强制命名参数

下面是Demo

#测试参数类型:位置参数,默认值参数,命名参数

def test01(a,b,c,d):
    print('{}-{}-{}-{}'.format(a,b,c,d))

def test02(a,b,c=10,d=15):
    print('{}-{}-{}-{}'.format(a, b, c, d))

test01(10,20,30,40)   #位置参数
# credits(10,20)            #参数个数不匹配,报错

test01(a=10,b=20,c=30,d=100)  #命名参数,通过形参名称来匹配
test02(2,3)
test02(2,3,4)
#测试可变参数,强制命名参数
def f1(a,b,*c):
    print(a,b,c)

f1(8,9,19,20)

def f2(a,b,**c):
    print(a,b,c)

f2(8,9,name='gaoqi',age=18)

def f3(a,b,*c,**d):
    print(a,b,c,d)

f3(8,9,20,30,name='gaoqi',age=18)

lambda表达式和匿名函数

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

下面是Demo

#lambda表达式和匿名函数的测试

f = lambda a,b,c,d:a*b*c/d

def test01(a,b,c,d):
    return a*b*c/d


# print(f(2, 3, 4, 5))
test01(2,3,4,5)

g = [lambda a:a*3,lambda b:b/2,lambda c:c*6]

print(g[0](6),g[1](25),g[2](9))

h =[test01,test01]
print(h[0](3, 4, 5, 6))
eval函数

功能:将字符串STR当成有效的表达式来求值并返回计算结果

下面是Demo

#测试eval函数

s = "print('abcde')"
eval(s)

a = 10
b = 20
c = eval('a+b')
print(c)

dict1 = dict(a=100,b=200)

d = eval('a+b',dict1)
print(d)
递归函数

递归函数指的是:自己调用自己的函数,在函数体内直接或间接的自己调用自己,递归类似于中学学习过的数学归纳法,每个递归函数必须包含两个部分:1. 终止条件:表示递归什么时候结束,一般用于返回值,不再调用自己 2. 递归步骤:把第N步的值和第N-1步相关联
递归函数由于会创建大量的函数对象,过量的消耗内存和运算能力,在处理大量数据时,谨慎使用
下面是Demo

#测试递归函数的基本原理

def tset01(n):
    print('tset01',n)
    if n ==0:
        print('over')
    else:
        tset01(n-1)
    print('test01****',n)
def tset02():
    print('tset02')


tset01(5)
递归函数案例

综合练习。

下面是Demo

#使用递归函数计算阶乘综合练习
def factorial(n):

    if n==1:
        return 1
    else:
        return n*factorial(n-1)
result = factorial(5)
print(result)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值