【Python】有趣且鲜为人知的 Python 特性,火了!

机器学习初学者

共 4444字,需浏览 9分钟

 ·

2021-03-04 11:06

小编最近逛Github发现了一个给力的Python项目,绝对能让你傻眼!可以通过这个项目测试你对Python的熟悉程度!


这个项目叫做 “What the f*ck Python! 🐍",主要讲一些有趣且鲜为人知的 Python 特性。

项目地址为:https://github.com/leisurelicht/wtfpython-cn


来体会一些难以理解和反人类直觉的Python特性吧!


>>> a = 256
>>> b = 256
>>> a is b
True

>>> a = 257
>>> b = 257
>>> a is b
False

>>> a = 257; b = 257
>>> a is b
True


是我眼花了么?我动手敲了下,确实是这样...


这是为啥呢?


因为 256 是一个已经存在的对象, 而 257 不是。

大家可以想到256是2的8次方。

当Python开启后,-5~256数字已经分配好对象了,主要考虑这些数字经常使用。

引用自 https://docs.python.org/3/c-api/long.html

可以再看看这个案例:

>>> id(256)
10922528
>>> a = 256
>>> b = 256
>>> id(a)
10922528
>>> id(b)
10922528
>>> id(257)
140084850247312
>>> x = 257
>>> y = 257
>>> id(x)
140084850247440
>>> id(y)
140084850247344


大家都知道,在Python中通过id( )可以确定两个变量存储的内容是否是同一个,通过以上的代码结果说明创建了多个257对象。

你以为到这就结束了么?并没有

再来继续看这个:

>>> a, b = 257257
>>> id(a)
140640774013296
>>> id(b)
140640774013296
>>> a = 257
>>> b = 257
>>> id(a)
140640774013392
>>> id(b)
140640774013488


这又触及我的知识盲区了!这是为啥啊?

揭晓答案吧!当a和b在同一行被赋值为相同内容时,Python解释器会创建一个变量,然后引用它(不新创建了!)。注意这是在交互式的环境中,属于交互式环境的编译器优化。


我们看下一个有趣的特性:


# 我们先初始化一个变量row
row = [""]*3 #row i['', '', '']
# 并创建一个变量board
board = [row]*3


>>> board
[[''''''], [''''''], ['''''']]
>>> board[0]
['''''']
>>> board[0][0]
''
>>> board[0][0] = "X"
>>> board
[['X'''''], ['X'''''], ['X''''']]


???这是为啥呢,我明明只给一个位置赋值了“X”啊!

大家应该想到了原因!

当我们初始化时:



然后我们使用乘法初始化board变量时,是这样的:



也就是说,这三行都引用了row的内存空间。

所以改变其中一个位置的值,也就改变了3个位置的值!

为了避免引用相同位置内容,可以采用以下方法:


>>> board = [['']*3 for _ in range(3)]
>>> board[0][0] = "X"
>>> board
[['X'''''], [''''''], ['''''']]


接着看下个案例吧:


神奇的三引号!


>>> print('wtfpython''')
wtfpython
>>> print("wtfpython""")
wtfpython
>>> # 下面的语句会抛出 `SyntaxError` 异常
>>> # print('''wtfpython')
>>> # print("""wtfpython")


补充个说明,Python的隐式字符串连接:


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


思考一下再看答案!


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


我们再来看下一个例子:


# 一个简单的例子, 统计下面可迭代对象中的布尔型值的个数和整型值的个数
mixed_list = [False1.0"some_string"3True, [], False]
integers_found_so_far = 0
booleans_found_so_far = 0

for item in mixed_list:
    if isinstance(item, int):
        integers_found_so_far += 1
    elif isinstance(item, bool):
        booleans_found_so_far += 1


返回的结果是:


>>> integers_found_so_far
4
>>> booleans_found_so_far
0


???我的bool值都到哪去了?



其实,布尔值是int的子类,看下面这个就懂了:


>>> isinstance(True, int)
True
>>> isinstance(False, int)
True


如果还没理解,可以继续往下看:


another_dict = {}
another_dict[True] = "JavaScript"
another_dict[1] = "Ruby"
another_dict[1.0] = "Python"


>>> another_dict[True]
"Python"


True 的整数值是 1, 而 False 的整数值是 0。


>>> True == 1 == 1.0 and False == 0 == 0.0
True


>>> some_bool = True
>>> "wtf"*some_bool
'wtf'
>>> some_bool = False
>>> "wtf"*some_bool
''


还有很多Python神奇的特性,大家自己看这个项目吧~


如果觉得项目作者写的不错,给他点亮star吧!

往期精彩回顾





本站qq群704220115,加入微信群请扫码:

浏览 44
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报