python变量类型怎么决定的_Python数据类型提示痛点的解决方案探讨

几个月前,你写了一段Python代码,当时只有你和上帝能看懂。几个月后,这段代码就只有上帝能看懂了。

痛点是什么

Python是一门弱类型的动态语言,在看其他人写的一些Python项目的代码、特别是大型项目的代码的时候,是不是会有这样的体验:很多函数的参数超多,而且很难看出来每个参数代表什么含义、是什么数据类型的、字典类型的参数究竟可以传哪些参数等等等。如果写这些代码的人习惯还不好,没有写什么注释或注释写的比较糟糕,那看这种代码简直就是一种折磨了,这样的情况下一开篇所描述的情景就并不算夸张了。这样的代码可读性、可维护性几乎为0。

解决方案

PEP 484类型提示语法

那么怎么解决上述痛点呢?Python 3.5版本在语言层面加入了一个新特性:类型提示(Type Hints,详情见开篇引文),可以以一种非常优雅的方式来对代码中变量的类型进行提示,大大提高了Python代码的可读性,例如下面这段代码:

def hello(name:str, age:int) -> str:

return 'hello, {0}! your age is: {1}'.format(name, age)

在IPython中输入这段代码,然后用help函数查看hello函数的帮组文档,显示内容如下:

In [10]: help(hello)

Help on function hello in module __main__:

hello(name: str, age: int) -> str

类型提示语法中,在变量或函数形参后面加:类型名称可以指明变量的数据类型,在函数定义def语句的后面加上-> 类型名称可以指明函数返回值的数据类型,非常方便。

PEP 484类型提示的不足之处

要注意的是,PEP 484的类型提示语言特性只在Python 3.5或更高版本才支持,而且仅仅是作为注释性的语法元素进行解析,在编译的时候类型提示相关的代码都是会被当做注释而忽略掉的,Python编译器并不会因为有了类型提示而对代码做任何类型检查。

更通用的解决方案:文档注释

那么还有没有更好、更通用的办法来解决上述类型提示痛点呢?有的,文档注释就是一个非常好的解决办法。

文档注释的优点

清晰、准确、完善的文档注释可以让Python代码的可读性、可维护性非常高。

不受Python语言版本的限制。

按照一定约定规范书写的文档注释,可以被一些第三方IDE或语法检查工具利用,从而可以对代码做静态类型检查,在语法层面检查代码是否有类型错误,也可以做一些代码补全方面的事情。

PyCharm风格的文档注释

这是一种个人比较推崇的文档注释格式,PyCharm IDE可以识别这种文档注释格式,从而进行代码静态语法类型检查、代码自动补全等操作。

下面是一个简单的示例,在示例中用文档注释标注了hello函数的功能描述、每个形参变量的含义和类型、函数的返回值类型等信息:

def hello(name, age, habits = []):

'''

Say hello to someone, and print some info.

:param name: name of someone

:type name: str

:param age: age of someone

:type age: int

:param habits: habits of someone

:type habits: List[str]

:return: a hello sentence

:rtype: str

'''

return 'Hello, {name}! Your age is {age}, and your habits are {habits}.'.format(name = name, age = age, habits = habits)

将上述代码输入到IPython中,然后执行hello?命令来查看hello函数的文档注释,结果如下:

In [28]: hello?

Signature: hello(name, age, habits=[])

Docstring:

Say hello to someone, and print some info.

:param name: name of someone

:type name: str

:param age: age of someone

:type age: int

:param habits: habits of someone

:type habits: List[str]

:return: a hello sentence

:rtype: str

可以看出函数的功能描述、每个参数的含义和数据类型、函数返回值的含义和数据类型都非常清晰明了。

numpy风格的文档注释

还有一种numpy项目中所使用的文档注释风格,也非常不错,可以参考。一个示例如下:

def squeeze(self, axis=None):

"""

Return a possibly reshaped matrix.

Refer to `numpy.squeeze` for more documentation.

Parameters

----------

axis : None or int or tuple of ints, optional

Selects a subset of the single-dimensional entries in the shape.

If an axis is selected with shape entry greater than one,

an error is raised.

Returns

-------

squeezed : matrix

The matrix, but as a (1, N) matrix if it had shape (N, 1).

See Also

--------

numpy.squeeze : related function

Notes

-----

If `m` has a single column then that column is returned

as the single row of a matrix. Otherwise `m` is returned.

The returned matrix is always either `m` itself or a view into `m`.

Supplying an axis keyword argument will not affect the returned matrix

but it may cause an error to be raised.

Examples

--------

>>> c = np.matrix([[1], [2]])

>>> c

matrix([[1],

[2]])

>>> c.squeeze()

matrix([[1, 2]])

>>> r = c.T

>>> r

matrix([[1, 2]])

>>> r.squeeze()

matrix([[1, 2]])

>>> m = np.matrix([[1, 2], [3, 4]])

>>> m.squeeze()

matrix([[1, 2],

[3, 4]])

"""

return N.ndarray.squeeze(self, axis=axis)

Emacs编辑器自动插入PyCharm风格的文档注释模板

如果你平时经常使用Emacs编辑器写Python代码,那么我写了一个简单的函数,可以方便地在python-mode一键插入上面所讲的PyCharm风格的文档注释。只需将下面的elisp代码加入你的Emacs配置文件中,然后在python-mode写完一个函数的def语句后,光标在def语句所在的行时按快捷键C-c C-a即可快速插入文档注释模板:

(defun insert-doc-annotation-below-current-line ()

"Insert doc annotations for python class or function below current line."

(interactive)

;; first, get current line text

(let ((cur-line-str (buffer-substring-no-properties (line-beginning-position) (line-end-position))))

(cond

;; judge whether current line text match python function define pattern

((string-match "^[[:space:]]*def.+?(\\(.*\\))[[:space:]]*:" cur-line-str)

;; first capture group of regex above is params list string

(setq params-str (match-string 1 cur-line-str))

;; split params list string to list, and do some strip operation

(setq params (split-string params-str ",[[:space:]]*" t "[[:space:]]*=.+?"))

;; go to end of current line and go to new line and indent

(goto-char (line-end-position))

(newline-and-indent)

;; insert head of doc annotation `'''`

(insert "'''")

(goto-char (line-end-position))

(newline-and-indent)

;; record current line number, jump back to here after inserting annotation

(setq annotation-top-line (line-number-at-pos))

(newline-and-indent)

(newline-and-indent)

;; insert each params annotation

(while params

;; NOT insert param `self`

(when (not (string-equal (car params) "self"))

(progn

(setq param (car params))

;; insert param name annotation line

(insert (format ":param %s: " param))

(newline-and-indent)

;; insert param type annotation line

(insert (format ":type %s: " param))

(newline-and-indent)

(newline-and-indent)))

(setq params (cdr params)))

;; insert return and return type annotation line

(insert ":return: ")

(newline-and-indent)

(insert ":rtype:")

(newline-and-indent)

;; insert tail of doc annotation

(insert "'''")

;; jump back to the position of annotation top

(goto-line annotation-top-line)

(indent-for-tab-command))

((string-match "^[[:space:]]*class.+?:" cur-line-str)

(goto-char (line-end-position))

(newline-and-indent)

;; insert head of doc annotation `'''`

(insert "'''")

(goto-char (line-end-position))

(newline-and-indent)

;; record current line number, jump back to here after inserting annotation

(setq annotation-top-line (line-number-at-pos))

(newline-and-indent)

;; insert tail of doc annotation

(insert "'''")

;; jump back to the position of annotation top

(goto-line annotation-top-line)

(indent-for-tab-command))

(t (message "current line NOT match neither function nor class!")))))

(add-hook 'python-mode-hook

(lambda ()

(local-set-key (kbd "C-c C-a") 'insert-doc-annotation-below-current-line)))

总结

最终决定采用文档注释这种更通用的方式在Python代码中做类型提示,虽然无法做到要求其他的人都能为他们自己的Python代码提供完备、清晰的文档注释,但提升代码的可读性可以先从自身做起,起码可以防止那种自己也读不懂自己的代码、只有上帝才能看懂的尴尬局面的发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306754.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——图-最短路径长度中最大的一个

#include<stdio.h> #include<string.h> #define INF 32767 #define MAXVEX 30 int dist[MAXVEX]; //建立dist数组int path[MAXVEX]; //建立path数组int S[MAXVEX]; //建立S数组typedef char VertexType;typedef struct graph {int n,e;VertexType vexs[MAXVE…

一个情怀引发的生产事故

在一个项目中&#xff0c;需要轻量级用到脚本语言&#xff0c;来提高应用服务的灵活性。因为知道Roslyn可以动态编辑C#&#xff0c;本着情怀&#xff0c;就自然用Roslyn来处理这块业务了。开在windows上执行&#xff0c;一次调用风平浪静&#xff0c;因为这个功能使用频次不高&…

python standardscaler_教你用python一步步解决“维度灾难”

全文共7016字&#xff0c;预计学习时长40分钟或更长现代科技时代产生和收集的数据越来越多。然而在机器学习中&#xff0c;太多的数据可不是件好事。某种意义上来说&#xff0c;特征或维度越多&#xff0c;越会降低模型的准确性&#xff0c;因为需要对更多的数据进行泛化——这…

南湖量子计算机科学课程,《量子计算》暑期课程开课通知

课程题目&#xff1a;《量子计算》暑期课程课程时间&#xff1a;2019年7月8-12日(星期一至星期五)下午2:30-5:30上课地点&#xff1a;中南大学校本部科教北楼105授课老师&#xff1a;孙晓明、田国敬 中国科学院计算技术研究所授课对象&#xff1a;全院师生联 系 人&#xff1a;…

c++的输入和输出

1. 输入/输出流的成员函数 put()函数 put函数常用的调用形式&#xff1a; cout.put(char ch); 功能&#xff1a;用于输出一个字符&#xff0c;还可以是ASCII代码&#xff08;或者是ASCII表达式&#xff09; cout.put(65)&#xff1b; get()函数 常用形式为&#xff1a;cin.g…

被 C# 的 ThreadStatic 标记的静态变量,都存放在哪里了?

一&#xff1a;背景 1. 讲故事前几天公号里有一位朋友留言说&#xff0c;你windbg玩的溜&#xff0c;能帮我分析下被 ThreadStatic 修饰的变量到底存放在哪里吗&#xff1f;能不能帮我挖出来????????????&#xff0c;其实这个问题问的挺深的&#xff0c;玩高级语言…

唐山师范学院计算机论文,唐山师范学院校园网络解决方案 毕业论文

唐山师范学院校园网络解决方案 毕业论文 (43页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;9.90 积分1 唐山师范学院 专 科毕业论文 题 目 唐山师范学院校园网络解决方案 学 生 指导教师 年 级 200…

基本系统设备感叹号更新不了_电脑识别不了U盘?别紧张,免费教你如何解决...

你的电脑会出现识别不了U盘的情况吗&#xff1f;为什么会识别不了U盘你了解过吗&#xff1f;首先我们说一下&#xff0c;U盘作为一个办公必备品&#xff0c;用来存储文件以便随时使用&#xff0c;简单方便。但是如果某一天你的电脑突然之间无法识别U盘的话&#xff0c;就代表新…

群同态基本定理证明_群论(7): 群代数, 群表示基础

内容提要:1 群代数; 2 域上的有限维群代数和Maschke定理; 3 函数环; 4 代数闭域上的群表示论; 本文主要参考文献.本文的前置内容为:格罗卜&#xff1a;群论(1): 群, 同构定理, 循环群格罗卜&#xff1a;群论(2): 群作用, Sylow定理更多内容&#xff0c;请移步专栏目录:格罗卜&a…

c++的文件输入/输出

1文件的概述 根据文件中数据的组织形式分为&#xff1a; 1 文本文件 文本文件又称ASCII文件&#xff0c;它的每一个字节存放一个ASCII代码&#xff0c;代表一个字符 输出文本&#xff1a;接收从内存输出的数据 输出文件&#xff0c;向它写入数据 ofstream fout; 输入文件&…

南阳理工计算机全国排名,全国工科实力最强的10所高校排名,

评价工科实力一个非常明显的指标就是学科实力&#xff0c;2017年公布的第四次学科评估结果就是最好的参考。下面就以学科评估排名全国5%的学科数作为评比基准&#xff0c;对国内主要高校的工科实力进行一个排名&#xff0c;结果如下&#xff1a;前3甲&#xff1a;清华大学、浙江…

真正的高手,都有增长思维!(深度好文)

点击蓝字关注&#xff0c;回复“职场进阶”获取职场进阶精品资料一份职场&认知洞察 丨 作者 / findyi这是findyi公众号分享的第99篇原创文章最近几年互联网红利消亡&#xff0c;老板们非常焦虑。这也一度让所谓的「首席增长官」被媒体热炒。仿佛来一个增长的救世主&#xf…

service层中有某个事物要立马提交_硬货你要的,binder机制来了

欢迎关注专栏&#xff1a;里面定期分享Android和Flutter架构技术知识点及解析&#xff0c;还会不断更新的BATJ面试专题&#xff0c;欢迎大家前来探讨交流&#xff0c;如有好的文章也欢迎投稿。Android高级进阶​zhuanlan.zhihu.com前言Binder做为Android中核心机制&#xff0c;…

服务器虚拟化分为半,服务器虚拟化有哪些?

你好&#xff0c;服务器虚拟化分为完全虚拟化和半虚拟化&#xff0c;完全虚拟化(Full Virtualization)&#xff1a;在当前的系统级虚拟化解决方案中&#xff0c;全虚拟化应用得非常普遍&#xff0c;典型的有知名的产品有VirtualBox、KVM、VMware Workstation和VMware ESX(它在其…

学习笔记 | 传统企业互联网改革之道

【学习笔记】| 作者 / Edison Zhou这是EdisonTalk的第306篇学习分享最近在看刘润老师的《互联网战略版&#xff1a;传统企业&#xff0c;互联网在踢门》&#xff0c;学习了传统企业互联网改革的价值模型与三大模式&#xff0c;醍醐灌顶受益良多。因此&#xff0c;我将我学到的总…

蓝桥杯杂题

蓝桥杯杂题开始聊天吧气球升起度熊所居住开始聊天吧 #include<bits/stdc.h> using namespace std; set<char>S; int main() {string s;while(cin>>s){S.clear();for(auto x:s)//使用x拷贝s字符串 中的每一个字符 {S.insert(x); //将每一个字符插入到集合S中/…

setnx是原子操作吗_谈谈Volatile关键字?为什么不能保证原子性?用什么可以替代?为什么?...

大家好&#xff0c;欢迎关注我的公众号码猿bug,需要资料的话可以加我微信好友。再谈volatile关键字之前&#xff0c;首先必须聊聊JMM内存模型&#xff01;JMM主要的特性&#xff1a;可见性、原子性&#xff0c;顺序性Java 虚拟机规范试图定义一种 Java 内存模型&#xff08;JMM…

360 屏蔽ajax,怎么在easy ui做全局Ajax拦截啊?

满意答案egiuas2014.08.13采纳率&#xff1a;53% 等级&#xff1a;9已帮助&#xff1a;167人在web.xml中定义一个全局过滤器拦截所有请求&#xff1a;自定义filter your difine filter name /* 后台代码&#xff1a;过滤器中获取session用户对象 如果为空&#xff0c;返回超…

c++的STL

STL&#xff0c;英文全称 standard template library&#xff0c;中文可译为标准模板库或者泛型库&#xff0c;其包含有大量的模板类和模板函数&#xff0c;是 C 提供的一个基础模板的集合&#xff0c;用于完成诸如输入/输出、数学计算等功能。 泛型编程指编写完全一般化并可重…

【招聘(深圳)】TCL通讯科技控股有限公司

Windows 架构师 (25-35K)工作职责&#xff1a;1. 负责windows平台产品功能的需求分析、系统设计和规划&#xff1b;2. 负责Windows 平台关键功能技术预研、技术攻坚、性能优化。岗位核心价值&#xff1a;智能连接中WINDOWS投屏部分的架构技术分解和技术攻坚。关键工作任务&…