Форум сайта python.su
Не соображу, как сделать.
Хочу к стандартному логгеру добавить уровень логгирования TRACE=5 и соответствующий метод trace().
Вроде бы должно быть примерно так:
class MyLogger(logging.Logger): TRACE = 5 def trace(self, msg, *args, **kwargs): if self.getEffectiveLevel < logging.TRACE: return self.debug(msg, *args, **kwargs) logging.setLoggerClass(MyLogger) logging.basicConfig(level=MyLogger.TRACE) log = logging.getLogger(__name__)
Офлайн
В таком виде работает:
class MyLogger(logging.Logger): logging.TRACE = 5 def trace(self, msg, *args, **kwargs): if self.getEffectiveLevel() <= logging.TRACE: return self.debug(msg, *args, **kwargs) logging.setLoggerClass(MyLogger) log = logging.getLogger(__name__) log.setLevel(logging.TRACE) log.trace('* trace') log.debug('* debug') log.info('* info')
Офлайн
Вот такой вариант вроде бы правильный:
class MyLogger(logging.Logger): logging.TRACE = 5 logging.addLevelName(logging.TRACE, 'TRACE') def _trace(logger, message, *args, **kwargs): if logger.isEnabledFor(logging.TRACE): logger._log(logging.TRACE, message, args, **kwargs) logging.Logger.trace = _trace logging.setLoggerClass(MyLogger) logging.basicConfig(format='%(asctime)s [%(name)s:%(process)d] |%(levelname)s| %(message)s', datefmt='%Y-%m-%d %H:%M:%S') log = logging.getLogger(__name__) log.setLevel(logging.TRACE) log.trace('* trace') log.debug('* debug') log.info('* info')
Офлайн
alibekА где ты его взял? Написан бред явный.
Вот такой вариант вроде бы правильный
Онлайн
Тем не менее он работает именно так, как мне требуется; поведение полностью идентично остальным уровням логгирования.
Что именно там бредового?
Офлайн
alibekНу вот ты вот это написал и говоришь “это правильный код”. Вообще-то, в классе никакие операторы нельзя выполнять. Максимум там можно имена какие-то присваивать (перепривязывать имена). Такую бредятину могла выдать только ChatGPT, поэтому у меня и закрались сомнения, а не через неё ли ты пишешь код и вещаешь потом здесь, что он правильный. Она же ахинею пишет и утверждает, что это всё правильно, что она пишет там.
Вот такой вариант вроде бы правильный:class MyLogger(logging.Logger): logging.TRACE = 5 logging.addLevelName(logging.TRACE, 'TRACE') def _trace(logger, message, *args, **kwargs): if logger.isEnabledFor(logging.TRACE): logger._log(logging.TRACE, message, args, **kwargs) logging.Logger.trace = _trace logging.setLoggerClass(MyLogger) logging.basicConfig(format='%(asctime)s [%(name)s:%(process)d] |%(levelname)s| %(message)s', datefmt='%Y-%m-%d %H:%M:%S') log = logging.getLogger(__name__) log.setLevel(logging.TRACE) log.trace('* trace') log.debug('* debug') log.info('* info')
Онлайн
py.user.nextСинтаксически — можно. Если что-то на самом деле нельзя, то об этом скажет Python.
Вообще-то, в классе никакие операторы нельзя выполнять.
Отредактировано alibek (Авг. 17, 2023 12:08:18)
Офлайн
Не, это не я так считаю. Тут ещё один пацан считает, что надо там по-нормальному всё делать. Но тот пацан, какой-то вот лох, написал как раз этот logging, которым ты пользуешься. Ну иди поспорь ещё с ним. Ты же умный, а он дурак.
python.org. logging
logging.setLoggerClass(klass)Вот для тупорылых написано: сделайте в __init__'е это всё, вызовите родительский __init__ ещё, чтобы ничего не сломалось.
Tells the logging system to use the class klass when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__(). This function is typically called before any loggers are instantiated by applications which need to use custom logger behavior. After this call, as at any other time, do not instantiate loggers directly using the subclass: continue to use the logging.getLogger() API to get your loggers.
alibekТебе же говорят, ты просто дурак.
Если про “бред” и “нельзя” было написано только из-за ваших привычек и вашего представления о том, как должен быть написан код, то так и пишите — “я считаю неправильным выполнять операторы в основном теле класса, перенесите их в конструктор или метод инициализации”.
alibekА кто ты такой, чтобы видеть? У тебя мозгов нет. Тебе же говорят: сначала нужно прочитать всё, а потом делать. В итоге ты делаешь какую-то хуйню, потом ещё это с умным видом постишь везде, а потом ещё споришь со всеми, когда тебе в лицо говорят, что ты хуйню сделал. Потом тебе говорят, что ты говнодел и всё. А потом ты обижаешься на всех. Так что сиди обиженный и дальше. В этом виноват только ты сам.
Тем более, что в данном случае никаких проблем не вижу
Онлайн
Мда.
Ладно, попробую еще раз.
Ранее вы написали про мой код, что это “бред” и так “нельзя”.
А когда я попросил пояснить, заявили что “в классе никакие операторы нельзя выполнять”.
Разумеется, это заявление ошибочно.
Во-первых, использование оператора присвоения в теле класса — это не просто нормально, это распространенный сценарий.
Если моих слов недостаточно, можете посмотреть исходный код стандартных классов питона, например logger: https://github.com/python/cpython/blob/main/Lib/logging/__init__.py
Во втором же классе PercentStyle идут строки:
default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)'
Офлайн
alibekЭто присваивание констант на уровне класса. Эти операции ничего не меняют нигде. Так же, как и регулярное выражение, которое там компилируется дальше, ни на что не влияет и даёт константный объект.
Во втором же классе PercentStyle идут строки:default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)'
>>> import re >>> >>> pat = re.compile('.') >>> >>> pat re.compile('.') >>> type(pat) <class '_sre.SRE_Pattern'> >>> dir(pat) ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'findall', 'finditer', 'flags', 'fullmatch', 'groupindex', 'groups', 'match', 'pattern', 'scanner', 'search', 'split', 'sub', 'subn'] >>> pat.x = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: '_sre.SRE_Pattern' object has no attribute 'x' >>> pat.match = lambda: 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: '_sre.SRE_Pattern' object attribute 'match' is read-only >>>
alibekДаже несмотря на то, что в logging.TRACE в твоём чудесном коде, причём “правильном” (как ты выразился изначально и упёрся потом, когда тебя носом в это ткнули, что это неправильно вообще-то), ей присваивается константа, это тоже неправильно. Это вообще твой уровень показывает, что ты находишься где-то на непонимании даже того, чем вредны глобальные переменные. То есть это воообще новичковый пробел в знаниях. Почему это нельзя делать - по той же самой причине, почему и глобальные переменные нельзя делать. У них похожие механизмы генерации бардака и неразберихи.
Таким образом два случая использования оператора присвоения в моем коде (logging.TRACE = 5, logging.Logger.trace = _trace) и декларация функции (def _trace) это не “бред”, а вполне рабочая и используемая конструкция.
alibekТы знаешь, это как бы не аргумент. Иметь дело можно только с интерфейсом модуля, это знает любой дурак, а ты не знаешь, потому что ты глупее вот этого вот любого дурака. Ну поздравляю тебя!
Но если посмотреть код этого метода (https://github.com/python/cpython/blob/main/Lib/logging/__init__.py#L156), то это не метод класса, а функция в теле модуля
Анекдот №-311115024
Поручик Ржевский просыпается после пьянки и видит,
что денщик Петруха чистит его обблёванный китель.
Ну поручику, естессно, невздобняк стало - офицер,
и так обблевался. Он и говорит денщику:
- Знаешь, Петруха, вчера на балу встретил своего друга
генерала, а он скотина так нажрался и обблевал мне
весь китель.
- Да, Ваше Благородие, он вам не только китель обблевал,
но ещё и в штаны насрал.
alibekХорошо, что ты это написал, потому что это всё про тебя написано
Думаю, что на самом деле причина подобных агрессивных заявлений в другом.
alibekТолько у тебя не социальная функция, это ты немножко подменил, а это по-другому устроено. Ты чему-то там подучился, совсем немного (может, тебя турнули откуда-то, где ты там сидел, присосавшись плотненько, поэтому-то и не развивался вообще, а зачем? на покушать и так дают), и тут ты решил делать так. А вот теперь я сделаю такой финт ушами: создам себе рекламу и буду её везде постить, какой я замечательный, какой я нужный и так далее. Может, кто-то не разберётся и возьмёт меня к себе, чтобы я снова мог сидеть и нихера не делать, как обычно, по привычке. А как же их найти, вот этих дурачков? Хм… да надо зайти просто на какой-нибудь форум, куда ходят всякие шлюшки из этих hh, avito и прочих шараг и ищут, рыщут в поисках специалистов, которых так не хватает вокруг, и там начать продвигать себя, авось клюнут. А раз так, то они же не разберутся, что я полный дебил и ничего не знаю, а потому и поведутся на меня, читая мои письмена и коды великие, которые я будут обильно приправлять своими мнениями тупорылыми и спорами разного рода желательно с кем-нибудь покрупнее (замахнулся бы на создателя модуля logging, но слишком палевно это, могут просто понять, что я дурак обычный, надо осторожнее действовать - назалупаться, например, на какого-нибудь местного авторитета, гуру или кого-нибудь подобного). Сказано - сделано. Главное, надо уверенно себя вести, утверждать, что я мастер этого дела, говорить, что мой код везде всегда правильный, даже если это полная ахинея. Ну вот такая вот стратегия, мне вот кажется она хорошей, я же её САМ придумал, я же умнее всех и никто об этом не догадается даже, все же дураки, а я один умный, а сомневаться в собственной гениальности - это себя не уважать, это моё и-зо-бре-те-ни-е! никто кроме меня никогда так не делал и не приходил на форумы.
Очевидно, что интернет играет в вашей жизни социальную функцию.
Вероятно, вы рассматриваете данный форум в каком-то смысле как свою территорию.
А там, где есть территория и коллектив, есть и иерархические игры.
Возможно вы думаете, что любая ответная реакция новичка на ваш совет, отличная от благодарности и признательности, является покушением на ваше место в иерархии, на которое, разумеется, нужно дать мгновенный и жесткий отпор.
Поэтому ваши агрессивные заявления про “бред” на самом деле не про корректность (или некорректность) программного кода, а автоматическая реакция с попыткой заранее обесценить любые аргументы соперника, объявив их несущественными и/или ложными.
Реакция поспешная и ошибочная, но признать ошибку вы уже не можете, ведь это публичное место и вдруг другие участники форума подумают, что Акела промахнулся.
Отсюда и пустая болтовня и софистика, чтобы отвлечь от своей ошибки и не допустить падения авторитета.
alibekКакого авторитета? Я тут сижу больше десяти лет. Ты думаешь, сюда никто не приходил и не выяснял про меня ничего? Что я знаю и чего я не знаю? Да тут всё выяснено и перевыяснено десять раз уже. Меня эти вещи вообще не волнуют. Я всему учусь не для того, чтобы кому-то там нравиться, особенно всяким шлюшкам со всяких рабочих платформ, ценность которых не больше чем у сопли под носом, потому что они ничего не умеют делать в жизни и просто сидят и стараются на айтишниках подзаработать себе на жизнь их беспонтовую, на что - на трусы, на булочки. Это все их интересы, они ничем не занимаются, они ничего не развивают, они ничего не изучают. Им это не надо.
Отсюда и пустая болтовня и софистика, чтобы отвлечь от своей ошибки и не допустить падения авторитета.
Отредактировано py.user.next (Авг. 17, 2023 22:39:01)
Онлайн