这样的奇技淫巧,劝你不用也罢
假设我现在使用print
大法打印了一段日志:
print('我是日志')
我想把这段日志注释掉,大家会怎么做呢?相信大多数人都是在行首加上一个#
号:
# print('我是日志')
有些人可能也会用多行注释:
"""
print('我是日志')
"""
但有些人,偏偏喜欢另辟蹊径标新立异,非要跟大家不一样,他们是这样写的:
print:('我是日志')
在print
和左括号之间,加了一个冒号。从效果上看,确实也起到了注释的作用:
[image:029695FF-7538-4215-8977-31A43EE9B51C-383-0000504BC19305F0/047B50A4-F251-42F3-B1D2-16EA50CD86E3.png]
为什么这样写也能实现注释的效果呢?这就要从 Python 的类型标注
说起。
Python作为一个动态语言,其本身对变量类型是没有强制要求的,同一个变量,我们既可以让它是int,也可以让它是字符串:
a = 1
a = 'x'
但项目规模大起来以后,这种特性可能会带来很多难以察觉的隐患。因此,Python引入了一个新的功能,叫做类型标注
。在定义变量、函数接收参数的时候,我们可以指定它们的类型,如果赋值或者传递参数的时候类型不匹配,IDE会给你加上深色背景,提醒你这里有问题,如下图所示:
但类型标注这个功能是给IDE或者静态检查工具使用的,Python解释器在解释代码的时候,会自动忽略它。所以即使你强行不遵守也没有关系,如下图所示:
.
有些人正是看中了Python解释器自动忽略类型标注这个特点,动起了歪脑筋,干起了奇技淫巧的勾当。
因为类型标注中,冒号后面的类型
,除了我们常见的类型外,还可以是我们自定义的类,甚至是一个列表:
class People:
def __init__(self, name, age):
self.name = name
self.age = age
kingname = People('kingname', 28)
kingname_clone: People = kingname
kingname_god: [1, 2, 3] = kingname # 这里,强制标注 kingname_god 变量的类型为[1, 2, 3]。
同时,类型标注也可以不赋值,所以这样写也是可以的:
a: int
这样一来,显然下面这种写法也是可以的:
kingname_god: [1, 2, 3]
现在,我们把列表改成元组,于是就变成了:
kingname_god: (1, 2, 3)
现在我们把kingname_god
改成print
,于是我们就得到了:
print: (1,2, 3)
因为元组也可以只有一个元素,所以显然:
print:('我是日志')
这种写法也是合法的,它表示把 print
变量标注为('我是日志')
类型,但不赋值。
由于Python 解释器会自动忽略类型标注,所以对于这种没有赋值的类型,Python 会自动忽略整行,所以看起来就像是被注释了一样。
为了更好地证明print:('我是日志')
本质上是一个没有赋值的类型标注,我们来看一下字节码:
可以看到,这两种写法,我们一行一行对比,他们的字节码流程完全一样,差别仅仅在用的类型是int
还是'我是日志'
,以及变量名是a
还是print
。
除了print
外,任何我们自定义的函数甚至是字典、列表都可以这样写,例如:
但我真切希望,任何一个脑袋正常的同学都不要这样写。这种写法除了炫技以外没有任何作用。
- 浏览器缓存问题的解决
- nginx下目录浏览及其验证功能、版本隐藏等配置记录
- Sqlite的多表连接更新
- Enterprise Library 4.1学习笔记6----加密应用程序块
- 浅谈数据库主键策略
- nginx应用总结(1)--基础认识和应用配置
- nginx反向代理tomcat访问时浏览器加载失败,出现 ERR_CONTENT_LENGTH_MISMATCH 问题
- Enterprise Library 4.1学习笔记5----实体验证程序块
- Python防止sql注入
- 电工学PLC编程的入门建议
- 人工智能、区块链、图灵测试……这30个大数据热词你真的都懂吗?
- Enterprise Library 4.1学习笔记4----缓存应用程序块
- 设置py文件的路径
- jenkins中通过git发版操作记录
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Mybatis plus自动生成业务代码
- 功能强大的CD工具 - flagger
- Swift defer
- MySQL 最佳实践:CPU 100%,MySQL 到底在干什么
- 【译】Flutter 1.20 发布
- 算法面试题:一个List,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点!
- Angular CLI创建的项目文件用途一栏
- [888]python内置函数vars()|dir()|locals()
- Mdnice,一种记录知识的新方式
- [887]python中@classmethod和@staticmethod
- leetcode每日一题-99. 恢复二叉搜索树
- Java 两个经纬度获取方位
- 使用Python实现基本初等函数可视化
- 递归回溯--复原IP地址
- 通过 generic-webhook-trigger 插件实时获取 Bitbucket Repository Events