zoukankan      html  css  js  c++  java
  • 函数(01)

    这一周都没有休, 陪着业务小姐姐, 导那些历史数据, 真的让我有点崩溃, 各种问题, 最后总结出一个问题, 就是数据的问题, 真的是经验教训. 首先是关系型数据库不能识别的特殊字符, 其次是数据空行, 数据库以为是 空值, 导致一直主键更新错误; 最后是数据编码, utf8 和 utf8_sig 有很大不同, 哇, 这一波坑踩得有点难受, 好在都就发现了, 不然又要凉了. 经验, 真的就是, 采的坑多了, 边累计为了经验. 这也是现在自己有事没事, 写的笔记, 一方面督促自己学而时习之和不求甚解, 另外就是记录踩个的坑...

    不扯了, 回到正题, 零星地回顾一些函数基础, 虽然不怎写Python代码, 但我还是始终保持良好的状态, 毕竟是我现在的第二语言, 当然第一是 sql, 这两个老大哥, 都要安排上, 每天.

    在 Python 语言中, 程序的最小单元, 是函数. 从我认知来看, 使用函数, 应该是所有编程语言的基础. 我人认为, 编程学习和编程思维的训练, 核心在于深刻理解两个关键点:

    • 控制流: IF - ELSE 和 循环 (FOR, WHILE)
    • 使用和编写函数

    包括现在, 回过头一想, 我每天不论是抄的, 写的那些低质量代码, 始终围绕着, 函数 (封装功能), 控制流, 注入功能和数据处理逻辑这样, "不断堆砌", 俗称搬砖嘛, 很形象.

    其实要以最为通俗的直观感来区分, 编程中的函数, 和数学中的函数的区别.

    • 数学函数, 表示映射关系, 比如 实数 -> 实数, 实数 -> 向量; 向量 -> 向量; 向量-> 矩阵; 矩阵 -> 实数 ....
    • 编程函数, 表示一段逻辑, 类似容器, 对一段代码的封装, 指向某个功能, "输入 -> 处理 -> 输出"

    二者是有本质上的区别的.

    接收任意个参数

    需求

    构造一个可接受任意数量参数的函数.

    方案

    首先这场景非常多, 我认为最为实用是, 异常处理, 有的时候追求程序的稳健性, 不知道用户到底会填几个, 或者过程中, 调用别的兄弟的函数, 接收的时候, 不知会有几个结果 .. 这类场景.

    通过 * 参数来完美解决.

    第一种是, 通过 *args 将任意 个 参数, package 为元组.

    # * 对参数组包 package
    
    def my_avg(first, *rest):
        """对输入参数求均值"""
        return (first + sum(rest)) / (1 + len(rest))
    
    # test 
    print(my_avg(1, 2)) 
    print(my_avg(1,2,3,4,5))
    
    1.5
    3.0
    

    通过 *args 的写法, 可将多个参数打包 package 为一个 元组 Tuple. 然后在代码中, 将其作为一个序列来进行各种骚操作.

    第二种是, 通过 **kwargs 将任意 组 关键字参数, 以字典形式 组包 package

    def any_args(a, b=123, *args, **kwargs):
        """完整且健壮的函数写法"""
        print(a)
        print(b)
        print(args)
        print(kwargs)
        
    # test 
    any_args(1,2, 3,4,5)
    
    1
    2
    (3, 4, 5)
    {}
    

    只接收关键字参数

    需求

    希望函数的某些参数, 只能通过关键字参数传递

    方案

    通过 关键字参数, 放到某个 * 或者单个 * 后面即能实现这种效果.

    # 强制要求用关键字传参 
    
    def recv(maxize, *, block):
        'receives a message'
        pass 
    
    # test 
    recv(1024, block=True)  # 这个 ok
    recv(1024, True)  # TyepError
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-22-f823bb78270b> in <module>
          5 # test
          6 recv(1024, block=True)
    ----> 7 recv(1024, True)
    
    TypeError: recv() takes 1 positional argument but 2 were given
    

    通过这种小 Tips, 我们还能实现, 在接收任意多个位置参数的函数中, 指定关键字参数.

    def minimum(*values, clip=None):
        """返回参数序列中最小值"""
        m = min(values)
        if clip is not None:
            m = clip if clip  > m else m 
        return m 
    
    # test
    print(minimum(1, 2, -5, 4, 3)) 
    print(minimum(1, 2, -9, 2, 3, clip=0))
    
    -5
    0
    

    这种三元表达式的写法, 还是可以的, 以前我觉得有点难懂, 现在倒是觉得非常简洁优雅. 即, 如果 if 的内容为 True, 则返回左边; else 则返回右边.

      m = clip if clip  > m else m 
    
    # 3 元表达式 
    
    ret = '对' if  1 + 1 == 2 else '不对'
    
    ret 
    
    '对' 
    

    返回多个值

    需求

    一个函数, 能返回多个值 , 对象

    方案

    通过 return 一个元组 (用逗号',' 隔开) 即可.

    def my_func():
        return 1,2,3 
    
    # test
    a, b, c = my_func()
    
    print(a, b, c)
    
    1, 2, 3
    

    当调一个返回元组的函数式, 通常会将结果赋值到多个变量, 也就是拆包 unpack. 当然也可以不拆, 用一个变量接收, 那这样, 这个变量就指向这个元组本身了.

    x = my_func()
    
    print(x)
    
    (1, 2, 3)
    

    先到这吧, 感觉今天有点不在状态, 不想再反复温习了....

  • 相关阅读:
    AlphaMobileControls
    .NET Compact Framework下注册表导出工具的开发
    windows moblie 5.0在托管程序中实现短信接收和拦截
    自定义MessageBox
    Windows Mobile 背景灯控制
    windows Mobile 启动Mobile Office
    windows mobile 5.0 进程管理、窗体管理、重启和关闭操作系统
    让Windows Mobile模拟器通过你的PC上网
    Windows Mobile获取存储卡容量及使用情况
    透明背景
  • 原文地址:https://www.cnblogs.com/chenjieyouge/p/13252531.html
Copyright © 2011-2022 走看看