کمی کاوش در ماژول this پایتون

سلام دوستان امیدوارم حالتون خوب باشه. امروز صبح بعد از اینکه سیستمم رو روشن کردم، بلافاصله یه پنجره CMD باز کردم و وارد interpreter پایتون شدم. می خواستم بدونم با نوشتن import this چه اتفاقی قراره بیوفته.

123456789101112131415>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
....

خوب، به نظر این یه شعر هست که اصول توسعه پایتون رو گوش زد می کنه. اولش فکر کردم که شاید فقط یه عبارت print گذاشته اند که این رو چاپ کنه ولی بعد تصمیم گرفتم این کد رو وارد کنم

12>>> dir(this)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'c', 'd', 'i', 's']

بعد چند چیز نظرم رو جلب کرد: s و i و d و c دیگه چی هستند!؟

12>>> this.s
"Gur Mra bs Clguba, ol Gvz Crgref\n\nOrnhgvshy vf orggre guna htyl.\nRkcyvpvg vf orggre guna vzcyvpvg.\nFvzcyr vf orggre guna pbzcyrk.\nPbzcyrk vf orggre guna pbzcyvpngrq.\nSyng vf orggre guna arfgrq.\nFcnefr vf orggre guna qrafr.\nErnqnovyvgl pbhagf.\nFcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.\nNygubhtu cenpgvpnyvgl orngf chevgl.\nReebef fubhyq arire cnff fvyragyl.\nHayrff rkcyvpvgyl fvyraprq.\nVa gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.\nGurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.\nNygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.\nAbj vf orggre guna arire.\nNygubhtu arire vf bsgra orggre guna *evtug* abj.\nVs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.\nVs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.\nAnzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"

اول فکر کردم شاید ترجمه شده شعر بالا به زبان روسی یا ایتالیایی هست ولی کمی که دقت کردم فهمیدم اصلا به زبان آدمی زاد نمیخوره. درضمن فهمیدم به جای کلمه `is` انگلیسی از `vf` استفاده شده و این کمی من رو به شک انداخت. با خودم فکر کردم شاید از همون شیوه رمزگزاری قدیمی که در اون حروف الفبا رو با چند حرف بعدش عوض می کنند استفاده کرده اند (مثلا به جای a مینویسن c بعد موقع رمزگشایی به جای c می نویسن a تا متن برگرده).

شروع کردم بقیه متغیر ها رو بگردم:

12>>> this.d
{'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 'G': 'T', 'H': 'U', 'I': 'V', 'J': 'W', 'K': 'X', 'L': 'Y', 'M': 'Z', 'N': 'A', 'O': 'B', 'P': 'C', 'Q': 'D', 'R': 'E', 'S': 'F', 'T': 'G', 'U': 'H', 'V': 'I', 'W': 'J', 'X': 'K', 'Y': 'L', 'Z': 'M', 'a': 'n', 'b': 'o', 'c': 'p', 'd': 'q', 'e': 'r', 'f': 's', 'g': 't', 'h': 'u', 'i': 'v', 'j': 'w', 'k': 'x', 'l': 'y', 'm': 'z', 'n': 'a', 'o': 'b', 'p': 'c', 'q': 'd', 'r': 'e', 's': 'f', 't': 'g', 'u': 'h', 'v': 'i', 'w': 'j', 'x': 'k', 'y': 'l', 'z': 'm'}

یه جورایی انگار حدسم درست بود، این یک dictionary هست که به ازای هر یک از حروف الفبای انگلیسی به حرف دیگه ای map میشه. با خودم فکر کردم که شاید با قرار دادن تک تک حروف متن رمزگزاری شده به جای key های dictionary بشه اون رو رمزگشایی کرد. حداقل به امتحانش می ارزید:

12import string
decoded = "".join([this.d[x] if x not in ["\n", " "] else x for x in this.s if x not in string.punctuation])

مزخرف ترین one-liner ای که تو عمرم نوشتم ولی به هر حال مهم اینه که فعلا کار می کنه. حالا اگه به مقدار decoded یه نگاهی بندازیم می بینیم که همون متن اصلی هست:

12>>> print (decoded)
this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. ....

اما یه سوال برام پیش اومد، اصلا چرا باید همچین چیزی وجود داشته باشه!؟ توسعه دهنده های پایتون که هیچ چیزی رو بی دلیل ایجاد نمی کنند!

تصمیم گرفتم برم source کد this.py رو ببینم:

123456789101112131415161718192021222324252627s = """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]))

یه سوال اساسی، اصلا چرا باید همچین کاری کنند؟ این ها رو میشه خیلی آسون تر هم انجام داد. جالب اینه که همین یه تیکه کدی که نوشته اند تقریبا تمام اصول پایتونی رو که در شعر آورده اند زیر سوال می بره!

راستی یه مقایسه جالب:

1"".join([this.d[x] if x not in ["\n", " "] else x for x in this.s if x not in string.punctuation])

بالایی کد منه، پایینی کد توسعه دهنده های پایتونه

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

بعد این، باید برم دوباره مباحث پایه ای پایتون رو مرور کنم …


خیلی ممنون که وقت گذاشتید و این پست رو خوندید. تا دفعه بعدی در پناه یگانه!

نویسنده مطلب: اشکان محمدی

منبع مطلب

به فکر سرمایه‌گذاری هستی؟

با هر سطحی از دانش در سریع‌ترین زمان با آموزش گام به گام، سرمایه گذاری را تجربه کن. همین الان میتونی با لینک زیر ثبت نام کنی و ۱۰ درصد تخفیف در کارمزد معاملاتی داشته باشی

ثبت نام و دریافت جایزه
ممکن است شما بپسندید
نظر شما درباره این مطلب

آدرس ایمیل شما منتشر نخواهد شد.