在Python中,如何将公共对象传递给不同的模块文件

在Python中,如何将公共对象传递给不同的模块文件,python,Python,我有各种模块文件,并希望与每个模块共享一个公共对象(在本例中为记录器)。最好的方法是什么?我有一个解决办法,但感觉不太对劲 在伪代码中: module_1.py global logger # module_1 def pass_logger_module1(plogger): global logger logger = plogger global logger # module_2 def pass_logger_module2(plogger): glo

我有各种模块文件,并希望与每个模块共享一个公共对象(在本例中为
记录器
)。最好的方法是什么?我有一个解决办法,但感觉不太对劲

在伪代码中:

module_1.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)
module_2.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)
main_module.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)

正如评论中指出的,这不是使用
日志记录
模块的方式

但是,对于“不同模块文件的公共对象”有一个更一般的答案 与您的示例相反,意思是:

main_module.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)
module_1.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)
module_2.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)
编辑: 为了避免循环导入,可以将
记录器
存储在不同的模块中:

settings.py

# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
main_module.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)

首先,在
custom_logger.py

global logger

# module_1

def pass_logger_module1(plogger):
    global logger
    logger = plogger
global logger

# module_2

def pass_logger_module2(plogger):
    global logger
    logger = plogger
from module_1 import pass_logger_module1
from module_2 import pass_logger_module2

logger = set_logger(logfile, logformat, 'DEBUG')

pass_logger_module1(logger)
pass_logger_module2(logger)
# this is in global
logger = set_logger(logfile, logformat, 'DEBUG')
from main_module import logger
from main_module import logger
from settings import logger
import logging
import sys


class CustomFormatter(logging.Formatter):
    err_fmt  = "[*] ERROR: %(msg)s"
    dbg_fmt  = "[-] DEBUG: %(module)s: %(lineno)d: %(msg)s"
    info_fmt = "[+] %(msg)s"

    def __init__(self):
        super().__init__(fmt="%(levelno)d: %(msg)s", datefmt=None, style='%')

    def format(self, record):
        # Save the original format configured by the user
        # when the logger formatter was instantiated
        format_orig = self._style._fmt

        # Replace the original format with one customized by logging level
        if record.levelno == logging.DEBUG:
            self._style._fmt = CustomFormatter.dbg_fmt

        elif record.levelno == logging.INFO:
            self._style._fmt = CustomFormatter.info_fmt

        elif record.levelno == logging.ERROR:
            self._style._fmt = CustomFormatter.err_fmt

        # Call the original formatter class to do the grunt work
        result = logging.Formatter.format(self, record)

        # Restore the original format configured by the user
        self._style._fmt = format_orig

        return result


class CustomLogger(logging.Logger):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        formatter = CustomFormatter()
        handler = logging.StreamHandler(sys.stdout)
        handler.setFormatter(formatter)
        self.addHandler(handler)
        self.setLevel(logging.INFO)
然后,在其他模块中,导入
CustomLogger

from custom_logger import CustomLogger


logger = CustomLogger(__name__)

logger.debug("Hello, world!")

一种方法是通过第三个模块公开共享对象,如下所示:

my_logger.py

logger = set_logger(logfile, logformat, 'DEBUG')
模块_1.py

from my_logger import logger
...
模块2.py

from my_logger import logger
...

然后,您的主模块可以导入模块1和模块2,而无需了解记录器,并避免循环导入情况。

这不是您应该使用记录器的方式。日志模块具有特定的功能,可以使用所需的设置定义父日志记录器,并允许子日志记录器继承这些设置。你应该阅读文档。谢谢,我会的。然而,在更一般的情况下,共享公共对象的最佳方式是什么?最好的方式是显式地将其传递给每个需要它的函数,并/或将其保存在使用它的对象中。这给了我循环导入的情况,但正如建议的那样,我可以将共享对象放入另一个模块文件中并从那里导入…感谢这很好地工作。我有一个设置模块,但是每个模块都启动了它自己的设置实例,对于值没有变化的对象,它工作正常,但是我的记录器启动了好几次。我必须重写它,以使设置对象类对象而不是实例对象…不会,您将得到已经导入的相同模块(它将来自sys.modules)。我鼓励你自己检查一下,看看这是真的!