博客
关于我
Python 中 3 个不可思议的返回功能
阅读量:797 次
发布时间:2023-03-06

本文共 2284 字,大约阅读时间需要 7 分钟。

Python 的三大神奇之处

1. 神奇的字典键

在 Python 中,字典的键是根据它们的哈希值进行匹配的。然而,值得注意的是,5 和 5.0 在 Python 中被视为同一个键。这是因为它们具有相同的哈希值。因此,当你执行以下代码时:

some_dict = {}some_dict[5.5] = "Ruby"some_dict[5.0] = "JavaScript"some_dict[5] = "Python"

最终,some_dict[5] 的值会是 "Python",而不是 "JavaScript"。这是因为 Python 在处理这些键时,会将它们作为同一个键处理。

为什么会出现这样的情况?

这是因为 Python 会将浮点数和整数当作相同的键。具体来说,当你执行 some_dict[5] = "Python" 时,5 会被视为与 5.0 相同的键。因此,原有的 "JavaScript" 会被覆盖。

此外,需要注意的是,尽管 5 和 5.0 在 Python 中被视为相同的键,但它们的值是不同的。如果你想区分它们,应该使用不同的键类型。

哈希值的重要性

哈希值是一种用于快速查找数据的机制。Python 会根据对象的哈希值来决定如何存储和检索字典中的值。如果两个键具有相同的哈希值,它们会被视为相同的键。

需要注意的是,尽管哈希值相同,两个键的值可能不同(即哈希冲突)。然而,在 Python 中,5 和 5.0 会被视为相同的键,因为它们具有相同的哈希值。

2. 异常处理中的 return

在 Python 中,try-finally 结构中的 return 语句有一些特殊之处。具体来说,如果 try 块中有 return 语句,finally 块中的 return 语句仍然会执行。

例如:

def some_func():    try:        return 'from_try'    finally:        return 'from_finally'

当你调用 some_func() 时,输出会是 'from_finally'。这是因为 Python 会先执行 try 块中的 return 语句,然后再执行 finally 块中的 return 语句。

为什么会这样?

这是因为 Python 的异常处理机制是这样的。无论 try 块中是否有 return 语句,finally 块中的代码都会执行。因此,try 块中的 return 语句会被 finally 块中的 return 语句覆盖。

return 语句的执行顺序

函数的返回值是由最后执行的 return 语句决定的。在 try-finally 结构中,finally 块中的 return 语句是最后执行的语句。因此,函数的返回值是由 finally 块中的 return 语句决定的。

这也是为什么在 try-finally 结构中,try 块中的 return 语句会被 finally 块中的 return 语句覆盖的原因。

3. 相同对象的判断

在 Python 中,对象的比较是基于它们的身份(id)和哈希值的。一般来说,两个不同的对象不会相等。但是,有时候它们可能具有相同的哈希值。

例如:

class WTF:    passwtf1 = WTF()wtf2 = WTF()print(wtf1 == wtf2)  # 输出: Falseprint(wtf1 is wtf2)  # 输出: Falseprint(hash(wtf1) == hash(wtf2))  # 输出: Trueprint(id(wtf1) == id(wtf2))  # 输出: True

为什么 id 相同?

这是因为 id 函数会返回对象的内存地址。在 CPython 中,id 函数会返回对象的内存地址。因此,当两个对象的内存地址相同时,它们的 id 值也会相同。

为什么 is 运算符返回 False?

is 运算符用于比较两个对象是否是同一个对象。例如:

wtf1 = WTF()wtf2 = WTF()print(wtf1 is wtf2)  # 输出: False

这是因为 wtf1 和 wtf2 是两个不同的对象。虽然它们的 id 值相同,但它们是两个不同的对象。

为什么 hash 值相同?

哈希值是根据对象的 hash 方法返回的值。在 Python 中,两个不同的对象可能具有相同的哈希值(哈希冲突)。这可能会导致哈希表(如字典)中出现冲突。

对象的销毁顺序

在上面的代码中,你可以看到,当对象被销毁时,它们的 del 方法会被调用。例如:

class WTF(object):    def __init__(self):        print("I")    def __del__(self):        print("D")wtf1 = WTF()wtf2 = WTF()print(wtf1 is wtf2)  # 输出: Falseprint(id(wtf1) == id(wtf2))  # 输出: True

在上面的例子中,wtf1 和 wtf2 是两个不同的对象。它们的 id 值相同,但它们是两个不同的对象。这是因为 id 函数在生成这两个对象时,返回了相同的内存地址。

然而,当其中一个对象被销毁时,它的 id 会被重新分配给另一个对象。这就是为什么在销毁顺序不同的情况下,对象的 id 值可能会不同。

转载地址:http://xyofk.baihongyu.com/

你可能感兴趣的文章
pytest测试框架:最强大的自动化测试工具,让测试变得轻松有趣
查看>>
Pytest自动化测试指定执行测试用例
查看>>
python - 如何并行化python numpy中的总和计算?
查看>>
Python - 如何解析 xml 响应并将元素值存储在变量中?
查看>>
Python - 安装了扩展的远程 Webdriver
查看>>
python - 将字符串中的日期与今天的日期进行比较
查看>>
python - 数据描述符(class 内置 get/set/delete方法 )
查看>>
Python - 根据值绘制彩色网格
查看>>
Python - 正则表达式在括号之间获取数字
查看>>
python binascii.Error: Incorrect padding
查看>>
Python bool() 函数能否为无效参数引发异常?
查看>>
Python C 程序子进程在“for line in iter“处挂起
查看>>
Python Celery:自动化测试平台定时任务必备的三方库
查看>>
python check_output 失败,退出状态为 1,但 Popen 适用于相同的命令
查看>>
Python CONNECT 4 CHECK WIN函数
查看>>
python ctypes库中动态链接库加载方式
查看>>
python cv2 图像( np array )转 HObject
查看>>
python cv2截取不规则区域图片
查看>>
python CV2裁剪图片并保存
查看>>
python cv2读取rtsp实时码流按时生成连续视频文件
查看>>