python学习总结---函数使用 and 装饰器

本文深入探讨Python中的函数使用技巧,包括条件表达式、类型判断、递归函数、匿名函数、闭包及装饰器的运用。同时,提供了丰富的实践案例,如列表排序、字符串操作等。
# 函数使用

### 零碎知识

- 灵活的if-else

  ```python
  a = 3 if False else 5
  print(a)

  '''
  if False:
      a = 3
  else:
      a = 5
  '''
  ```

- 灵活的and/or

  ```python
  # 前面的表达式为真,才会执行后面的表达式
  a = True and 3
  print(a)

  # 前面的表达式为假,后面的表达式不需要执行
  b = False and 5
  print(b)

  # 前面的表达式为真,后面的表达式就不需要执行了
  c = True or 3
  print(c)

  # 前面的表达式值为假,才会执行后面的表达式
  d = False or 5
  print(d)

  ```

- 类型判断

  ```python
  a = 123

  # print(type(a))
  # if type(a) == int:
  if type(a) == type(1):
      print('整数')

  # 判断一个对象是否是一个类的实例
  print(isinstance(a, int))
  print(isinstance(a, float))

  def test():
      pass

  # print(type(test))
  # 不能这样判断
  # print(isinstance(test, function))
  # 判断是否可以调用
  print(callable(test))
  ```


### 递归函数

- 定义:在函数内部调用函数本身的函数叫递归函数。
- 组成:
  - 函数内部调用自己
  - 终止条件(停止调用自己的条件)
  - 核心算法
- 特点:
  - 代码简洁
  - 可读性差
  - 瞬间占用内存较大,终止条件出错会立即崩溃
  - 能不使用就不使用,在不得不使用的时候再使用(目录遍历)
- 练习:
  - 求n的阶乘

  - ```python
    #递归函数n的阶乘
    #1*2*3*....*n=jiecheng(n)=jiecheng(n-1)*n
    def jiecheng(n):
        if n==1:
            return  1
        return  jiecheng(n-1)*n

    print(jiecheng(4))
    ```

    ​

  - 斐波那契数列的第n项
    - 前两项都是1,后面的项都等于前两项的和

    - 示例:`1, 1, 2, 3, 5, 8, 13, 21, ...`

    - ```python
      def shulie(n):
          if n==1 :
            return 1
          elif n==2:
              return 1
          return shulie(n-1)+shulie(n-2)
      print(shulie(6))
      ```

      ​

### 匿名函数

- 函数可以向普通变量一样进行赋值

  ```python
  def test():
    print('for test')

  print(test.__name__)   
  # 函数可以像普通变量一样进行赋值
  a = test
  print(a.name)
  a()
  ```


- 函数可以作为参数传递

  ```python
    def show(func):
        func()

    # 函数可以作为参数传递
    show(test) 
  ```


- 匿名函数

  - 将函数作为参数传递时,若函数只需要一次,没有必要定义函数,可以通过匿名函数解决

  - 语法格式:

    ```
    lambda 参数列表: 表达式
    ```

  - 说明:

    - 可以有多个参数,多个参数之间使用逗号隔开
    - 表达式就是返回值,不需要使用return关键字

  - 示例

    ```python
    lt = [
        {'name': 'ergou', 'age': 18, 'height': '180'},
        {'name': 'dagou', 'age': 20, 'height': '170'},
        {'name': 'dahua', 'age': 19, 'height': '160'},
        {'name': 'cuihua', 'age': 21, 'height': '165'},
    ]

    def key(d):
        return d['age']

    # lt.sort(key=key)
    lt.sort(key=lambda d: d['height'])
    for i in lt:
        print(i)
    ```


  - 练习:

    - 自己实现列表的sort函数,支持逆序,可以排序任意类型的数据。

### 闭包使用

- 定义:

  - 外部函数中定义一个内部函数
  - 内部函数中使用外部函数的局部变量
  - 外部函数将内部函数作为返回值返回
  - 此时的内部函数就叫闭包

- 示例:

  ```python
  def wai(n):
      def nei():
          # 内部函数中使用外部函数的局部变量
          return n * n
      return nei

  f1 = wai(10)
  f2 = wai(5)

  print(f1())
  print(f2())
  ```


  ###装饰器

- 作用:当我们想要改变函数的原有功能时,但不想/不能改变原来的函数,就可以通过装饰器解决

- 使用:

  - 装饰器其实就是一个函数,该函数具有一个参数(函数类型),返回一个闭包
  - 在闭包中调用传递进来的函数,然后就可以在调用函数的前后添加内容了。

- 示例:

  ```python
    def zhuangshiqi(func):
        def wrapper():
            print('前面的装饰')
            func()
            print('后面的装饰')
        return wrapper

    def test():
        print('for test')

    # t = zhuangshiqi(test)
    # t()

    test = zhuangshiqi(test)
    test()

    @zhuangshiqi
    # 上面的语法相当于:hello = zhuangshiqi(hello)
    def hello():
        print('How are you?')

    hello()  
  ```


- 装饰器使用

  - 装饰无参无返回值的函数
  - 装饰带参无返回值的函数
  - 装饰带参有返回值的函数

### 练习

- 实现列表的排序,要求支持逆序和指定标准(key)

- ```python
  def list_sort(lt, key=None, reverse=False):
     n = len(lt)
     for i in range(n-1):
        for j in range(n-i-1):
           if key:
              if reverse:
                 if key(lt[j]) < key(lt[j + 1]):
                    lt[j], lt[j + 1] = lt[j + 1], lt[j]
              else:
                 if key(lt[j]) > key(lt[j + 1]):
                    lt[j], lt[j + 1] = lt[j + 1], lt[j]
           else:
              if reverse:
                 if lt[j] < lt[j+1]:
                    lt[j], lt[j+1] = lt[j+1], lt[j]
              else:
                 if lt[j] > lt[j + 1]:
                    lt[j], lt[j + 1] = lt[j + 1], lt[j]
     return lt
  lt = [
     {'name': 'xiaoming', 'age': 18},
     {'name': 'xiaoming', 'age': 15},
     {'name': 'xiaoming',  'age': 16},
     {'name': 'xiaoming', 'age': 17}
  ]
  print(list_sort(lt, key=lambda d: d['age'], reverse=False))
  ```

  ```python
  def sort(lt,key=None,reverse=False):
      n =len(lt)
      for i in range(n-1):
          for j in range(i+1,n):
            if key:
                is_swap = (key(lt[i]) <  key(lt[j]))  if reverse else (key(lt[i])> key(lt[j]))
            else:
                is_swap = (lt[i] < lt[j])  if reverse else (lt[i]>lt[j])
            if is_swap:
                lt[i] , lt[j] = lt[j], lt[i]
  lt = [
      {'age':12,'eight':60},
      {'age':16,'eight':70},
      {'age':18,'eight':50},
      {'age':11,'eight':90},
      {'age':15,'eight':80},
  ]
  sort(lt, key=lambda  d : d['age'],reverse=False)
  for i in lt :
      print(i)
  ```

  ​

- 计算一个字符串中所有数字的和(连数字为整体)

- ```python
  def char_count(string):
      len1 = len(string)
      sum = 0
      for i in range(len1):
          x = ord(string[i])
          if 49 <= x <=57 :
              a = int(chr(x))
              sum += a
          else:
              continue
          i += 1
      return sum
  str = input('请输入字符串:')

  print((char_count(str)))
  ```

  ​

- 实现一个字符串的逆序函数

- ```python
  def nixu_function(str):
      print(str[: : -1])
  a = input(str('请输入一个字符:'))
  nixu_function(a)
  print()
  ```

  ​

- 返回一个列表中出现次数最多的元素

- ```python
  def showmax(lt):
      index1 = 0                    #记录出现次数最多的元素下标
      max = 0                          #记录最大的元素出现次数
      for i in range(len(lt)):
          flag = 0                    #记录每一个元素出现的次数
          for j in range(i+1,len(lt)): #遍历i之后的元素下标
              if lt[j] == lt[i]:
                  flag += 1   #每当发现与自己相同的元素,flag+1
          if flag > max:   #如果此时元素出现的次数大于最大值,记录此时元素的下标
              index1 = i
      return lt[index1]               #返回出现最多的元素
  lt = [1,1,2,3,3,5,6,8,9,4,6,18,6,44,6,44,44,44]
  print(showmax(lt))
  ```

  ​

- 歌词解析:解析成一个时间戳语句歌词的形式,封装函数(根据时间返回歌词)

  ```
  [ti:蓝莲花]
  [ar:许巍]
  [al:留声十年绝版青春北京演唱会]
  [00:-01.70]蓝莲花
  [00:-00.70]演唱:许巍
  [00:00.00]
  [00:00.70]没有什么能够阻挡
  [00:06.01]你对自由的向往
  [00:11.43]天马行空的生涯
  [00:16.99]你的心了无牵挂
  [00:21.20]
  [02:11.55][01:50.60][00:22.63]穿过幽暗的岁月
  [02:16.93][01:55.60][00:27.81]也曾感到彷徨
  [02:22.21][02:01.09][00:33.13]当你低头的瞬间
  [02:27.62][02:06.33][00:38.32]才发觉脚下的路
  [02:31.64][02:10.23][00:42.37]
  [02:32.97][00:43.79]心中那自由的世界
  [02:38.23][00:49.50]如此的清澈高远
  [02:43.30][00:54.31]盛开着永不凋零
  [02:47.70][00:58.50]蓝莲花
  [02:53.95][03:00.06][01:05.41]
  ```

  ```python
  def song(t):
      ln = [
          [0.7,"没有什么能够阻挡"],
          [6.01,"你对自由的向往"],
          [11.43,"天马行空的生涯"],
          [16.99,"你的心了无牵挂"],
          [21.20," "],
          [22.63,"穿过幽暗的岁月"],
          [27.81,"也曾感到彷徨"],
          [33.13,"当你低头的瞬间"],
          [38.32,"才发觉脚下的路"],
          [42.37," "],
          [43.79,"心中那自由的世界"],
          [49.50,"如此的清澈高远"],
          [54.31,"盛开着永不凋零"],
          [58.50,"蓝莲花"],
          [65.41," "],
          [110.6,"穿过幽暗的岁月"],
          [115.6,"也曾感到彷徨"],
          [121.09,"当你低头的瞬间"],
          [126.33,"才发觉脚下的路"],
          [130.23," "],
          [131.55,"穿过幽暗的岁月"],
          [136.93,"也曾感到彷徨"],
          [142.21,"当你低头的瞬间"],
          [147.62,"才发觉脚下的路"],
          [151.64," "],
          [152.97,"心中那自由的世界"],
          [158.23,"如此的清澈高远"],
          [163.30,"盛开着永不凋零"],
          [167.70,"蓝莲花"],
          [173.95," "],
          [180.06," "]
      ]
      for i in range(len(ln)):  #遍历ln列表
          if t < ln[i][0]:      #找到t值第一次小于某时间的下标
              break              #找到之后结束循环
      i = i - 1                  #t时间段内正在播放i-1到i之间的歌词
      print(ln[i][1])            #输出对应的歌词
  while True:                    #死循环
      t = int(input("请输入秒数:"))
      if t == "#":               #当t位“#”时结束循环
          break
      song(t)
  ```

  ​
posted on 2018-09-08 17:02 liangzhiwen 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lzw19951020/p/9650030.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值