GitHub项目wtfpython学习

2019-01-19  本文已影响67人  不存在的一角

前言

前段时间看到一个GitHub项目叫wtfpython专门收录一些鲜为人知的Python特性,看起来可能比较简单,但是背后的关于Python的原理还是值得深思,而且理解之后也会对你的Python水平有所提高

这是简介

An interesting collection of surprising snippets and lesser-known Python features.

嘿嘿看不懂吧,反正我英语水平一般看的不是很懂,这里还好有大哥整了一版中文版的wtfpython-cn

于是本来打算一天看个几条,但是发现坚持了一两天,flag就倒了,好在灵机一动,觉得拿出来跟大家一起学习可能效果会好点!(可能有人看完了都...)

这里就来记录一下,粗略估计有51个,每次来学习5个,循序渐进(别说我水!)

另外该项目还提供了PDF可供下载,我也下载下来了--传送门

注:以下示例在Python3中运行可以通过

正文


Strings can be tricky sometimes/微妙的字符串 *

先来看几个例子

>>> a = "yuan_shi"
>>> id(a)  # id() 函数用于获取对象的内存地址
17240856
>>> id("yuan" + "_" + "shi")  # 这里可以发现两个id值是相同的 
17240856
>>> a = "yuanshi"
>>> b = "yuanshi"
>>> a is b
True

>>> a = "yuanshi!"
>>> b = "yuanshi!"
>>> a is b
False

>>> a, b = "yuanshi!", "yuanshi!"
>>> a is b
True
>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'
True
>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'
False

解释:

这些行为是由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变对象而不是每次都创建一个新对象. (这种行为被称作字符串的驻留[string interning])

发生驻留之后, 许多变量可能指向内存中的相同字符串对象. (从而节省内存)

在上面的代码中, 字符串是隐式驻留的. 何时发生隐式驻留则取决于具体的实现. 这里有一些方法可以用来猜测字符串是否会被驻留:

Time for some hash brownies!/是时候来点蛋糕了!

hash brownie指一种含有大麻成分的蛋糕, 所以这里是句双关
虽然我并没有看出双关在哪里...

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

输出:

>>> some_dict[5.5]
"Ruby"
>>> some_dict[5.0]
"Python"
>>> some_dict[5]
"Python"

解释:

Return return everywhere!/到处返回!

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

输出:

>>> some_func()
'from_finally'

解释:

Deep down, we're all the same./本质上,我们都一样.

class WTF:
  pass

输出:

>>> WTF() == WTF() # 两个不同的对象应该不相等
False
>>> WTF() is WTF() # 也不相同
False
>>> hash(WTF()) == hash(WTF()) # 哈希值也应该不同
True
>>> id(WTF()) == id(WTF())
True

解释:

class WTF(object):
  def __init__(self): print("I")
  def __del__(self): print("D")

输出:

>>> WTF() is WTF()
I
I
D
D
False
>>> id(WTF()) == id(WTF())
I
D
I
D
True

正如你所看到的, 对象销毁的顺序是造成所有不同之处的原因.

For what?/为什么?

some_string = "wtf"
some_dict = {}
for i, some_dict[i] in enumerate(some_string):
    pass

输出:

>>> some_dict # 创建了索引字典.
{0: 'w', 1: 't', 2: 'f'}

解释:

Python 语法 中对 for 的定义是:

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

其中 exprlist 指分配目标. 这意味着对可迭代对象中的每一项都会执行类似 {exprlist} = {next_value} 的操作.

一个有趣的例子说明了这一点:

for i in range(4):
    print(i)
    i = 10

输出:

0
1
2
3

你可曾觉得这个循环只会运行一次?

>>> i, some_dict[i] = (0, 'w')
>>> i, some_dict[i] = (1, 't')
>>> i, some_dict[i] = (2, 'f')
>>> some_dict

今日份就到这里,之后可能会单独发,也可能是跟在别的文章之后,注意品尝~

print('微信公众号搜索 "猿狮的单身日常" ,Java技术升级、虫师修炼,我们 不见不散!')
print('也可以扫下方二维码哦~')
猿狮的单身日常
上一篇 下一篇

猜你喜欢

热点阅读