【问题标题】:Define class method based on import success根据导入成功定义类方法
【发布时间】:2022-01-11 04:16:37
【问题描述】:

我有一些接口类,如果 numpy 可用,我会为该类提供一些额外的方法(更快的实现)

可以根据导入成功定义一些函数,但相同的代码不适用于类方法。

这段代码

try:
    import numpy

    def main2():
        ret_array= numpy.array([],dtype=numpy.double)
        return ret_array
except ImportError:
    def main2():
        print ("do nothing")

成功定义了一个main2(),它返回一个空的numpy数组

但是这段代码

class xxx:
    try:
        import numpy

        def main2():
            ret_array= numpy.array([],dtype=numpy.double)
            return ret_array
    except ImportError:
        def main2():
            print ("do nothing")

导致异常 如果我尝试拨打main2()

xxx.main2()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "test2.py", line 17, in main2
    ret_array= numpy.array([],dtype=numpy.double)
NameError: name 'numpy' is not defined

还有其他方法可以实现吗? (根据模块的可用性定义不同的类方法)

【问题讨论】:

  • 因为您的 import numpy 在类内,所以 numpy 成为类变量(xxx.numpy 代替 numpy 会起作用,尽管我怀疑这不是推荐的方法) .
  • 您可以尝试检查导入的模块是否存在:stackoverflow.com/questions/4858100/…
  • 一种可能的方法是(在顶部,在类之外)try: import numpyexcept ImportError: numpy=None,然后在你的类定义中你可以使用if numpy: ....else:。 ... 使用 main2 的替代定义,具体取决于 numpy 是否可用。任何对numpy 的引用将只使用numpy 而不必使用xxx.numpy

标签: python class python-import


【解决方案1】:
try:
    import numpy

    class xxx:
        def main2(self):
            ret_array = numpy.array([],dtype=numpy.double)
            print(ret_array)
except:
    class xxx:
        def main2(self):
            print("do nothing")

【讨论】:

  • 这不起作用(或至少不合理)该类已经有 20 个方法,所以我需要做两个完整的定义
  • 如果类定义中还有其他部分怎么办?复制粘贴所有这些会很烦人。也许使用type() 手动构建类会更好。
  • @nobs 我确实在本地测试过它,它可以工作。
  • @wjandrea 还有其他语法选项,但我认为 OP 想要他们所要求的:)
【解决方案2】:

你可以试试:

class Test:
    def test(self):        
        try:
            import numpy
            import_succeeded = True
        except:
            import_succeeded = False
        
        if import_succeeded:
            pass
        else:
            pass

【讨论】:

  • 我全局导入了 numpy '''try: import numpy numpy_defined = True except ImportError: numpy_defined = False''' 并根据 bool 变量定义了函数 -> 这行得通
  • @nobs 老实说,你甚至不需要布尔值。如果导入失败,只需设置numpy=None(显然前提是您随后对其进行测试并且无论如何都不要使用它)。不过,除非有很好的理由在类中进行导入,否则我只会在模块的顶部进行。
【解决方案3】:

感谢我收到的所有提示

我要使用的解决方案是:

try:
    import numpy
except ImportError:
    numpy = None

class xxx:

    if numpy:
        def main2():
            ret_array= numpy.array([],dtype=numpy.double)
            return ret_array
    else:
        def main2():
            print ("do nothing")

【讨论】:

  • 很高兴您同意这个建议 :) 最后一件事:如果您打算将 main2 方法绑定到类的实例(而不是静态方法),那么您将需要self 参数。
  • @alani 是的,我知道!我试图从源中删除与问题无关的所有内容。我已经签入了代码,用一些巨大的数组对其进行了测试,并且令人惊讶的是 numpy 与标准列表相比有多快。 :-)
【解决方案4】:

在第一个版本的 main2() 中导入(再次)模块将起作用。

class xxx:
    try:
        import numpy
        def main2():
            import numpy
            ret_array= numpy.array([],dtype=numpy.double)
            return ret_array
    except ImportError:
        def main2():
            print ("do nothing")

y = xxx.main2()
print(y)

【讨论】:

    【解决方案5】:

    使用ABC

    from abc import ABC, abstractmethod
    
    class ICalculator(ABC):
      @abstractmethod
      def calculate(self) -> int:
        pass
    
    class CalculatorNoNumPy(ICalculator):
        def calculate(self):
          return 7
    
    class CalculatorWithNumPy(ICalculator):
        def calculate(self):
          return 9
    
    try:
      import YouCantFindMe # TODO: replace with numpy
      calculator = CalculatorWithNumPy()
    except ImportError:
       calculator = CalculatorNoNumPy()
    
    print(calculator.calculate())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-19
      • 2011-07-10
      • 1970-01-01
      • 2013-08-08
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多