将复活节彩蛋分配给变量

时间:2014-09-15 20:27:20

标签: python python-2.7

是否可以将Python复活节彩蛋this分配给变量?

理想情况下,我想要尝试在文本上尝试各种字符串方法,例如单词“the”出现的次数。

我尝试了以下内容:

import this

long_text = this

print long_text.count('the')

这会打印出Zen消息但我看到一个错误,其中使用了count方法:

...    
Namespaces are one honking great idea -- let's do more of those!
Traceback (most recent call last):
  File "count.py", line 5, in <module>
    print long_text.count('the')
AttributeError: 'module' object has no attribute 'count'

提前致谢。

4 个答案:

答案 0 :(得分:6)

this模块中的代码是故意混淆的代码,作为一个笑话,*所以字符串as-is不会直接出现在任何地方。

但是,如果您查看来源(例如print inspect.getsource(this)或查看in the source repo),您会看到最后一行是:

print "".join([d.get(c, c) for c in s])

......这意味着答案是:

text = "".join([this.d.get(c, c) for c in this.s])

当然,这依赖于未记录的,特定于实现的细节,但this模块本身没有文档化,特定于实现的细节,可以通过查看the library reference看出。


但是,如果你想要一些适用于任何具有this模块的Python实现的东西,即使它的实现方式不同(也不是单个Python实现,据我所知...),你总能做到这一点:

old_stdout = sys.stdout
sys.stdout = StringIO.StringIO()
try:
    import this
    text = sys.stdout.getvalue()
finally:
    sys.stdout = old_stdout

但请注意,import仅在首次导入时运行代码,因此如果您在同一会话中执行此操作两次,那么您将以''结束第二次时间。


另一个有趣的选择是下载PEP 20并使用您喜欢的HTML解析器解析它以提取文本。但我会把它留作e xercise给读者。


*如果您想知道,那个笑话是混淆源代码,从头开始重新实现rot13,即使它内置于stdlib中,使用嵌套循环执行,循环65到97代替字符,循环遍历range(26),原因是你必须多次阅读代码才能理解......所有这些都尽可能地违反了Zen。有关他们实施时心态的更多背景信息,请参阅Barry Warsaw's post

答案 1 :(得分:2)

仅仅因为没有其他人提到它:

from codecs import decode
from this import s

zen = decode(s, "rot13")

答案 2 :(得分:1)

您目前正在为模块long_text分配this,以获取您可以执行的文字:

>>> import this
>>> text = "".join([this.d.get(c, c) for c in this.s])
>>> print text.count('the')
5

实际源代码:

>>> this.__file__
'/usr/lib/python2.7/this.py'
>>> !cat /usr/lib/python2.7/this.py
s = """Gur Mra bs Clguba, ol Gvz Crgref

Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""

d = {}
for c in (65, 97):
    for i in range(26):
        d[chr(i+c)] = chr((i+13) % 26 + c)

print "".join([d.get(c, c) for c in s])

答案 3 :(得分:1)

我不会写它,但......到底是怎么回事。这可能是获得Zen的唯一正式记录方式 - 即使没有复活节彩蛋,它也适用于任何Python实现:

#!/usr/bin/env python

import HTMLParser
import urllib2

class ZenParser(HTMLParser.HTMLParser):
    def __init__(self, *args, **kwargs):
        HTMLParser.HTMLParser.__init__(self, *args, **kwargs)
        self.state = 'START'
    def handle_data(self, data):
        if self.state == 'CHECKING HEADER':
            if data.strip() == 'The Zen of Python':
                self.state = 'AWAITING ZEN'
            else:
                self.state = 'START'
        elif self.state == 'GATHERING ZEN':
            self.zen = data
            self.state = 'ENLIGHTENED BODDHISATVA'
    def handle_starttag(self, tag, attrs):
        if self.state == 'START' and tag == 'h3':
            self.state = 'CHECKING HEADER'
        elif self.state == 'AWAITING ZEN' and tag == 'pre':
            self.state = 'GATHERING ZEN'

def zen():
    r = urllib2.urlopen('http://legacy.python.org/dev/peps/pep-0020/')
    parser = ZenParser()
    parser.feed(r.read())
    return '\n'.join(line.lstrip() for line in parser.zen.splitlines())

print zen()

或者,如果您愿意使用第三方库,BeautifulSoup(像往常一样)会让它变得更容易:

import urllib2
import bs4

def zen():
    r = urllib2.urlopen('http://legacy.python.org/dev/peps/pep-0020/')
    soup = bs4.BeautifulSoup(r.read())
    zen = soup.find('h3', text='The Zen of Python').find_next_sibling('pre').string
    return '\n'.join(line.lstrip() for line in parser.zen.splitlines())

print zen()