十七、自定义函数

自定义函数

 之前我们接触了很多的内置函数。函数可以极大提高工作效率

一、一般函数

函数特性

  • 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
  • 函数能提高应用的模块性,和代码的重复利用率。

函数规则如下:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None
  • 我们用之前的一个例子做比较。通过产品ID来查找产品的价格。如果这个代码按照之前写的。在别的模块里面或者别的同事需要用到的时候。只能完整的拷贝这些代码了。而如果自定义写个函数。那么完全不需要关心函数内部是这么实现的。也不需要拷贝所有的代码。只需要调用这个函数传入ID就好了。代码的复用率得到很大的提升。对于项目级别的代码。这是非常明显的。
“”“
id_price_ = {
    1: 180,
    2: 90,
    3: 100,
    4: 50
}

bzf_ = True
while bzf_:
    product_id = input('请输入产品id:')

    if int(product_id) in id_price_:
        print('产品价格:' + str(id_price_[int(product_id)]))
        bzf_ = False
        break
        
    else:
        print('产品不存在!请重新输入')
”“”

# 自定义函数实现的过程如下
# def 函数声明
# find_product 函数名称
# product_id 函数参数
# return 函数返回结果
# 中间的代码块称为函数主体
def find_product(product_id):
    """
    查询产品价格
    :param product_id:产品id
    :return: 产品价格
    """
    _id_price = {
        1: 180,
        2: 90,
        3: 100,
        4: 50
    }

    if int(product_id) in _id_price:
        return _id_price[int(product_id)]

    else:
        return ('产品不存在!请重新输入')


print(find_product(222))
print(find_product(2))

打印结果:
产品不存在!请重新输入
90
  • 函数嵌套函数
def qt(m):
    def qths():
        return 333
    n = m + qths()
    return n
qt(111)
    

函数的几种参数

  • 必填参数
  • 默认参数
  • 不定长元组参数
  • 关键字参数
def demo1(cs1, cs2='不传值为默认值'):
    print(cs1)
    print(cs2)


demo1('参数1')


def demo2(*args, **kwargs):
    """
    特殊参数演示
    :param args: 不定长元组参数
    :param kwargs: 关键字参数
    :return:
    """
    print(args,type(args))
    print(kwargs,type(kwargs))


demo2('不定长参数元素1', '不定长参数元素2', key1='11', key2=22)

打印结果:

参数1
不传值为默认值
('不定长参数元素1', '不定长参数元素2') <class 'tuple'>
{'key1': '11', 'key2': 22} <class 'dict'>

  • 变量在函数内部的作用域。函数外部的变量在同一文件中是全局的。函数可以直接使用该变量。但是当函数内部变量名称和函数外部名称一致时。在没声明函数内的变量是全局的话。2个变量之间没有任何关系。在嵌套函数中,如果要修改主函数的变量。可以使用nonlocal 
a = 2
c = 3
def m(x):
    a = 3 
    y = x + a + c
    return y

print(m(3),a)


b = 3

def n(z):
    global b  # 声明 b 的作用域为全局
    b = 5  # 因为b是全局变量。当函数内b的值改变了。函数外的b的值也改变了。
    q = z+b
    return q

print(n(4),b)


def q():
    u = 5
    def r():
       nonlocal u # 声明 u的作用域是整个函数
       u = 6
    r()
    return u

print(q())

参数的传递

  • 函数的入参如果是不可变的数据类型。重新赋值该入参。只不过是新创建了一个变量。和原始参数没有任何关系。
  • 函数的入参如果是可变的数据类型。该变量值发生变化。原始参数也会跟着变化。因为他们自始至终都指向同一个对象。
a = 1
b = [1,2,3,4]

def n(x,y):
    x = 3
    y.append(x)
    return d

n(a,b)
print(a,b)

二、几种特殊的函数

闭包函数是函数嵌套的一种特殊方式。规则如下:

  • 必须有一个嵌套函数(函数内部的函数)。
  • 嵌套函数必须引用封闭函数中定义的值。
  • 闭包函数必须返回嵌套函数。
# 计算一个数的平方
def c(i):
    def nested():
        b = i ** 2
        return b
    return nested

 递归函数

  • 在函数的执行过程中不断的调用函数本身。
def call(n):
    print(n)
    if int(n/2) >0:
        call(int(n/2))
    else:
        print('~~~~~')
    print(n)

call(10)

猜猜这个结果是什么??

  • 在使用递归函数的时候。一定要遵循一下原则。
  • 必须有一个明确的结束条件,要不就会变成死循环了,最终撑爆系统
  • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
  • 递归执行效率不高,递归层次过多会导致栈溢出。(实际测试超过了996次递归基本就会溢出了)

匿名函数

  • python 使用 lambda 来创建匿名函数。所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
# 一般的函数和匿名函数实现相加的功能
def demo(cs1,cs2):
    return cs1+cs2

sum = lambda cs1,cs2:cs1+cs2

print(demo(1,2))
print(sum(1,2))


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bug来袭~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值