Python避坑指南(续)

news2025/7/18 2:30:37

在上一篇《Python避坑指南》中,我重点给大家讲了Python可变容器数据类型中的坑。除了这些,Python还有其他一些细小方面的坑,本章为大家讲解Python中这些大家可能会忽视的细节。

在这里插入图片描述

文章目录

    • 链式`or`的坑
    • 访问字面量属性的坑
    • `is`的坑
    • GIL全局锁的坑
    • 多数据返回的坑
    • JSON中的坑

链式or的坑

Python支持简化链式逻辑判断。比如:

if a > 1 and a < 3:

可以简化成:

if 1 < a < 3:

当多个相等判断连接时,比如

if a == 3 or b == 3 or c == 3:

可能有人会简化成这样:

if a or b or c == 3: # !这是错的!

注意:上面的代码是错的!因为or==的优先级要低。上面表达式的执行顺序是 if (a) or (b) or (c == 3):

替代链式or的更好的方法是用系统内置的any()方法。

if any([a == 3, b == 3, c == 3]): # 正确

如果嫌上面代码太重复,编码不够高效,可以优化成下面这种写法:

if any(x == 3 for x in (a, b, c)): # 正确

如果比较的值都是相同的,还可以进一步简化为:

if 3 in (a, b, c): # 正确

这里我们用in判断要比较的值是否在待比较的变量构成的元组中。

同理,下面这种写法也是不对的:

if a == 1 or 2 or 3:

应该这样写:

if a in (1, 2, 3):

访问字面量属性的坑

Python中一切皆对象,即便是字面量也是对象。例如7,在Python中也是对象。这也就意味着7也有属性和方法。例如bit_length()这个方法,它会返回表示这个值所需的二进制位数。

x = 7
x.bit_length()
# Out: 3

上面的代码是可以正确输出的。应为7的二进制是111,需要3位二进制来表示,所以bit_length()会返回3。你可能直观地感觉7.bit_length()也一样会返回3。但不幸的是你会得到 SyntaxError。为什么会这样?这是因为Python中.有两重含义,即可以是访问对象的属性,也可以是表示浮点数。Python解析器需要区分到底是哪一种含义。7.bit_length()7.2 解析器无法区分,因此会报语法错误。

有两种办法可以直接访问字面量的属性:

(7).bit_length() # 用括号将字面量括起来,告诉解析器这里7不是个浮点数
7 .bit_length()  # 7后面加个空格,告诉解析器这里7不是个浮点数

注意:这里加两个点7..bit_length是不对的。这样写第一个点会被理解为浮点数,第二个点会访问对象的属性。虽然语法上没有歧义,但是浮点数是没有bit_length()方法的。这里如果访问的是浮点数对象有的属性或方法,程序是可以正常运行的。

7..as_integer_ratio()
# Out: (7, 1)

is的坑

编程过程中,整型和字符串是使用最多的数据类型。为了减少整型和字符串频繁创建带来的内存开销,Python会用内部缓存一定范围的整数和字符串。当我们用is判断两个对象是否是同一个对象时,这里的内部缓存机制可能会带来让人迷惑的结果。比如:

>>> -8 is (-7 - 1)
False
>>> -3 is (-2 - 1)
True

再举一个例子:

>>> (255 + 1) is (255 + 1)
True
>>> (256 + 1) is (256 + 1)
False

这里的输出结果着实让人疑惑。-3, 255就返回True,-8, 256就是False。

更具体地说,在[-5, 255]区间内地整型在Python解析器启动时会放入内部缓存。因此用is判断这个区间内的整型是否是同一对象时会返回True。不在这个区间内地整型会在使用时创建,所以即便值相同,但在内存中不是同一对象,因此会返回False。

⚠注意,可能编译器版本不同,内部缓存地范围可能不同。

解决这个问题的方法就是永远用==判断值是否相等,不要用is

⚠注意,在Python交互式运行环境下,用is判断值相等会受到一条警告:

SyntaxWarning: "is" with a literal. Did you mean "=="?

字符串也是同样道理,永远用==判断值相等!

GIL全局锁的坑

GIL全局锁大家可能比较陌生,它跟多线程有关。在处理多线程时,全局锁有时可能会产生疑惑。请看下面这个例子:

import math
from threading import Thread

def calc_fact(num):
	math.factorial(num)

num = 600000
t = Thread(target=calc_fact, daemon=True, args=[num])
print("About to calculate: {}!".format(num))
t.start()
print("Calculating...")
t.join()
print("Calculated")

你可能以为Calculating...会在线程启动后立即打印出来,毕竟我们将calc_fact()这个比较耗时的运算放到了线程中执行。但实际上他会在计算完成后才打印。这是因为math.factorial()背后是C语言实现,线程在执行C语言实现函数时会锁住GIL直到运行结束。

有多种方法可以绕开这个问题。

第一种方法,你可以用纯Python来实现factorial的功能。

def calc_fact(num):
	""" 纯Python实现阶乘 """
	res = 1
	while num >= 1:
		res = res * num
		num -= 1
	return res

这样做的弊端就是运行速度变慢,因为我们不再使用C语言实现的阶乘函数。

第二种方法,你可以在调用C函数前休眠一下。

def calc_fact(num):
	sleep(0.001)
	math.factorial(num)

注意:这里的休眠不会影响C函数的执行,只是让主线程有机会向下执行。

多数据返回的坑

Python允许函数返回多个数据,比如下面的函数xyz就返回了2个值:

def xyz():
	return a, b

Python的这个特性很方便,当我们使用时可以用两个变量承接返回值

a, b = xyz()

但是如果用一个变量来承接多返回值,

t = xyz()

python也是允许的,只不过t的数据类型是个元组(a, b),不是函数返回的第一个值。这里大家要格外注意。

JSON中的坑

JSON是我们日常开发中用到最多的数据类型,也是前后端传输数据最常用的数据类型。但是Python对json的处理跟javascript不同,这会让很多前端转型Python开发的同学不适应。我们看下面这个例子:

my_var = 'bla'
my_key = 'key'

params = {"language": "en", my_var: my_key}

上面的代码如果在javascript中,params的内容为:

{
	"language": "en",
	"my_var": "key"
}

而在python中,param的内容为:

{
    "language": "en",
 	"bla": "key"
}

在Python中,字典中的my_varapi_key会被当做变量来求值。

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

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

相关文章

建模杂谈系列177 APIFunc继续实践-比对研究

说明 在最终的实用上,我还是选择了Kettle。主要还是因为考虑未来公司的部署和使用上有比较全的文档,也比较有说服力。所以有时候也挺有趣的: 1 其实APIFunc要好得多,但是(刚做完原型验证)并不能取得大部分人的信任2 有一些方法对于有一定基础的人来说很方便,但是对于更…

剑指offer试题整理1

1、定义一个空的类型&#xff0c;里面没有任何成员变量和成员函数。对该类型求sizeof&#xff0c;得到的结果是什么&#xff1f; 答案&#xff1a;1. 为什么不是0? 空类型的示例中不包含任何信息&#xff0c;本来求siezof应该是0&#xff0c;但是当我们声明改类型的实列是时…

Zookeeper的数据模型和节点类型

数据模型&#xff1a; 树形结构 zk维护的数据主要有&#xff1a;客户端的会话&#xff08;session&#xff09;状态及数据节点&#xff08;dataNode&#xff09;信息。 zk在内存中构造了个DataTree的数据结构&#xff0c;维护着path到dataNode的映射以及dataNode间的树状层级关…

asp.net+sqlserver团购网站c#

数据需求分析 该网站的主要功能主要体现在对各种信息的添加、修改、删除和查询的操作上&#xff0c;包括会员信息、公司管理信息、订单信息、产品信息、团购管理信息等&#xff0c;各部分的信息之间又有着内在联系&#xff0c;因此总结出如下需求&#xff1a; &#xff08;1&am…

使去中心化媒体网络相关联的NFT元数据标准

1. 概述 (社交)媒体网络的力量日益强大。我们需要分散这种力量&#xff0c;使网络更加透明。 由于网络效应&#xff0c;新媒体网络和能够与现有网络竞争的去中心化替代方案很难吸引广大公众。 我们建议&#xff0c;与其创建新的协议&#xff0c;将每个平台的内容隔离起来&…

录屏怎么录,这2个方法不容错过!

​我们都知道在电脑使用频率越来越高的现在&#xff0c;无论是生活中还是工作中&#xff0c;有时可能会因为一些需要&#xff0c;使用到录屏的功能。最近&#xff0c;有不少的小伙伴前来询问小编&#xff0c;录屏怎么录&#xff1f;其实答案很简单&#xff0c;接下来小编分享的…

手机号码认证什么价格?手机号码认证怎样申请?

手机号码认证基于通话场景(呼入&#xff0c;呼出)的指定号码&#xff0c;来电展示企业号码专门名称&#xff0c;可提高电话号码辨识度&#xff0c;防止错误标记&#xff0c;提升品牌曝光度、接听率&#xff0c;低成本提升目标顾客接听率。 手机号码认证如何收费呢&#xff1f;…

【附源码】Python计算机毕业设计图书销售网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

数据结构和算法 IV

数据结构和算法 IV 面试题 冒泡排序 排序算法 原理机制: 相邻元素两两比较,大的/小的往后排,一轮比较结束,最大值出现在最大下标处.会比较多轮 代码实现 public static void main(String[] args) {int[] ary {23,12,7,0,67,9,11};for (int i0;i<ary.length-1;i){ //i…

MySQL高频面试题

1. drop&#xff0c;delete和truncate删除数据的区别&#xff1f; delete 语句执行删除是每次从表中删除一行&#xff0c;并且同时将改行的删除操作作为事务记录在日志中保存以便进行回滚。 truncate 则是一次从表中删除所有的数据并不把单独的删除操作记录计入日志&#xff0c…

详述分布式事务Seata TCC空回滚/幂等/悬挂问题、解决方案(seata1.5.1如何解决?)

文章目录一、前言二、问题介绍、seata1.5.1版本之前的解决方案1、空回滚出现原因解决措施事务控制记录表try()、cancel()中获取xid、branch_id2、幂等出现原因解决措施事务控制记录表3、悬挂出现原因解决措施4、总述最终的事务控制记录表三、seata1.5.1版本起官方提供的解决措施…

[附源码]java毕业设计基于Java烟支信息管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

前端框架 网络请求 Fetch Axios

目录 一、Fetch请求的使用 1、 Fetch官网 2、基本案例 二、跨域请求解决 三、Axios的使用 1、Axios官网 2、基本使用 推荐使用Axios更方便&#xff01; 一、Fetch请求的使用 1、 Fetch官网 使用 Fetch - Web API 接口参考 | MDN 2、基本案例 二、跨域请求解决 &…

2023第二届中国能源管理碳中和国际峰会

峰会背景 应对气候变化已经成为21世纪人类社会面临的紧迫挑战&#xff0c;推进绿色发展成为全球共识。中国积极参与和引导应对气候变化国际合作&#xff0c;向世界作出“力争2030年前实现碳达峰、2060年前实现碳中和”的承诺&#xff0c;逐步完善碳达峰碳中和“1N”政策体系&a…

史上最全安装Maven教程一看就会吊炸天的教程

史上最全安装Maven教程 简单了解一下什么是Maven 1.Maven翻译为“专家“&#xff0c; ”内行”的意思&#xff0c;是著名Apache公司下基于Java开发的开源项目。 2.Maven项目对象模型&#xff08;POM&#xff09;是一个项目管理工具软件&#xff0c;可以通过简短的中央信息描述…

LeetCode第 319 场周赛题解

目录2469. 温度转换2470. 最小公倍数为 K 的子数组数目2471. 逐层排序二叉树所需的最少操作数目2472. 不重叠回文子字符串的最大数目2469. 温度转换 模拟 class Solution { public:vector<double> convertTemperature(double celsius) {return {celsius273.15,celsius*1…

前端面试中小型公司都考些什么

什么是物理像素&#xff0c;逻辑像素和像素密度&#xff0c;为什么在移动端开发时需要用到3x, 2x这种图片&#xff1f; 以 iPhone XS 为例&#xff0c;当写 CSS 代码时&#xff0c;针对于单位 px&#xff0c;其宽度为 414px & 896px&#xff0c;也就是说当赋予一个 DIV元素…

Ubuntu20.04 中已经安装 Pytorch 但 Import 报错 - 解决记录

01 问题描述 笔者使用的是 Ubuntu 20.04.3 LTS&#xff0c;在使用 PyTorch 训练模型的时候&#xff0c;torch 模块引用失败&#xff0c;报错信息是 OSError: /home/wang/.local/lib/python3.8/site-packages/torch/lib/../../nvidia/cublas/lib/libcublas.so.11: undefined s…

C++对象和类概述

11 对象和类 11.1 过程式和面向对象编程 面向过程编程&#xff1a;先考虑函数&#xff0c;然后再细化到数据 面向对象编程&#xff1a;对象&#xff08;数据函数&#xff09; 11.2 抽象和类 在计算中&#xff0c;抽象是根据与用户的接口来表示信息的关键步骤。 11.2.1 什…

QT默认自带mscv2017 2019 ,配置vs2022

试验QT版本&#xff1a;5.14.2 所需文件&#xff1a; QT安装程序--qt-opensource-windows-x86-5.14.2.exe具体地址是&#xff1a;Index of /archive/qthttps://download.qt.io/archive/qt/Microsoft 生成工具 2022 Visual Studio 2022 IDE - 适用于软件开发人员的编程工具win…