Python基础知识06

目录

 

一、函数用法和底层分析


一、函数用法和底层分析

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

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

#测试函数也是对象

def test01():
    print("sxtsxt")

test01()
c = test01
c()

print(id(test01))
print(id(c))

print(type(c))

(二)变量的作用域(全局变量和局部变量)

1.全局变量:

(1)在函数和类定义之外声明的变量。作用域为定义的模块,从定义位置开始直到模块结束。

(2)全局变量降低了函数的通用性和可读性。应尽量避免全局变量的使用。

(3)全局变量一般做常量使用。

(4)函数内要改变全局变量的值,使用global声明一下。

2.局部变量:

(1)在函数体中(包含形式参数)声明的变量。

(2)局部变量的引用比全局变量快,有限考虑使用。

(3)如果局部变量和全局变量同名,则在函数内隐藏局部变量,只使用同名的局部变量。

#测试全局变量、局部变量

a = 3  #全局变量

def test01():
    b = 4    #局部变量
    print(b*4)

    global a  #如果要在函数内改变全局变量的值,增加global关键字声明
    a = 300


test01()
test01()

print(a)

3.输出局部变量和全局变量

print(locals())

print(globals())

(三)局部变量和全局变量效率测试

局部变量的查询和访问速度比全局变量快,优先考虑使用,尤其是循环的时候

#测试局部变量、全局变量的效率

import math
import  time

def test01():
    start = time.time()
    for i in range(10000000):
        math.sqrt(30)
    end = time.time()
    print("耗时{0}".format((end-start)))

def test02():
    b = math.sqrt
    start = time.time()
    for i in range(10000000):
        math.sqrt(30)
    end = time.time()
    print("耗时{0}".format((end-start)))

test01()
test02()

(四)参数的传递

函数的参数传递本质上是:从实参到形参的赋值操作。所有事物赋值操作都是“引用的赋值”。Python 中参数的传递都是“引用传递”,不是“值传递”。

a.对“可变对象”进行“写操作”,直接作用于对象本身。

b.对“不可变对象”进行“写操作”,会产生一个新的“对象空间”,并用新的值填充这块空间。(起到其他语言的“值传递”效果,但不是“值传递”。)

可变对象:字典、列表、集合、自定义的对象等

不可变对象:数字、字符串、元祖、function等

1.传递可变对象的引用

#参数的传递
#传递可变对象

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)

结果:
14667336
[10, 20]
*********************
14667336
14667336
[10, 20, 300]

2.传递不可变对象的引用

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

f1(a)
print("a:",id(a))

结果:
n: 1739910624
n: 12205952
300
a: 1739910624

3.浅拷贝和深拷贝

浅拷贝:不拷贝子对象的内容,知识拷贝子对象的引用

深拷贝:会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象

#测试浅拷贝、深拷贝

import copy

def testCopy():
    '''测试浅拷贝'''

    a = [10, 20, [5, 6]]
    b = copy.copy(a)

    print("a:", a)
    print("b:", b)

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

    print("浅拷贝……")

    print("a:", a)
    print("b:", b)

def testDeepCopy():
    '''测试深拷贝'''

    a = [10, 20, [5, 6]]
    b = copy.deepcopy(a)

    print("a:", a)
    print("b:", b)

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

    print("深拷贝……")

    print("a:", a)
    print("b:", b)

testCopy()
print("**********************")
testDeepCopy()

4.传递不可变对象包含的子对象是可变的情况:是浅拷贝

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

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

def test01(m):
    print("m:",id(m))
    m[2][0] = 888
    print(m)
    print("m:",id(m))

test01(a)
print(a)

结果:
a: 44709480
m: 44709480
(10, 20, [888, 6])
m: 44709480
(10, 20, [888, 6])

(五)参数的几种类型

1.位置参数

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

2.默认值参数

可以为某些参数设置默认值,这些参数在传递时可选。默认值参数放到位置参数后面。

3.命名参数:关键字参数

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

def test01(a,b,c,d):
    print("{0}-{1}-{2}-{3}".format(a,b,c,d))

def test02(a,b,c=15,d=25):    #默认值参数,必须位于其他参数后面
    print("{0}-{1}-{2}-{3}".format(a,b,c,d))

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

test01(d=20,b=10,a=40,c=30)    #命名参数,通过形参名称来匹配

test02(2,3)
test02(2,3,4)

4.可变参数

(1)*param(一个星号),将多个参数收集到一个“元祖”对象中

(2)**param(两个星号),将多个参数收集到一个“字典”对象中

5.强制命名参数

在带星号的“可变参数”后面增加新的参数,必须在调用的时候“强制命名参数”。

(六)lambda表达式和匿名函数

f = lambda a,b,c:a+b+c

def test02(a,b,c):
    return a+b+c

print(test02(2,3,4))


print(f(2,3,4))

g = [lambda a:a*2,lambda b:b*3]
print(g[0](6))

h = [test02,test02]    #函数也是对象
print(h[0](3,5,6))

(七)eval()函数:将字符串str当成有效的表达式求值并返回计算结果

#测试eval()函数

s = "print('abcdef')"
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)

(八)递归函数

自己调用自己的函数

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

def test01(n):
    print("test01:",n)
    if n == 0:
        print("over")
    else:
         test01(n-1)

    print("test01***",n)

def test02():
    print("test02")

test01(4)

结果:
test01: 4
test01: 3
test01: 2
test01: 1
test01: 0
over
test01*** 0
test01*** 1
test01*** 2
test01*** 3
test01*** 4
#使用递归函数,计算阶乘

def factorial(n):

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

result = factorial(5)
print(result)

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页