栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

鲜为人知的 Python 特性,颠覆你的认知

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

鲜为人知的 Python 特性,颠覆你的认知

Interesting python

文章目录

Interesting pythonBad key奇怪的return特殊 for执行时机差异赋值方式差异浅拷贝奇怪的function隐式连接What's wrong with boolean丢失的变量跳过一行空间移动同人不同命

 一些有趣且鲜为人知的 Python 特性

Run at Python 3.8.11

Bad key
dct = {}
dct[5] = "java"
dct[5.0] = "python"

Output:

>>> dct[5.0]
python

>>> dct[5]
python

Remark:

Python 字典通过键的值是否相等以及比较哈希值来确定两个键是否相同

具有相同值的不可变对象在 Python 中始终具有相同的哈希值

>>> 5 == 5.0
True
>>> hash(5) == hash(5.0)
True
奇怪的return
def demo():
    try:
        return "try"
    finally:
        return "finally"

Output:

>>> demo()
finally

Remark:

当在 try...finally 语句的 try 中执行 return, break 或 continue 后,finally 子句依然会执行

特殊 for
s = "wtf"
dct = {}

for i, dct[i] in enumerate(s):
	pass

Output:

>>> dct
{0: 'w', 1: 't', 2: 'f'}

Remark:

Python 语法中对 for 的定义是:

for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]

其中 exprlist 指分配目标,这意味着可迭代对象中的每一项都会执行类似 {exprlist} = {next_value} 的操作,上述代码等效于:

>>> i, dct[i] = (0, 'w')
>>> i, dct[i] = (1, 't')
>>> i, dct[i] = (2, 'f')
执行时机差异
arr = [1, 2, 3]
g = (x for x in arr if arr.count(x) > 0)
arr = [2, 4, 6]

Output:

>>> print(list(g))
[2]

Remarks:

在生成器表达式中,in 子句在声明时执行,而条件子句则是在运行时执行 赋值方式差异

# demo1
lst = [1, 2]
print(id(lst))    # 140444505190976
lst = [3, 4]
print(id(lst))    # 140445040739584

# demo2
lst2 = [1, 2]
print(id(lst2))   # 140444504561920
lst2[:] = [3, 4]
print(id(lst2))   # 140444504561920

Remarks:

在 demo1 中,lst 被绑定到新对象在 demo2 中,lst2的切片赋值为原地更新 浅拷贝

l = [''] * 3
ll = [l] * 3
print(ll)      # [['', '', ''], ['', '', ''], ['', '', '']]

ll[0][0] = 'x'
print(ll)      # [['x', '', ''], ['x', '', ''], ['x', '', '']]
奇怪的function
lst = [lambda a:a*x for x in range(4)]
res = [func(1) for func in lst]
print(res)

# [3, 3, 3, 3]

Remarks:

当在循环内部定义一个函数时,如果该函数在其主体内部使用了循环变量,则闭包函数将于循环变量绑定,而不是它的值因此,所有的函数都是使用最后分配给变量的值 (3)来进行计算的 隐式连接

>>> print('wtf''')    # wtf
>>> print("wtf""")    # wtf

>>> print("""wtf")    # raise SyntaxError
>>> print('''wtf')    # raise SyntaxError

Remarks:

Python 提供隐式的字符串连接,例:

>>> print("wtf" "python")  # wtfpython

''' 和 """ 在 Python 中是一组字符串定界符,Python 解释器在先遇到三个引号的时候会尝试再寻找三个终止引号作为定界符,若不存在则会导致 SyntaxError 异常

What’s wrong with boolean
lst = [1, 1.0, '123', True, False]

int_num = 0
bool_num = 0

for i in lst:
    if isinstance(i, int):
        int_num += 1
    elif isinstance(i, bool):
        bool_num += 1
        
print(int_num)     # 3
print(bool_num)    # 0

Remarks:

布尔是 int 的子类True 的整数值是 1,False 的整数值是 0 丢失的变量

e = 7

try:
	raise Exception()
except Exception as e:
	pass

print(e)   # NameError: name 'e' is not defined

Remarks:
当使用 as 为目标分配异常的时候,将在 except 子句的末尾清除该异常

except Exception as e:
	foo

# 会被翻译为:

except Exception as e:
	try:
		foo
	finally:
		del e
跳过一行
value = 11
valuе = 32

print(value)   # 11

Remarks:

 如果你想重现的话,最好的方法是直接复制上面的代码片段到你的文件中

一些非西方字符虽然看起来和英语字母相同,但会被解释器识别为不同的字母

>>> ord('е') # 西里尔语的 'e' (Ye)
1077

>>> ord('e') # 英文字母 'e'
101

>>> 'е' == 'e'
False
空间移动
# numpy.__version__    1.21.2

import numpy as np

def energy_send(x):
    # 初始化一个 numpy 数组
    np.array([float(x)])

def energy_receive():
    # 返回一个空的 numpy 数组
    return np.empty((), dtype=np.float).tolist()

energy_send(123.456)
print(energy_receive())     # 123.456

Remarks:

注意在 energy_send 函数中创建的 numpy 数组并没有返回,因此内存空间被释放并可以被重新分配numpy.empty() 直接返回下一段空闲内存,而不重新初始化,而这个内存节点恰好就是刚刚释放的那个(通常情况下,并不绝对) 同人不同命

a = [1, 2]
b = a
a = a + [3]
print(a)    # [1, 2, 3]
print(b)    # [1, 2]

a = [1, 2]
b = a
a += [3]
print(a)   # [1, 2, 3]
print(b)   # [1, 2, 3]

Remarks:

a += b 并不总是与 a = a + b 表现相同

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767997.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号