Python:在函数中使用类内部导入

时间:2011-07-30 13:14:51

标签: python python-import

任何人都可以解释如何使以下示例有效吗?由于类中的几个函数将使用平台中的相同函数,我认为最好在类内部导入它,但我不知道如何在函数内部使用它(因为我经常出错关于它)。

#!/usr/bin/python

class test:
   from platform import system
   is_linux(self):
      system = system()
      if system == "Linux": return True

一个更好的例子:

#!/usr/bin/python

# Add ANSI colour strings
class stdout:
    from sys import stdout
    def message(message, self):  stdout.write(message)

注意:这只是一个片段,有些部分缺失,但我的意思是一个例子 我知道我可能只是移动system = system()并使用self.system但也许是更好的方式?

4 个答案:

答案 0 :(得分:8)

嗯,事情并非那么简单。 实际上,import语句在很多方面看起来像直接定义某些东西而不是它。如果你写

class test:
    from platform import system

看起来很像

class test:
    def system():
        # ....

然后您遇到以下问题:

  1. 你不能只使用system(),因为系统不在全球范围内
  2. 你不能使用self.system(),因为在这种形式下,python会自动传递self作为第一个参数,但是system()没有参数,你会得到TypeError: system() takes no arguments (1 given)
  3. 你不能使用test.system(),因为system()看起来像一个简单的方法,你会得到TypeError: unbound method system() must be called with test instance as first argument (got nothing instead)
  4. 有几种解决这些问题的方法:

    1. import platform置于顶层,并在任何地方使用platform.system(),从而解决prev的问题#1。列表
    2. 使用staticmethod装饰器,修复prev的问题#2和#3。列表。
    3. class test:
          from platform import system
          system = staticmethod(system)
      

      然后你可以使用self.system()或test.system()

      实际上,你应该只是将所有内容导入到顶层而忘记它。 如果您需要特殊的运行方式,则只需拆分导入声明。 像

      import foo
      import bar
      
      def fun(param1, param2):
          # .....
      
      if __name__ == '__main__':
          from sys import argv
          if len(argv) > 2:
              fun(argv[1], argv[2])
      

      在此示例中,移动from sys import argv有效,因为仅在运行脚本时才需要它。但是当您将其用作导入模块时,此导入中不需要它。 但这不是你的情况,因为在你的情况下,测试类总是需要system(),所以没有理由将这个导入从顶层移动。只要把它放在那里就不要紧。

答案 1 :(得分:2)

我很惊讶没有人想到这个:

class test:
    def __init__(self):
        from platform import system
        self.system = system()
    def test(self):
        return self.system()

d = test()
print d.system()
print d.test()

答案 2 :(得分:1)

在宣布课程之前,先将其导入顶部。这就是解释器期望看到它的地方,如果你尝试在类或其他定义中导入它,你将面临以后遇到重大范围问题的风险。

或者,基于你正在尝试做的事情,你可能会尝试将你正在使用的一些东西子类化(在Java中,它有点像extends。)

答案 3 :(得分:0)

看起来像premature optimization的情况!?我认为在类定义中导入一些东西是不可能的。你为什么要那样做?在某些情况下,在方法中导入可能是有意义的,但即使这些也很少见。为什么不把导入放在文件的顶部,每个人都可以看到它?