私信  •  关注

Bharel

Bharel 最近创建的主题
Bharel 最近回复了
3 年前
回复了 Bharel 创建的主题 » python中析构函数的用法

__del__() 您只是在实例上调用一个方法,没有任何特殊意义。

这个 方法,无论是您的方法还是默认方法,都绝对不执行任何操作。此外,它是 析构函数,而不是终结器:

当实例即将被销毁时调用。这也叫做 终结器或(不恰当地)析构函数。

Python的内存分配完全是内部的。唯一的 Python中的保证是如果 __del__;() 存在时,它将在对象从内存中删除之前被调用。在某些情况下,如果对象被复活,它甚至可能被调用两次或三次,或者在守护进程线程的情况下根本不被调用。

documentation .

3 年前
回复了 Bharel 创建的主题 » json。转储不使用自定义python对象

你可以使用 default 参数 json.dump :

def default(obj):
  if isinstance(obj, Library):
      return {"name": obj.name}
  raise TypeError(f"Can't serialize {obj!r}.")

json.dumps(data, default=default)
7 年前
回复了 Bharel 创建的主题 » python:logging.warn()添加stacktrace

我不相信一个管理者是你的解决方案。选择过滤器:

import os.path
import traceback
import logging
_LOGGING_FILE = os.path.normcase(logging.addLevelName.__code__.co_filename)
_CURRENT_FILE = os.path.normcase(__file__)
_ELIMINATE_STACK = (_CURRENT_FILE, _LOGGING_FILE)


class AddStackFilter(logging.Filter):
    def __init__(self, levels=None):
        self.levels = levels or set()

    def get_stack(self):
        # Iterator over file names
        filenames = iter(_ELIMINATE_STACK)
        filename = next(filenames, "")
        frames = traceback.walk_stack(None)

        # Walk up the frames
        for frame, lineno in frames:

            # If frame is not from file, continue on to the next file
            while os.path.normcase(frame.f_code.co_filename) != filename:
                filename = next(filenames, None)
                if filename is None:
                    break
            else:
                # It's from the given file, go up a frame
                continue

            # Finished iterating over all files
            break

        # No frames left
        else:
            return None

        info = traceback.format_stack(frame)
        info.insert(0, 'Stack (most recent call last):\n')

        # Remove last newline
        info[-1] = info[-1].rstrip()

        return "".join(info)

    def filter(self, record):
        if record.levelno in self.levels:
            sinfo = self.get_stack()
            if sinfo is not None:
                record.stack_info = sinfo

        return True

此过滤器有许多优点:

  1. 从本地文件和日志记录文件中删除堆栈帧。
  2. 留下堆栈帧,以防在通过日志记录后返回到本地文件。重要的是,如果我们希望将同一个模块用于其他内容。
  3. 您可以将它附加到任何处理程序或记录器,而不会将您绑定到streamhandler或任何其他处理程序。
  4. 您可以使用相同的筛选器或单个处理程序影响多个处理程序。
  5. 等级表示为 __init__ 变量,允许您根据需要添加更多级别。
  6. 允许您将堆栈跟踪添加到日志中,而不仅仅是打印。
  7. 很好地处理日志模块,将堆栈放在正确的位置,没有什么意外。

用途:

>>> import stackfilter
>>> import logging
>>> sfilter = stackfilter.AddStackFilter(levels={logging.WARNING})
>>> logging.basicConfig()
>>> logging.getLogger().addFilter(sfilter)
>>> def testy():
...     logging.warning("asdasd")
...
>>> testy()
WARNING:root:asdasd
Stack (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in testy