TIOBE排行榜是程序开发语言的流行使用程度的有效指标,对世界范围内开发语言的走势具有重要参考意义。随着数据挖掘、机器学习和人工智能相关概念的风行,Python一举收获2018年年度语言,这也是Python继2007和2010年之后第三次问鼎榜单。前阵子在GitHub创建Profile README时惊觉Python是我的第二高频语言,回想第一次见到positional only parameter传参方式时一头雾水的查找资料,借由周末闲暇,将Python函数传参的部分语法糖做一次总结。Python是Guido van Rossum(以下简称GvR)在1989年圣诞节创造的编程语言,支持多种编程范式,1991年对外发布了第一个版本。随后的2000年发布了Python2,2008年发布了不完全向前兼容的Python3,Python语言目前由Python基金会进行维护,2020年1月1日Python2正式落幕,因此本文所述内容均基于Python3。在Python中将面向过程方式声明的函数(即不归属于类)称为函数(function),而面向对象方式声明的函数称为方法(method)。语法糖1:实例方法第一个参数默认为当前实例对象,类方法第一个参数默认为当前类对象,静态方法没有该约束。

# 函数def greeting():  print("function")class Human:  # 实例方法  def greeting(self):    print("instance method")    # 类方法  @classmethod  def write(cls):    print("class method")    # 静态方法    @staticmethod  def read():    print("static method")

语法糖2:

参数可以具备默认值,对比Objective-C由于这项特性的缺失需要实现构造方法和便利构造方法。

def greeting(name = "Jack Ma"):  print("Hello", name)  >>> greeting()Hello Jack Ma>>> greeting("Pony Ma")Hello Pony Ma

语法糖3:通过*args表示可变参数。

def calc(name, *args):  spent = 0  for v in args:    spent += v  print(name, "spent money:", spent)  >>> calc("Jack Ma", 1000000, 2000000)Jack Ma spent money: 3000000

传入的参数通过type(args)可以检查类型为元组(tuple),除了函数声明外函数调用亦然。

>>> args = (1000000, 2000000, 3000000) # [1, 2, 3]同理>>> calc("Jack Ma", *args)Jack Ma spent money: 6000000

通过**kwargs以键值对的形式表示可变参数。

def calc(name, **kwargs):  spent = name + " spent on:"  for k, v in kwargs.items():    spent += "%s=%s," % (k, v)  print(spent)>>> calc("Jack Ma", eating=10000, shopping=20000)Jack Ma spent on:eating=10000,shopping=20000

同理,函数调用亦然。

>>> kwargs = {"eating":10000, "shopping":20000}>>> calc("Jack Ma", **kwargs)Jack Ma spent on:eating=10000,shopping=20000

自Python1起就支持通过位置和参数名称两种方式传递参数,如对于原型为def add(x, y)的函数,同时支持以下两种调用方式。

add(1, 2)add(x=1, y=2)

语法糖4:

Keyword-Only Arguments (PEP-3012)

函数声明时,参数列表中单独的*表示在此之后的参数仅支持通过名称进行传递。通过这个语法可以在可变参数列表之后传递其他参数。

def compare(a, b, *, key=None):  pass  >>> compare(1, 2, 3) # 调用失败Traceback (most recent call last):  File "", line 1, in TypeError: compare() takes 2 positional arguments but 3 were given>>> compare(1, 2, key=3) # 调用成功

语法糖5:

Positional-Only Parameters (PEP-570)

函数声明时,参数列表中单独的/表示在此之前的参数仅支持通过位置进行传递。这个语法主要解决部分函数的参数没有实际意义,后续可能会进行修改,避免通过名称传递参数在名称修改后失效。比如int(x="1")中x并没有实际意义,而且相比int("1")可读性有所不足。

def name(positional_only_parameters, /, positional_or_keyword_parameters,         *, keyword_only_parameters):  pass

此外,官方文档表述这个语法还解决了某个边界条件下的调用失败。对于以下函数:

def foo(name, **kwargs):    return 'name' in kwargs

当我们传递的kwargs拥有一个"name"的key时会调用失败,如下。

>>> foo(1, **{'name': 2})Traceback (most recent call last):  File "", line 1, in <module>TypeError: foo() got multiple values for argument 'name'

通过以下方式可以解决这个问题。

def foo(name, /, **kwargs):    return 'name' in kwargs

语法糖6:如何修改参数的引用,官方文档解释称:Python中参数的传递通过值传递(但引用是通过值传递的,参考链接2),最简单的方式是将入参按顺序以元组进行返回。

  • https://docs.python.org/zh-cn/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

  • https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference

语法糖7:由于Python的first-class function特性,函数作为一等公民可以像其他类型一样进行传递和赋值。比如max函数原型可以传入一个用于比较的函数,当然函数也可以被重新赋值。

>>> max=min>>> max(19,9)9

全局函数和关键字有时候会不易分辨,比如print在Python2中是关键字,而在Python3中是内置函数。可以通过下列方式获取关键字列表。

>>> import keyword>>> keyword.kwlist['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

语法糖8:类型标注(Type Hint)通过:type表示参数类型,由于Python动态类型的特性Python 运行时并不强制标注函数和变量类型,类型标注可被用于IDE等第三方工具。如下:

def greeting(name: str) -> str:    return 'Hello ' + name

详细内容可以参考官方中文文档:

  • https://docs.python.org/zh-cn/3/library/typing.html

回想第一次在Python作者GvR的500-lines-of-code中见到Keyword-Only Arguments的用法几度无法理解代码为什么能够正常运行,顺便一提,该项目同时也是绝佳的编程学习材料。行文至此语法糖的数量超出了我的预期,本篇文章创作期间我惊喜的发现官方已经宣告了Python2的落幕,官方文档提供了简体中文版本,而Python也已经发布了3.9版本,被称为BDFL的GvR也在2018年通过邮件组宣布了权力的交接。通过TIOBE长期榜单变化可以发现,Python作为这个榜单的常青树且仍然保持着上升趋势,身边也有不少人自学这门语言。文章的最后摘录Python之禅与各位共勉。

>>> python3>>> import thisThe Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!

assert函数_悉数Python函数传参的语法糖相关推荐

  1. python return函数_理解Python函数中的return关键字

    一.说明 return 语句是Python函数返回的结果,可以是数值.字符串.列表.表达式.函数等: return 语句将Python函数的结果,返回到调用的地方,并把程序的控制权一起返回,即在函数中 ...

  2. python center函数_利用Python函数实现一个万历表完整示例

    前言 大家可以根据格式化打印字符去调一下最后的输出,不过有中文好像不好调整,可以换成星期的单词,这样应该会好一点,format()函数可以用来格式化打印字符,format()可以使用字符串去调用,也可 ...

  3. python 排名函数_一个危险的Python函数,不推荐使用

    本文由编程派根据 Hacker News 上曾经排名第一的文章 编译而来,作者 Hynek Schlawack 是一名德国软件工程师. 他建议, 除非是编写只兼容 Python 3 的代码而且清楚地了 ...

  4. java调用python,传参json字符串,含中文传参

    java调用python,传参json字符串 python脚本内容(test.py) # -*- coding: utf-8 -*-def main(input):return input java调 ...

  5. python 元组传参 *args 字典传参 **kwargs 的用法

    python 元组传参 *args 字典传参 **kwargs 的用法 # 元组参数 def func_arg(*args):print("args:", args) func_a ...

  6. python包裹 函数_关于Python中包裹传参和解包裹的理解

    1.包裹传参 首先思考一个问题:为什么要有包裹传参?原因包括但不仅限于以下两点:①不确定参数的个数.②希望函数定义的更加松散灵活 包裹传参分两种:包裹位置传参和包裹关键字传参.先看包裹位置传参: 在这 ...

  7. python四大高阶函数_详谈Python高阶函数与函数装饰器(推荐)

    一.上节回顾 Python2与Python3字符编码问题,不管你是初学者还是已经对Python的项目了如指掌了,都会犯一些编码上面的错误.我在这里简单归纳Python3和Python2各自的区别. 首 ...

  8. python pos函数_使用python+sklearn实现特征提取

    sklearn.feature_extraction模块可用于以机器学习算法支持的格式从原始数据集(如文本和图像)中提取特征.**注意:**特征提取与特征选择有很大不同:前者是将任意数据(例如文本或图 ...

  9. python diff函数_使用Python创建你自己的diff工具

    为什么我需要自己的diff工具? 我经常使用git跟踪我的编码项目.文章.业务工作等等.git的一个美妙之处在于,你可以通过简单地使用其内置的diff功能来轻松地比较你的工作的不同状态.要使用这个功能 ...

最新文章

  1. insert语句让我学会的两个MySQL函数
  2. vs2008、vs2010、vs2012中查看变量在内存中的内容的方法
  3. 32-第3章 数据链路层--抓包分析数据帧格式
  4. SAP Cloud for Customer前台发送到后台的HTTP请求,遇到错误该怎么分析
  5. 后端:Layui实现文件上传功能
  6. 三星Galaxy S20 FE 5G正式在国内发布 售价4999元起
  7. flash小黄油安卓_99%安卓被这个小破软件给干了?拥有它!Google直呼内行!
  8. remove Host from VMware cluster
  9. 小知识--电脑隐藏文件
  10. 快慢指针在数组中的应用
  11. Flash Timer的用法 计时器
  12. cmpp java代码_CMPP2.0 java实现基于 协议。 多个厂家的版本都有体现。 Develop 238万源代码下载- www.pudn.com...
  13. python安装Jpype
  14. 碰见参数错误咋解决?
  15. 11决策树算法;12案例实战:使用sklearn构造决策树模型(含数据)
  16. np.stack()函数详解
  17. html 整个页面只能看,如何截图整个完整的网页页面(包含滚动条下面看不到的网页)...
  18. 基于分类方法的银行客户流失预测
  19. 历年评书出版一览表(1955~1994)
  20. VS中怎么将一个页面设置为起始页的解决方案以及关于粘贴的小窍门

热门文章

  1. rzsz上传下载命令
  2. Spring Boot基础学习笔记04:Spring Boot加载自定义配置文件
  3. 大数据学习笔记44:Hive架构
  4. 安卓案例:演示广播接受者
  5. 安卓案例:启动和停止服务
  6. wifi传输信息需要连接服务器,基于近场通信的WiFi传输连接方案.pdf
  7. 【英语学习】【Level 07】U07 Stories of my Life L4 Not my best moment
  8. 确定了C/C++的学习路线之后,便只能是一条路走到黑了
  9. 采用MATLAB的DSP调试方法
  10. c++怎么将两个类的方法集合成一个类的方法_一文帮你梳理 Java 集合