定义函数

1.使用def定义函数

比如:

    def max(num1,num2):

        return num1 if num1>num2 else num2

说明:def 关键词,max是函数名称,num1,num2是参数名称,若要返回值,则可以使用return。如果函数执行完毕但没有使用return返回值,或者使用了return结束函数但没有指定返回值,默认就会返回None。

支持递归和局部函数

2.参数与自变量


python中不支持函数重载

参数默认值

虽然不支持函数重载的实现,不过在Python中可以使用默认自变量来有限度地模仿函数重载。例如:

def account(name,number,balance=100):
    return{'name':name,'number':number,'balance':balance}



#显示
print(account('Justin','123-4567'))
{'name': 'Justin', 'number': '123-4567', 'balance': 100}

#显示
print(account('JK','987-234',1000))
{'name': 'JK', 'number': '987-234', 'balance': 1000}

使用参数默认值时,必须小心指定了可变动对象时的一个陷阱,Python在执行到def时,就会按照定义创建相关的资源。看看下面会出现的问题。

def prepend(elem,It=[]):
    It.insert(0,elem)
    return It


prepend(10)
Out[23]: [10]


prepend(10,[20,30,40])
Out[24]: [10, 20, 30, 40]


prepend(20)

Out[25]: [20, 10]


在上例中,IT默认值设置为[],由于def是条语句,执行到def的函数定义时就创建了[],而这个对象列表会一直存在,如果没有指定It,使用的就会一直是一开始指定的列表对象。想要避免这样的问题,可以将prepend()的It参数默认值设为None,并在函数中指定真正的默认值。例如:

def prepend(elem,It=None):
    It=It if It else []
    It.insert(0,elem)
    return It

prepend(10)
Out[32]: [10]

prepend(10,[20,30,40])
Out[33]: [10, 20, 30, 40]

prepend(20)

Out[34]: [20]

关键词自变量

可以指定

参数名称来设置其自变量值。

*与**

如果有个函数拥有固定的参数,而我们有一个序列,像列表、元组,只要在传入时加上*,列表或元组中各个元素就会自动拆解给各个参数。

比如:

def account(name,number,balance):
    return{'name':name,'number':number,'balance':balance}

#显示
print(account(*('Justin','123-4567',1000)))
{'name': 'Justin', 'number': '123-4567', 'balance': 1000}

像sum()这种加总数字的函数,事先无法预期要传入的自变量个数,可以在定义函数的参数时使用*,表示该参数接受不定长度的自变量。例如:

def sum(*numbers):
    total=0
    for i in numbers:
        total+=i
    return total

#显示
print(sum(1,2))
3

#显示
print(sum(1,2,3,4))
10

传入函数的自变量,会被收集到一个元组中,再设置给numbers参数,这适用于参数个数不固定而且会按序迭代处理参数的场合。


如果有个字典,打算按照键的名称赋值给对应的参数名称,可以在字典前加上**,这样字典中各对键和值就会自动拆解给各个参数。


注意:如果参数个数越来越多,而且每个参数名称都有其意义,像def ajax(url,method,contents,datatype,accept,headers,username,password)这样的函数定义不但“丑陋”,调用时也很麻烦。这个时候可以试着使用**来定义参数,让指定的关键词自变量收集为一个字典。

例如:

def some(*arg1,**arg2):
    print(arg1)
    print(arg2)


some(2,3,4,a=5,b=8,c=10)
(2, 3, 4)
{'a': 5, 'b': 8, 'c': 10}


3.一级函数的运用

在Python中,函数不单只是个定义,还是个值,定义的函数会产生一个函数对象,它是function的实例,既然函数是对象,也就可以赋值给其他的变量。例如:

def max(num1,num2):
    return num1 if num1>num2 else num2

maximum=max

maximum(10,5)
Out[47]: 10


type(max)

Out[48]: function

函数与数值、列表、集合、字典、元组等一样,都被Python视为“一级公民”来对待

实际上,Python内建有filter()、map()函数可以直接调用它们。在Python3中,map()、filter()返回的实例并不是列表,分别是map与filter对象,都具有惰性求值的特性。基本上filter()、map()能做到的,for Comprehension基本上都做得到。在大多数情况下,for Comprehension比较常见,不过有时通过适当的命名,使用filter()、map()会有比较好的可读性。

再来看一个一级函数传递的例子,到目前为止,经常会使用列表、元组等有序结构,有时想将其中的元素进行排序,这时可以使用sorted()函数,它可以按照我们指定的方式进行排序。例如:

sorted([2,1,3,6,5])
Out[53]: [1, 2, 3, 5, 6]


sorted([2,1,3,6,5],reverse=True)
Out[54]: [6, 5, 3, 2, 1]


sorted(('Justin','openhome','momor'),key=len)
Out[55]: ['momor', 'Justin', 'openhome']


sorted(('Justin','openhome','momor'),key=len,reverse=True)

Out[56]: ['openhome', 'Justin', 'momor']


sorted()会返回新的列表,其中包括了排序后的结果,key参数可用来指定针对什么特性来迭代。

如果是可变动的列表,本身也有个sort()方法,这个方法会直接在列表本身排序,不像sorted方法会返回新的列表。例如:



It=[2,1,3,6,5]


It.sort()

It
Out[60]: [1, 2, 3, 5, 6]


It.sort(reverse=True)


It
Out[62]: [6, 5, 3, 2, 1]

4.lambda表达式

当只有一句简单的运算,对于这类情况,可以考虑使用lambda表达式。例如:

def filter_lt(predicate,lt):
    result=[]
    for elem in lt:
        if predicate(elem):
            result.append(elem)
    return result


lt=['Justin','caterpillar','openhome']


print('大于6:',filter_lt(lambda elem:len(elem)>6,lt))
大于6: ['caterpillar', 'openhome']


print('小于5:',filter_lt(lambda elem:len(elem)<5,lt))
小于5: []


print('有个i:',filter_lt(lambda elem: 'i' in elem,lt))

有个i: ['Justin', 'caterpillar']

在lambda关键词之后定义的是参数,而冒号(:)之后定义的是函数体,运算的结果会作为返回值,不需要加上return,像lambda elem:len(elem)>6这样的lambda表达式会创建function实例,也就是一个函数。有时临时只是需要一个小函数,使用lambda就很方便。

如果lambda不需要参数,直接在lambda后加上冒号就可以了,若需要两个以上的参数,中间要使用逗号(,)分隔开,例如

max=lambda n1,n2:n1 if n1>n2 else n2

max(10,5)

Out[75]: 10

和其他语言中的lambda语句相比,Python使用lambda关键词的方式其实并不简洁,甚至有些妨碍可读性。实际上,Python中的lambda也没办法写太复杂的逻辑,这是Python中为了避免lambda被滥用而特意做的限制。


5.初探变量作用域

在Python中,变量无需事先声明,一个名称在赋值时,就可以成为变量,并创建起自己的作用域(Scope)。在存取一个变量时,会看看当前作用域中是否有指定的变量名称,若无则向外寻找,因此在函数中可存取全局变量。

def func():
    print(x)

func()

10


那么如果在func()中对名称x作了赋值的操作呢?

def func():
    x=20
    print(x)




func()
20


print(x)

10


在func()中进行x=20的时候,其实就创建了func()自己的局部变量x,而不是将全局变量设为20.


注意:就目前而言可以知道的是,变量可以在内建(Builtin)、全局(Global)、外包函数(Endosing function)、局部函数(Local function)中寻找或创建。

存取名称时(而不是对名称赋值)一定是从最内层往外寻找。Python中的全局变量,实际上是以模块文件为界。

Python 3中有个builtins模块,该模块中的名称作用域横跨各个模块。例如:print

locals()函数可以用来查询局部变量的名称和值

global()可以获取全局变量的名称与值

如果对变量赋值时希望针对全局作用域,可以使用global来声明。

因此在Python 3中应避免global声明的使用。

在Python3中新增了nonlocal,可以指明变量并非局部变量,请解释器按照局部函数、外包函数、全局、内建的顺序来寻找变量,就算是赋值运算时,也要求是这个顺序。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值