python-09-高阶函数、装饰器

目录

01-函数的回顾总结

02-默认参数的使用

03-自定义可变参数

04-可变参数

05-可变类型和不可变类型传参

06-函数的注意事项

07-递归函数的使用

08-递归的联系

09-匿名函数

10-自定义一个匿名函数的使用场景

11-sort方法的使用

12-filter内置类的使用

13-map的使用

14-reduce的使用

15-内置函数的总结

     Python any() 函数

     Python dir() 函数

16-高阶函数


01-函数的回顾总结

# 1. 函数的声明,使用关键字 def 来声明一个函数
# 2. 函数的格式  def 函数名(形参1,形参2...)
# 3. 函数的调用  函数名(实参1,实参2...)
# 4. 函数返回值 使用 return 语句返回函数的执行结果
# 5. 函数返回多个结果,就是将多个数据打包成一个整体返回。
#   可以使用列表和字典,通常情况下选择使用元组


# 函数名也是一个标识符。
# 由数字、字母下划线组成,不能以数字开头;严格区分大小写;不能使用关键字
# 遵守命名规范,使用下划线连接;顾名思义
def get_sum(a, b):  # 获取到和
    # 函数执行的逻辑,要和函数的名字一致
    # print(a + b)
    return a + b


x = get_sum(1, 3)


def print_sum(a, b):
    print(a + b)


print_sum(4, 5)


def calc(a, b):
    shang = a // b
    yushu = a % b
    return shang, yushu


m, n = calc(15, 4)
print(m, n)
# 1. 函数的声明,使用关键字 def 来声明一个函数
# 2. 函数的格式  def 函数名(形参1,形参2...)
# 3. 函数的调用  函数名(实参1,实参2...)
# 4. 函数返回值 使用 return 语句返回函数的执行结果
# 5. 函数返回多个结果,就是将多个数据打包成一个整体返回。
#   可以使用列表和字典,通常情况下选择使用元组


# 函数名也是一个标识符。
# 由数字、字母下划线组成,不能以数字开头;严格区分大小写;不能使用关键字
# 遵守命名规范,使用下划线连接;顾名思义

02-默认参数的使用

# def say_hello(city="襄阳", name, age):  # 缺省参数要放在后面
def say_hello(name, age, city="襄阳"):  # 形参city设置了一个默认值
    print("大家好,我是{},我今年{}岁了,我来自{}".format(name, age, city))


say_hello('jack', 19)  # 如果没有传递参数,会使用默认值
say_hello(name='tony', age=23, city='北京')  # 如果传递参数,就使用传递的实参

# 如果有位置参数和关键字参数,关键字参数一定要放在位置参数的后面
say_hello('jerry', age=24, city='南京')  # 可以直接传递单个参数,也可以使用变量赋值的形式传参
say_hello(name='henry', city='成都', age=21)

# 缺省参数:
# 有些函数的参数是,如果你传递了参数,就使用传递的参数
# 如果没有传递参数,就使用默认的值


# print函数里end就是一个缺省参数
# print('hello', '你好', sep="____")
# 缺省参数:
# 有些函数的参数是,如果你传递了参数,就使用传递的参数
# 如果没有传递参数,就使用默认的值

03-自定义可变参数

def add(a, b):
    return a + b


def add_many(mmp):
    x = 0
    for n in mmp:
        x += n
    return x


nums = [1, 2, 3, 4, 5, 9, 10, 12]
print(add_many(nums))

print(add_many((5, 8, 2, 1, 0, 9, 7, 4)))
print(add_many({5, 9, 2, 1}))

print(add_many(range(2, 19)))

# 一次input只能接收一次用户的输入
x = input('请输入多个数据,数据中间使用逗号分割:')
# print(x)
# nums = x.split(',')
# print(nums)
# nums = []
# while True:
#     num = input('请输入数字,输入exit退出输入:')
#     if num == 'exit':
#         break
#     nums.append(int(num))
# print(nums)
x = input('请输入多个数据,数据中间使用逗号分割:')
# print(x)
# nums = x.split(',')

04-可变参数

# *args 表示可变位置参数
# **kwargs 表示可变的关键字参数


def add(a, b, *args, mul=1, **kwargs):
    # print('a = {},b={}'.format(a, b))
    # print('args = {}'.format(args))  # 多出来的可变参数会以元组的形式保存到args里
    print('kwargs = {}'.format(kwargs))  # 多出来的关键字参数会以字典的形式保存
    c = a + b
    for arg in args:
        c += arg
    return c * mul


# def add(*args):
#     pass


print(add(1, 3, 5, 7, mul=2, x=0, y=4))
# add(9, 5, 4, 2, 0, p=9, q=10)
# add(8, 9, 7, 5, 7, 9, 8, 7, 5, 3, t=0, m=5)
# *args 表示可变位置参数
# **kwargs 表示可变的关键字参数

05-可变类型和不可变类型传参

from re import A


def test(a):
    print('修改前a的内存地址0x%X' % id(a))
    a = 100
    print('修改后a的内存地址0x%X' % id(a))


def demo(nums):
    print('修改前nums的内存地址0x%X' % id(nums))
    nums[0] = 10
    print('修改后nums的内存地址0x%X' % id(nums))


# x = 1
# print('调用前x的内存地址0x%X' % id(x))
# test(x)
# print('调用后x的内存地址0x%X' % id(x))
# print(x)  # 1
test(A)

y = [3, 5, 6, 8, 2]
print('调用前y的内存地址0x%X' % id(y))
demo(y)
print('调用后y的内存地址0x%X' % id(y))
print(y)  # [10, 5, 6, 8, 2]


'''
修改前a的内存地址0x30020F8
修改后a的内存地址0x7B45DEE0
调用前y的内存地址0x2FF8968#列表地址不变
修改前nums的内存地址0x2FF8968
修改后nums的内存地址0x2FF8968
调用后y的内存地址0x2FF8968
[10, 5, 6, 8, 2]
'''

Python的每个对象都分为可变和不可变,主要的核心类型中

数字、字符串、元组是不可变的

,列表、字典是可变的。

通过id函数查看变量i的内存地址进行验证(使用hex(id(i)) 可以查看16进制的内存地址)

可变类型的话,以list为例。list在append之后,还是指向同个内存地址,因为list是可变类型,可以在原处修改。

改改代码,当存在多个值相同的不可变类型变量时,看看它们是不是跟可变类型一样指向同个内存地址(不是哦)

Python的可变类型与不可变类型 - BlackMatrix - 博客园

06-函数的注意事项

# 函数的三要素:  函数名、参数和返回值
# 在有一些编程语言里,允许函数重名,在Python里不允许函数的重名
# 如果函数重名了,后一个函数会覆盖前一个函数

# def test(a, b):
#     print('hello,a={},b={}'.format(a, b))


# test = 对应的是一个函数
def test(x):
    print('good,x={}'.format(x))


# test = 5
test(3)

# python 里 函数名也可以理解成为一个变量名

# input = 2
# input('请输入您的银行卡密码:')

# int = 50
# print(int('45'))

print(int)
# 函数的三要素:  函数名、参数和返回值
# 在有一些编程语言里,允许函数重名,在Python里不允许函数的重名
# 如果函数重名了,后一个函数会覆盖前一个函数

07-递归函数的使用

# 递归简单来说,就是函数内部自己调用自己
# 递归最重要的就是找到出口(停止的条件)

count = 0


def tell_story():
    global count
    count += 1
    print('从前有座山')
    print('山上有个庙')
    print('庙里有个老和尚')
    print('还有一个小和尚')
    print('老和尚在个小和尚讲故事')
    print('故事的内容是')

    if count < 5:
        tell_story()


tell_story()


# 求 1 ~ n的和
def get_sum(n):
    if n == 6:
        return 21
    return n + get_sum(n - 1)


print(get_sum(5))  # 7 + 21

# 使用递归求 n!
# 使用递归求斐波那契数列的第 n 个数字
# 递归简单来说,就是函数内部自己调用自己
# 递归最重要的就是找到出口(停止的条件)

08-递归的联系

# 使用递归求 n!  n!=n*(n-1)!
def factorial(n):
    if n == 0:
        return 1
    return n * factorial(n - 1)


print(factorial(6))


# 使用递归求斐波那契数列的第 n 个数字
# 1,1,2,3,5,8,13,21,34,55,89,144
def fibonacci(n):
    if n == 1 or n == 2:
        return 1
    return fibonacci(n - 2) + fibonacci(n - 1)


print(fibonacci(9))

09-匿名函数

def add(a, b):
    return a + b


print("0x%X" % id(add))

x = add(4, 5)  # 函数名(实参) 作用是调用函数,获取到函数的执行结果,并赋值给变量 x
print(x)

fn = add  # 相当于给函数fn起了一个笔名
print(fn(3, 7))

# 除了使用 def 关键字定义一个函数以外,我们还能使用 lambda 表达式定义一个函数

# 匿名函数
# 用来表达一个简单的函数,函数调用的次数很少,基本上就是调用一次
# 调用匿名函数两种方式:
# 1. 给它定义一个名字(很少这样使用)
# 2. 把这个函数当做参数传给另一个函数使用(使用场景比较多)
mul = lambda a, b: a * b
print(mul(4, 5))
# 除了使用 def 关键字定义一个函数以外,我们还能使用 lambda 表达式定义一个函数

# 匿名函数
# 用来表达一个简单的函数,函数调用的次数很少,基本上就是调用一次
# 调用匿名函数两种方式:
# 1. 给它定义一个名字(很少这样使用)
# 2. 把这个函数当做参数传给另一个函数使用(使用场景比较多)
mul = lambda a, b: a * b
print(mul(4, 5))

等同于:

def add(a, b):
    return a * b

10-自定义一个匿名函数的使用场景

def calc(a, b, fn):
    c = fn(a, b)
    return c


# def add(x, y):
#     return x + y


# def minus(x, y):
#     return x - y


# 回调函数
# x1 = calc(1, 2, add)  # a=1,b=2,fn=add
# x2 = calc(10, 5, minus)  # a=10,b=5,fn=minus

x3 = calc(5, 7, lambda x, y: x + y)
x4 = calc(19, 3, lambda x, y: x - y)
x5 = calc(2, 7, lambda x, y: x * y)
x6 = calc(12, 3, lambda x, y: x / y)
print(x3, x4, x5, x6)

11-sort方法的使用

# 有几个内置函数和内置类,用到了匿名函数
nums = [4, 8, 2, 1, 7, 6]

# 列表的sort方法,会直接对列表进行排序
# nums.sort()
# print(nums)


ints = (5, 9, 2, 1, 3, 8, 7, 4)
# sorted内置函数,不会改变原有的数据,而是生成一个新的有序的列表
x = sorted(ints)
print(x)

students = [
    {'name': 'zhangsan', 'age': 18, 'score': 98, 'height': 180},
    {'name': 'lisi', 'age': 21, 'score': 97, 'height': 185},
    {'name': 'jack', 'age': 22, 'score': 100, 'height': 175},
    {'name': 'tony', 'age': 23, 'score': 90, 'height': 176},
    {'name': 'henry', 'age': 20, 'score': 95, 'height': 172}
]

# 字典和字典之间不能使用比较运算<
# students.sort()

# foo() takes 0 positional arguments but 1 was given
# foo这个函数需要 0 个位置参数,但是在调用的时候传递了一个参数
# def foo(ele):
#     # print("ele = {}".format(ele))
#     return ele['height']  # 通过返回值告诉sort方法,按照元素的那个属性进行排序


# 需要传递参数 key 指定比较规则
# key参数类型是函数

# 在sort内部实现的时候,调用了foo方法,并且传入了一个参数,参数就是列表里的元素
# students.sort(key=foo)


students.sort(key=lambda ele: ele['score'])
print(students)
# 列表的sort方法,会直接对列表进行排序
# nums.sort()
# print(nums)

12-filter内置类的使用

# filter 对可迭代对象进行过滤,得到的是一个filter对象
# Python2的时候是内置函数,Python3修改成了一个内置类

ages = [12, 23, 30, 17, 16, 22, 19]
# filter可以给定两个参数,第一个参数是函数,第二个参数是可迭代对象
# filter结果是一个 filter 类型的对象,filter对象也是一个可迭代对象
x = filter(lambda ele: ele > 18, ages)
# print(x)  # <filter object at 0x000002670373E908>
# for a in x:
#     print(a)
adult = list(x)
print(adult)

13-map的使用

ages = [12, 23, 30, 17, 16, 22, 19]
m = map(lambda ele: ele * 2, ages)
print(list(m))
#[24, 46, 60, 34, 32, 44, 38]

map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每一个元素,并把结果作为新的Iterable返回。其语法格式为:

                                                        map(function,iterable...)

                                                        function---函数名

                                                        iterable---一个或多个序列

map作为高阶函数,事实上它把运算规则抽象了,我们可以用这种方式计算任意复杂的函数,再比如,把一个list的所有数据转为string类型:


链接:https://www.jianshu.com/p/11787cf6ee96

 

在Python里iterable被认为是一类对象,这类对象能够一次返回它的一个成员(也就是元素)。抽象一点就是
适合迭代的对象。实际上,任何具有__iter__()或__getitem__()方法的对象,Python就认为它是一个iterable。
Python里有大量内置的iterable类型,如: list,str,tuple,dict,file,xrange等。使用内置的iter()函数来生成
iterator

14-reduce的使用

from functools import reduce  # 导入模块的语法


# reduce 以前是一个内置函数
# 内置函数和内置类都在 builtins.py文件里

def foo(x, y):  # x=100,y=89;x=189,y=76;x=265,y=87
    return x + y  #


scores = [100, 89, 76, 87]
print(reduce(foo, scores))

students = [
    {'name': 'zhangsan', 'age': 18, 'score': 98, 'height': 180},
    {'name': 'lisi', 'age': 21, 'score': 97, 'height': 185},
    {'name': 'jack', 'age': 22, 'score': 100, 'height': 175},
    {'name': 'tony', 'age': 23, 'score': 90, 'height': 176},
    {'name': 'henry', 'age': 20, 'score': 95, 'height': 172}
]

# def bar(x, y):
#     # x= 0
#     # y = {'name': 'zhangsan', 'age': 18, 'score': 98, 'height': 180},
#     return x + y['age']


# print(reduce(bar, students, 0))
print(reduce(lambda x, y: x + y['age'], students, 0))

描述

reduce() 函数会对参数序列中元素进行累积。

函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

注意:Python3.x reduce() 已经被移到 functools 模块里,如果我们要使用,需要引入 functools 模块来调用 reduce() 函数:

from functools import reduce

语法

reduce() 函数语法:

reduce(function, iterable[, initializer])

参数

  • function -- 函数,有两个参数
  • iterable -- 可迭代对象
  • initializer -- 可选,初始参数

返回值

返回函数计算结果。

实例

实例(Python 3.x)
#!/usr/bin/python
from functools import reduce

def add(x, y) :            # 两数相加
    return x + y
sum1 = reduce(add, [1,2,3,4,5])   # 计算列表和:1+2+3+4+5
sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5])  # 使用 lambda 匿名函数
print(sum1)
print(sum2)
以上实例输出结果为:

15
15

15-内置函数的总结

print(any(['hello', '', 'yes']))
print(any(['', 0]))

nums = [1, 2, 3]
print(dir(nums))

print(dir('hello'))

shang,yushu = divmod(15, 2)

def test():
    """
    这是一个函数
    :return:
    """
    return 0
help(test)

Python any() 函数

正在上传…重新上传取消 Python 内置函数


描述

any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。

元素除了是 0、空、FALSE 外都算 TRUE。

函数等价于:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

Python 2.5 以上版本可用。

语法

以下是 any() 方法的语法:

any(iterable)

参数

  • iterable -- 元组或列表。

返回值

如果都为空、0、false,则返回false,如果不都为空、0、false,则返回true。


实例

以下展示了使用 any() 方法的实例:

>>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
 
>>> any(['a', 'b', '', 'd'])   # 列表list,存在一个为空的元素
True
 
>>> any([0, '', False])        # 列表list,元素全为0,'',false
False
 
>>> any(('a', 'b', 'c', 'd'))  # 元组tuple,元素都不为空或0
True
 
>>> any(('a', 'b', '', 'd'))   # 元组tuple,存在一个为空的元素
True
 
>>> any((0, '', False))        # 元组tuple,元素全为0,'',false
False
  
>>> any([]) # 空列表
False
 
>>> any(()) # 空元组
False

Python dir() 函数

正在上传…重新上传取消 Python 内置函数


描述

dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。

语法

dir 语法:

dir([object])

参数说明:

  • object -- 对象、变量、类型。

返回值

返回模块的属性列表。

实例

以下实例展示了 dir 的使用方法:

>>>dir()   #  获得当前模块的属性列表
['__builtins__', '__doc__', '__name__', '__package__', 'arr', 'myslice']
>>> dir([ ])    # 查看列表的方法
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>>

16-高阶函数

# 1. 一个函数作为另一个函数的参数
# 2. 一个函数作为另一个函数的返回值
# 3. 函数内部再定义一个函数


def foo():
    print('我是foo,我被调用了')
    return 'foo'


def bar():
    print('我是bar,我被调用了')
    return foo


# x = bar()
# print('x的值是{}'.format(x))
#
# print('------------------')
# x()

y = bar()()
print(y)


# 装饰器
def outer():
    m = 100

    def inner():
        n = 90
        print('我是inner函数')

    print('我是outer函数')
    return inner


outer()()
# 1. 一个函数作为另一个函数的参数
# 2. 一个函数作为另一个函数的返回值
# 3. 函数内部再定义一个函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

老板来片烤面包

君子博学于文,赠之以礼,谢君~

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

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

打赏作者

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

抵扣说明:

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

余额充值