Python社区  »  Python

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

Python爱好者社区 • 1 周前 • 34 次点击  

小编最近逛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吧!


感谢阅读

推荐阅读:

1真实的上海IT圈:张江男vs漕河泾男

2:真实的北京IT圈:后厂村姑 vs 后厂村花?

3:为什么你的提问没人解答?

4:Python爱好者社区历史文章合集



重磅!Python交流已成立


公众号运营至今,离不开小伙伴们的支持。
为了给小伙伴们提供一个互相交流的技术平台,特地开通了Python交流群。
群里有不少技术大神,不时会分享一些技术要点,更有一些资源收藏爱好者不时分享一些优质的学习资料。(免费,不卖课!)
需要进群的朋友,可长按扫描下方二维码。


▲长按扫码

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/107946
 
34 次点击  
分享到微博