ثبت ساده پایتون – و انحراف در وابستگی ها، اعتماد، و کپی/پیست کردن کد

Summarize this content to 400 words in Persian Lang
تصویر سرصفحه (C) تای کیدزیرسکی
برو قطعه
این پست نظری است
راهاندازی گزارش پیشفرض پایتون مفید نیست. این بر خلاف رویکرد “باتری شامل” کار می کند که ما انتظار داریم.
از یک پیام گزارش مفید، می خواهم بدانم چه زمانی، چه سطحی و چه اطلاعاتی. من ممکن است آن را در کنسول بخواهم، ممکن است آن را در یک فایل بخواهم.
این باید ساده باشد – اما در پایتون هر بار مجبور می شوم به دنبال چگونگی ایجاد یک ابزار ورود به سیستم کامل با مدیریت فایل سفارشی و قالب بندی رشته باشم.
آن را باید به همین سادگی باشد logger = getLogger()، اما رفتار پیش فرض به دلایل نامعلومی ارائه یک قالب بندی کاملاً بی فایده و بدون کوتاه نویسی برای یک پیش فرض معقول است.
این یا من باید یک بسته پیپ با منشأ ناشناخته دانلود کنم، مطمئن باشم که به نام ربوده نشده است، یا انجام برخی از لایه برداری مبهم. حادثه چپ پد در سال 2016 و همچنین حمله ربودن Revival در سال 2024 به ذهن متبادر می شود که اساساً همان مشکل در یک سیستم مخزن متفاوت بود.
در واقع، هر کاربر مخزن بدون فاصله نام در برابر این آسیبپذیر است: npm نود، پیپ پایتون، AUR آرچ، اسنپ Canonical… برای نام بردن از تعداد انگشت شماری که به کاربران اجازه میدهند هر چیزی را آپلود کنند. حتی فاصله نام تضمینی برای اعتماد نیست – من با پروژههایی برخورد کردهام که نرمافزار خود را از طریق این کانالها نه از طریق نام پروژه، بلکه از طریق برخی نامهای خودسرانه توسعهدهنده توزیع میکنند، که باعث ایجاد شک در صحت بسته میشود. من در پست قبلی در مورد استفاده از همگام سازی در یک محیط کاری، روند فکر خود را در مورد چگونگی تصمیم گیری در مورد اعتماد به یک منبع ارائه دادم.
وابستگی های خارجی در مخازن تحت کنترل کاربر شیطان هستند و تنها زمانی باید در نظر گرفته شوند که راه حل یک مشکل پیچیده باشد. و به طور کلی، راهحلهای ساده باید مستقیماً در پایه کد وجود داشته باشند – در حالت ایدهآل خود نوشته شده باشند، اما گاهی اوقات مشکل فقط به فضای “به اندازه کافی دست و پا گیر” می زند تا وابستگی را هم منطقی و هم بد احساس کند.
پاسخ: یک بار آن را بنویسید، آن را در یک غول Github یا در یک مخزن «قطعات مفید» از خودتان ذخیره کنید. کپی و پیست کنید.
کپی پیست؟ اوه!
“کپی و چسباندن” کد احتمالاً زنگ خطر را برای هر کدنویس چاشنی به صدا در می آورد. “تکرار نکنید”، “از یک مدیریت بسته استفاده کنید”، “یک بار بنویسید، همه جا به روز کنید.” اینها غرایز خوبی برای داشتن هستند، اما مورد به مورد، همچنین خوب است بدانید که چه زمانی کپی پیست می شود. است ارجح است.
در این صورت لازمه این است که از وابستگی های خارجی غیر ضروری اجتناب کنید برای یک راه حل ساده برای یک نیاز ساده . در سمت چپ مانند این مینی لاگر، قطعه کد مورد نیاز است کوتاه و آسان برای درک ; در صورت نیاز، اجرای مجدد آن ضرری ندارد. همچنین مجوز مناسبی دارد (بله، ممکن است فقط یک قطعه باشد، اما توصیه میشود مطمئن شوید که آنچه کپی میکنید واقعا مجاز است. مراقب کپی کردن حبابهای تصادفی کد باشید.)
قطعه Mini Logger
من در زیر یک قطعه کد را برای یک ابزار مینی لاگر قرار می دهم که امکان یک تماس با حداقل پیکربندی را فراهم می کند:
from minilog import SimpleLogger
LOG = SimpleLogger(name=”mylog”, level=SimpleLogger.INFO)
LOG.info(“this is useful”)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
کدام چاپ برای کنسول:
2024-11-20 10:43:44,567 | INFO | mylog : this is useful
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
کد مینی لاگر
این را در یک کپی کنید minilogger.py فایل در پروژه شما تادا – نیازی به وابستگی خارجی نیست. دست نخورده باقی بماند تا ابد به همین شکل باقی بماند. بدون ربودن اسم بدون تزریق زنجیره تامین
# For completeness:
# (C) Tai Kedzierski – Provided under MIT license. Go wild.
import logging
class SimpleLogger(logging.Logger):
FORMAT_STRING = ‘%(asctime)s | %(levelname)s | %(name)s : %(message)s’
ERROR = logging.ERROR
WARN = logging.WARN
INFO = logging.INFO
DEBUG = logging.DEBUG
def __init__(self, name=”main”, fmt_string=FORMAT_STRING, level=logging.WARNING, console=True, files=None):
logging.Logger.__init__(self, name, level)
formatter_obj = logging.Formatter(fmt_string)
if files is None:
files = []
elif isinstance(files, str):
files = [files]
def _add_stream(handler:logging.Handler, **kwargs):
handler = handler(**kwargs)
handler.setLevel(level)
handler.setFormatter(formatter_obj)
self.addHandler(handler)
if console is True:
_add_stream(logging.StreamHandler, stream=sys.stdout)
for filepath in files:
_add_stream(logging.FileHandler, filename=filepath)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مجوز MIT اساساً به شما اجازه می دهد “هر کاری که می خواهید با این کار انجام دهید.” هیچ رشته ای متصل نیست.
ما آنجا هستیم. یک لاگ ساده 🪵
تصویر سرصفحه (C) تای کیدزیرسکی
برو قطعه
این پست نظری است
راهاندازی گزارش پیشفرض پایتون مفید نیست. این بر خلاف رویکرد “باتری شامل” کار می کند که ما انتظار داریم.
از یک پیام گزارش مفید، می خواهم بدانم چه زمانی، چه سطحی و چه اطلاعاتی. من ممکن است آن را در کنسول بخواهم، ممکن است آن را در یک فایل بخواهم.
این باید ساده باشد – اما در پایتون هر بار مجبور می شوم به دنبال چگونگی ایجاد یک ابزار ورود به سیستم کامل با مدیریت فایل سفارشی و قالب بندی رشته باشم.
آن را باید به همین سادگی باشد logger = getLogger()
، اما رفتار پیش فرض به دلایل نامعلومی ارائه یک قالب بندی کاملاً بی فایده و بدون کوتاه نویسی برای یک پیش فرض معقول است.
این یا من باید یک بسته پیپ با منشأ ناشناخته دانلود کنم، مطمئن باشم که به نام ربوده نشده است، یا انجام برخی از لایه برداری مبهم. حادثه چپ پد در سال 2016 و همچنین حمله ربودن Revival در سال 2024 به ذهن متبادر می شود که اساساً همان مشکل در یک سیستم مخزن متفاوت بود.
در واقع، هر کاربر مخزن بدون فاصله نام در برابر این آسیبپذیر است: npm نود، پیپ پایتون، AUR آرچ، اسنپ Canonical… برای نام بردن از تعداد انگشت شماری که به کاربران اجازه میدهند هر چیزی را آپلود کنند. حتی فاصله نام تضمینی برای اعتماد نیست – من با پروژههایی برخورد کردهام که نرمافزار خود را از طریق این کانالها نه از طریق نام پروژه، بلکه از طریق برخی نامهای خودسرانه توسعهدهنده توزیع میکنند، که باعث ایجاد شک در صحت بسته میشود. من در پست قبلی در مورد استفاده از همگام سازی در یک محیط کاری، روند فکر خود را در مورد چگونگی تصمیم گیری در مورد اعتماد به یک منبع ارائه دادم.
وابستگی های خارجی در مخازن تحت کنترل کاربر شیطان هستند و تنها زمانی باید در نظر گرفته شوند که راه حل یک مشکل پیچیده باشد. و به طور کلی، راهحلهای ساده باید مستقیماً در پایه کد وجود داشته باشند – در حالت ایدهآل خود نوشته شده باشند، اما گاهی اوقات مشکل فقط به فضای “به اندازه کافی دست و پا گیر” می زند تا وابستگی را هم منطقی و هم بد احساس کند.
پاسخ: یک بار آن را بنویسید، آن را در یک غول Github یا در یک مخزن «قطعات مفید» از خودتان ذخیره کنید. کپی و پیست کنید.
کپی پیست؟ اوه!
“کپی و چسباندن” کد احتمالاً زنگ خطر را برای هر کدنویس چاشنی به صدا در می آورد. “تکرار نکنید”، “از یک مدیریت بسته استفاده کنید”، “یک بار بنویسید، همه جا به روز کنید.” اینها غرایز خوبی برای داشتن هستند، اما مورد به مورد، همچنین خوب است بدانید که چه زمانی کپی پیست می شود. است ارجح است.
در این صورت لازمه این است که از وابستگی های خارجی غیر ضروری اجتناب کنید برای یک راه حل ساده برای یک نیاز ساده . در سمت چپ مانند این مینی لاگر، قطعه کد مورد نیاز است کوتاه و آسان برای درک ; در صورت نیاز، اجرای مجدد آن ضرری ندارد. همچنین مجوز مناسبی دارد (بله، ممکن است فقط یک قطعه باشد، اما توصیه میشود مطمئن شوید که آنچه کپی میکنید واقعا مجاز است. مراقب کپی کردن حبابهای تصادفی کد باشید.)
قطعه Mini Logger
من در زیر یک قطعه کد را برای یک ابزار مینی لاگر قرار می دهم که امکان یک تماس با حداقل پیکربندی را فراهم می کند:
from minilog import SimpleLogger
LOG = SimpleLogger(name="mylog", level=SimpleLogger.INFO)
LOG.info("this is useful")
کدام چاپ برای کنسول:
2024-11-20 10:43:44,567 | INFO | mylog : this is useful
کد مینی لاگر
این را در یک کپی کنید minilogger.py
فایل در پروژه شما تادا – نیازی به وابستگی خارجی نیست. دست نخورده باقی بماند تا ابد به همین شکل باقی بماند. بدون ربودن اسم بدون تزریق زنجیره تامین
# For completeness:
# (C) Tai Kedzierski - Provided under MIT license. Go wild.
import logging
class SimpleLogger(logging.Logger):
FORMAT_STRING = '%(asctime)s | %(levelname)s | %(name)s : %(message)s'
ERROR = logging.ERROR
WARN = logging.WARN
INFO = logging.INFO
DEBUG = logging.DEBUG
def __init__(self, name="main", fmt_string=FORMAT_STRING, level=logging.WARNING, console=True, files=None):
logging.Logger.__init__(self, name, level)
formatter_obj = logging.Formatter(fmt_string)
if files is None:
files = []
elif isinstance(files, str):
files = [files]
def _add_stream(handler:logging.Handler, **kwargs):
handler = handler(**kwargs)
handler.setLevel(level)
handler.setFormatter(formatter_obj)
self.addHandler(handler)
if console is True:
_add_stream(logging.StreamHandler, stream=sys.stdout)
for filepath in files:
_add_stream(logging.FileHandler, filename=filepath)
مجوز MIT اساساً به شما اجازه می دهد “هر کاری که می خواهید با این کار انجام دهید.” هیچ رشته ای متصل نیست.
ما آنجا هستیم. یک لاگ ساده 🪵