【问题标题】:Why do I have to import python packages into each class method?为什么我必须将 python 包导入到每个类方法中?
【发布时间】:2020-04-06 01:30:51
【问题描述】:

我有一个类对象,对象中的一些方法需要 python 包(例如 numpy)。如果我在创建对象之前在主脚本中导入包,则对象中的方法无法识别包已导入。为了解决这个问题,我必须在方法本身中导入所有必要的包,这似乎效率低下,因为该方法被多次调用。有没有其他方法可以确保这些方法可以找到以前导入的包?

这是类对象:

class CCState:
    def __init__(self, stateVector = None):
        self.fill_vol = 0
        self.headspace_vol = 0
        self.temperature = 0
        self.pressure = 0
        self.flowin = 0
        self.flowout = 0
        self.product = 0
        self.viacell_attach = 0
        self.viacell_suspend = 0
        self.deadcell_attach = 0
        self.deadcell_suspend = 0
        self.headspace_temperature = 0
        self.hdgas_o2 = 0
        self.hdgas_n2 = 0
        self.hdgas_co2 = 0
        self.hdgas_ar = 0
        self.dsg_o2 = 0
        self.dsg_n2 = 0
        self.dsg_co2 = 0
        self.dsg_ar = 0
        self.glucose = 0
        self.glutamine = 0
        self.glutamate = 0
        self.lacticacid = 0
        self.lactate = 0
        self.ammonia = 0
        self.ammonium = 0
        self.bicarbonate = 0
        self.carbonate = 0
        self.cation = 0
        self.proton =  0
        self.anion = 0
        self.hepes = 0
        self.hepesion = 0
        self.hydroxyl = 0
        self.microcarrier = 0
        self.antifoam = 0
        self.sulfite = 0
        self.rDTT = 0
        self.oDTT = 0
        self.promoter = 0
        self.sulfiteacid = 0
        self.sulfate = 0
        self.bisulfite = 0
        self.fudgeacid = 0
        self.fudgeanion = 0
        self.fudgebase = 0
        self.fudgecation = 0
        self.viacell_attach2 = 0
        self.serum = 0
        self.tris = 0
        self.triscation = 0
        self.aceticacid =0
        self.acetate = 0
        self.h3po4 = 0
        self.dihydrogenphosphate = 0
        self.hydrogenphosphate = 0
        self.phosphate = 0
        self.names = [i for i in self.__dict__.keys() if i[:1] != '_']

        # If a vector has been passed, assign all parameters to values in the vector
        if stateVector is not None:
            for iName in range(0,len(self.names)):
                setattr(self,self.names[iName],stateVector[iName])
    def pH(self):
        """Return pH"""
        #from math import log
        return -log(max(10E-14, self.proton)*0.001,10);

如果我运行此代码,我会收到错误“NameError: name 'log' is not defined”

from helper_functions import *
from scipy.integrate import ode
from math import exp, log
from scipy import interpolate
import numpy as np
from numpy.linalg import norm
from CCState import *
import chemical_reaction_model
import time

temp = CCState()
print(temp.pH())

【问题讨论】:

  • 你能发布你的代码吗?在文件开头导入python包应该允许在每个方法中使用包
  • 实际上你应该在方法或函数中进行导入。但是如果你的类不在你的主脚本中,你必须在你的类的模块中导入 numpy,而不是在主脚本中(当然,如果你在主脚本中需要它,你当然也必须在那里导入 numpy)。跨度>
  • @brunodesthuilliers 我试图不导入该方法,但我不确定为什么它找不到我导入的包。当你说导入到类的模块时,你是否建议在 _init_ 中添加导入?
  • 不,在定义类的模块顶部。我建议您完成完整的官方 Python 教程(也可以查看 pep8)。

标签: python python-import python-packaging


【解决方案1】:

Python 的导入与 C 或 PHP 风格的 include 完全不同。 Python 没有全局命名空间,每个模块(或脚本)都是它自己的命名空间,因此每个模块都必须明确导入它所依赖的库。

在您的情况下,解决方案很简单:在 CCState.py 模块中移动(或复制)所需的导入。

另外,不要使用通配符导入 (from xxx import *) - 这肯定是维护噩梦的秘诀。始终使用显式导入,即使 lib 的文档告诉您可以使用通配符。

最后,模块名称应该是 all_lower,而不是 CamelCase。

【讨论】:

    【解决方案2】:

    首先,请向我们展示您的脚本内容。

    如果您在主脚本中导入库,它应该在整个文件中都可用。使用import lib 导入第二个名为lib.py 的python 脚本与将该文件中的内容复制到主脚本中不同。但是,您在 lib.py 中实现的库可以由您的主脚本的方法使用。

    主脚本

    from lib import *
    
    x = [1, 2, 3]
    x = numpy.array(x)
    
    print(x)
    

    lib.py

    import numpy
    

    【讨论】:

    • 我添加了我的代码。根据您的描述,我的代码似乎应该可以工作,所以我不确定我做错了什么
    • 请不要建议使用通配符导入。
    • 我不建议这样做,我只是想展示它是如何工作的,因为您总是可以拥有一个导入其他模块的模块。
    • @Anteino 只需在 sn-p 中发布通配符导入,您就建议使用它们。
    • 我能感觉到你的意思,但这个小例子只是为了演示。那么import libfrom lib import * 到底有什么区别呢?
    猜你喜欢
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 2022-06-15
    相关资源
    最近更新 更多