دیروز پستی توی یه کانال تلگرامی دیدم که اومده بود و کد زیر رو ریفکتور کرده بود.
حالا چند تا نکته برای بهتر کردنش هم از نظر پرفورمنس و هم از نظر خوانایی میگم و باهم دوباره ریفکتورش میکنیم. در آخر نسخه ریفکتور شده توسط دوستمون رو هم میذارم تا ببینید.
اول از همه بگم که کاری به پترن رجکس نداریم، و توی این پست فقط خود کد رو بهتر میکنیم.
۲. دومین چیزی که خیلی اذیتم میکرد، استفاده از str به عنوان اسم آرگومان تابع بود(دلیلش رو هم میگم)، که اونم اینجوری بهترش میکنیم:
که اگه بخوایم از type hintها هم برای خوانایی بیشتر کد استفاده کنیم، نسخه نهایی به شکل زیر در میاد:
که اون str | None اینجا داره به ما نوع داده ورودی رو میگه، که در اینجا استرینگ(یا None) هست و اون bool <- هم برای مشخص کردن نوع داده خروجی هست که اینجا boolean هست.
حالا چرا گفتم از str برای اسم آرگومان استفاده نکنیم؟
دلیل اصلیش این هست که دیگه نمیتونیم از str که یکی از تابعهای داخلی(built-in) پایتون هست استفاده کنیم و یجورایی میایم اون رو بازنویسی میکنیم.
از اینجا میتونید یه لیست از این توابع رو ببینید، که نباید از اونا به عنوان اسم متغیر استفاده کنیم.
۳. نکته بعدی این هست که اگه به خط ۱۷ عکس بالا نگاه کنیم. میبینیم که اومده و چک کرده که چیزی که به تابع داده شده None نباشه.
اینجا دوتا نکته وجود داره:
نکته اول) برای مقایسه یک چیزی با None نباید از == استفاده کنیم. چرا؟ وقتی میخوایم برابر بودن دوتا چیز رو بررسی کنیم، باید از == استفاده کنیم. مثلا 5 == 5. ولی وقتی میخوایم این رو بررسی کنیم که یک چیزی دقیقا اون چیز دیگه هست باید از is استفاده کنیم. دقیقا مثل مورد این مثال.
که اینجوری باید بنویسیمش:
if url is None:
اگه میخواید بیشتر بدونید، به اینجا مراجعه کنید.
نکته دوم) اگه به کد دقت کنید، اول اومده ریجکس رو کامپایل کرده و بعد از اون چک کرده که چیزی که به تابع داده شده None هست یا نه.
درصورتی که اگه شرط url is None درست باشه، ما اصلا نیازی به کامپایل کردن ریجکس نداریم، پس چرا به خودمون زحمت کامپایل کردنش(اینم یه نکتهای داره که جلوتر میگم) رو بدیم؟ بنابراین بهتره این رو همون اول کار چک کنیم و کد تا اینجای کار به شکل زیر در میاد:
۴. نکته چهارم که زیاد هم مهم نیست اینه که نیازی به استفاده از اون +ها برای ساخت متغیر regex نیست. وقتی به شکل زیر توی پرانتز قرارش میدیم، خود پایتون میفهمه و کل اون رو یدونه استرینگ در نظر میگیره:
۵. نکته پنجم مربوط به پرفورمنس کد هست. (این مورد توی این مثال تاثیر آنچنانی نداره ولی جاهای دیگه ممکنه داشته باشه و فقط میگم که در آینده حواستون باشه)
ما داریم هر بار که این تابع اجرا میشه، رجکس رو کامپایل میکنیم، البته اینم بگم که پایتون خودش یک سری کار پشت پرده انجام میده و با کش کردن سعی میکنه پروفورمنس رو بهتر کنه، ولی وقتی تعداد رجکسا زیاد باشه و ... دیگه این کار جوابگو نیست و کدمون رو کند میکنه. خب چیکار کنیم؟ میتونیم کامپایل کردن ریجکس رو به بیرون از تابع ببریم که فقط یک بار انجام بشه (البته حواسمون باشه که برای کار کردن این کد باید re رو هم ایمپورت کنیم):
البته باید به این نکته هم حواسمون باشه که این کار start up time یعنی زمان بالا اومدن اولیه اسکریپت رو بالاتر میبره که بعضی جاها میتونه مشکل ساز باشه. توی این مورد هم میتونیم از چیزی مثل lru_cache استفاده کنیم. همونطور که توی این ویدئو نشون داده.
۶. آخرین نکتهای که میتونم بگم هم اینه که میتونیم چند خط آخر رو به شکل زیر خلاصه کنیم:
اگه دقت کنید، توی خط آخری جای re.search رو با re.match عوض کردم. اینجا هردوی اینها کار میکنن و به چیزی که میخوایم میرسیم ولی match برای اینکه فقط از ابتدای استرینگ سعی به پیدا کردن پترن میکنه(که توی این مثال چیزی بیشتر از این هم نیاز نیست) پرفورمنس بهتری به ما میده.
البته توی خط آخر به جای
re.match(url_regex, url)
میتونیم از
url_regex.match(url)
هم استفاده کنیم که البته فرقی ندارن ولی حالت دوم میتونه کمی زیباتر باشه.
کد نهایی رو میتونید از لینک زیر بردارید و هر کاری دوست داشتید باهاش بکنید :)
https://gist.github.com/sina-e/51e0f57f6a1e526aeb3f3c887bdbce35
اینم همون کد بالاست که توسط دوستمون در این پست ریفکتور شده:
پ.ن: خوشحال میشم نظراتتون رو راجع به این پست، یا بهتر کردن این کد بخونم.
اگه به این مدل پستها علاقه دارید میتونید نوشتههای من رو از کانالم به این لینک دنبال کنید :)