Python学习——函数

函数

#函数可以被反复调用
def MAX(a,b):
    '''输入两个数,输出其中的较大值'''
    if a>b:
        print(a,"max")
    else:
        print(b,"max")

MAX(10,30)
MAX(50,10)

help(MAX.__doc__)
#查询function的功能说明

'''
定义函数的格式为 def 函数名字(形参变量):   一定要注意符号,以及function的缩进
调用的时候,实参与形参一定要一一对应,type和数量要一致;实参调用,形参定义
'''

函数返回值

#函数中用return返回值,同时结束函数运行
def add(a,b):
    '''计算两个数的和'''
    return a+b
#函数的调用到return就停止了,后续的语句都不会被执行
c=add(30,40)
print(c)

def test(a,b,c):
    return [a*10,b*10,c*10]
#返回值只能是一个对象,但是可以借用返回列表、元组等的形式将需要返回的数据存储起来
print(test(2,3,4))

#如果没有定义return返回值,默认返回None

全局变量、局部变量

a=100   #全局变量

def f1():
    b=3
    a=4     #局部变量
    print(a+b)

f1()
print(a)
'''
7
100     局部变量再被使用完成后就会回收
'''

a=100   #全局变量

def f1():
    b=3
    global a
    a=4     #局部变量
    print(a+b)

f1()
print(a)
'''
7
4   global生命以后函数内部可以操作全局变量的值
'''

'''
fi在def时就将栈中的f1指向了堆中的function对象
每次运行f1会在栈中开辟一个栈帧,局部变量储存在里面指向堆中的对象
global声明后,栈帧中对a的操作都会使得原来的变量a进行改变

******局部变量的引用效率更高
'''

位置参数、默认参数、强制命名参数

def f1(a,b,c):
    pass
f1(2,3,4)
#要一一对应,不能缺少

def f2(a,b,c=100):
    pass
f2(1,2)
#默认值参数可以在没有主动赋值时有一个默认参数,默认参数必须在位置参数后

def f3(a,b,c):
    pass
f3(c=1,b=3,a=3)
#强制命名参数

def f1(a,b,*c): #一个星号代表元组,会将所有参数传到元组中
    print(a,b,c)
f1(1,2,3,4,5)

def f2(a,b,**c):    #字典,但是不能传入集合
    print(a,b,c)
f2(1,2,name="Jim",age="22")

#如果字典或者元组的参数在前,则必须使用强制命名

LEGB规则

a=100
def aa():
    c=10
    print(a)
    def bb():
        global a
        nonlocal c  #内部函数不像外部那样可以读取到全局变量,写的操作都需要声明
        print(a)
        print(c)
        a=20
        c=50
    bb()
    print(a)
    print(c)

aa()
'''
当只需要调取外部数据时不需要定义,但是需要改变变量value时需要在内部函数声明,nonlocal是外部函数,global用于全局变量声明
没有声明时会一层层往外查找
'''

参数传递

'''
参数传递与全局、局部变量概念不同,是函数运行需要传入的实际参数
列表、字典、集合、自定义等可以修改的参数,在传递时不会增加新的对象
字符串、数字、元组、function不可以修改,传递时会创建出新的对象
'''

'''
只进行读操作,任何可变或不可变对象都可以进行
'''

a=[10,20,30]
def f1(m):
    print(id(m))
    m.append(40)
    print(id(m))
f1(a)
print(a)
#传递可变对象的时候,写的操作会作用在原对象上

a=1000
def f2(m):
    print(id(m))    #地址仍然是传递进来的a的地址
    m=m+1000    #写操作
    print(m)
    print(id(m))    #id和value改变,新的一个对象
f2(a)
print(a)    #原对象没有改变
#如果传递的是不可变对象且需要进行修改,需要在def中给出print或return

不可变对象中包含可变对象的参数传递

a=(10,20,30,[50,60])
print(id(a))
def test1(m):
    print(id(m))
    m[3][0]=70
    print(id(m))
    print(m)
test1(a)
print(a)
#元组本身的元素不可以改变,但是其中的可变子对象的内容可以改变,且不会影响id
'''
函数传递不可变对象时是采用浅拷贝
'''

嵌套函数

def print_name(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)

print_name(True,"junyang","chen")

'''
if判断语句的结果时True和False 所以调用赋值也是这两个,0、1也可以用
'''

递归函数

#递归的本质是自己调用自己;谨慎使用,因为会占据大量的内存
def test01(n):
    print("a=",n)
    if n==0:
        print("over")
    else:
        test01(n-1)
    print("b=",n)

test01(4)
'''
a= 4
a= 3
a= 2
a= 1
a= 0
over
b= 0
b= 1
b= 2
b= 3
b= 4   为什么会输出这个结果?是因为调用自己时会在栈里开辟一个新的栈帧,导致b语句还没有进行执行就先进行了后面的调用;
       而执行完n=0时,没有新的栈帧再开辟所以会回过头来一个个消除掉栈帧,b语句由新到旧依次执行完毕
'''

lambda表达式声明匿名函数

f=lambda a,b,c:a+b+c    #只能返回简单表达式的值
print(f(1,2,3))
#lambda表达式可以声明匿名函数 由元素:表达式组成 会直接返回表达式的计算值

g=[lambda a:a*2,lambda b:b*3,lambda c:c*4]
print(g[0](1),g[1](2),g[2](3))
#放在一个列表里面也可以分开调用;lambda只能包含一个简单的表达式

eval函数

#eval应该包含的是依据逻辑执行语句的字符串形式

c=dict(a=10,b=15)
print(eval("a+b",c))    #以c为取值范围
#可以指定eval的调用范围,范围只能是字典形式

n=input("please input:")   #输入 (x,x) eval可以将该字符串转换为元组,可以用于储存坐标
print(eval(n))

'''
如果直接将字符串转为 list或者tuple只能将字符串元素进行储存
例如输入 200,300 list以后只能转化为 ['2', '0', '0', ',', '3', '0', '0']
'''

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值