在类中导入模块的最佳方法?

时间:2017-03-14 10:54:08

标签: python

我有一个Python模块文件,它实际上是一个带有相关公共和私有函数的类。我想在类中和内部所有函数中使用日志记录模块。但问题是如果我只在__init__()内导入一次导入在其余的函数中不可见。我是否必须在类的每个函数中导​​入它?

在类中导入此类模块的最佳方法是什么。我在stackoveflow论坛中搜索了关于相同的各种讨论,但没有具体的东西。

以下是我的示例课程:

class Add:
    def __init__(self,no1,no2):
        import logging
        logging.basicConfig(filename='example2.log',level=logging.INFO)
        logging.info("The two parameters passed are {0} and {1}:".format(no1,no2))
        self.num1 = no1
        self.num2 = no2

    def add(self):
        logging.debug("Inside add function of Add class")
        logging.info("Adding the two class properties")
        self.result = self.num1 + self.num2
        logging.debug("Exiting add function")

    def display(self):
        logging.debug("Inside display class")
        return self.result

if __name__ == '__main__':
    a = Add(10,11)
    a.add()
    print (a.display)

当我尝试运行时:

C:\Users\bhatsubh\Desktop\Everything\Codes\Python>python Test.py
Traceback (most recent call last):
  File "Test.py", line 21, in <module>
    a.add()
  File "Test.py", line 10, in add
    logging.debug("Inside add function of Add class")
NameError: name 'logging' is not defined

2 个答案:

答案 0 :(得分:0)

您可以简单地将其分配给变量:

class Foo:
    def __init__(self):
        import logging
        self._logging = logging

但我建议只在模块级别导入它。将模块附加到类的成员变量感觉非常错误。

另一种选择是仅存储您要使用的记录器:

class Foo:
    def __init__(self):
        import logging
        self.logger = logging.getLogger(__name__ + "." + self.__class__.__name__)

PS:这可能不是为课程创建记录器的正确方法,我从来没有这样做,只是在这里进行了即兴创作。阅读如何操作。

答案 1 :(得分:0)

所以这里的问题是范围之一。在函数内部导入时(偶然,见下文),导入的范围仅限于该函数内部:

def foo():
    import a
    a.something()

def bar():
    a.something() # won't work

相反,你应该尝试始终在顶部导入:

import a

def foo():
    a.something()

def bar():
    a.something()

您还应该提供一种良好,可维护的订购进口方式。

现在,你可以在一个函数内执行它,你可以做一些时髦的东西,比如动态导入和反射以及各种很酷的东西,但99.9%的时候你不需要因此,添加这种复杂性会降低可维护性(这应该是您的目标)。

您希望这样做的好时机是解决复杂的循环导入,或者如果您正在尝试使用动态加载来执行某些功能,那么性能就是如此。但是当谈到优化性能时,你应该首先构建它,然后看看它在哪里。