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

5 投票
4 回答
8995 浏览
提问于 2025-04-16 22:34

有没有人能解释一下怎么让下面这个例子正常工作吗?因为这个类里面有几个函数会用到同一个平台的函数,我觉得把它直接放在类里面导入会更好,但我不知道怎么在函数里面使用它(因为我总是收到关于它的错误信息)。

#!/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 个回答

1

我很惊讶居然没有人想到这一点:

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()
1

你只需要在最上面导入它,也就是在你声明类之前。这是解释器期待看到的地方。如果你试着在类里面或者其他定义中导入,就可能会遇到一些很麻烦的作用域问题。

另外,根据你想做的事情,你可以尝试继承你正在使用的一些东西(简单来说,这有点像Java中的extends)。

13

其实,这事没那么简单。

实际上,导入语句在很多方面看起来就像是直接在原地定义了某个东西。如果你写

class test:
    from platform import system

它看起来就和

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

一模一样,但你会遇到以下几个问题:

  1. 你不能直接用 system(),因为 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)

解决这些问题有几种方法:

  1. import platform 放在最上面,然后在需要的地方用 platform.system(),这样就解决了上面列表中的第一个问题。
  2. 使用 staticmethod 装饰器,这样可以解决上面列表中的第二和第三个问题。

像这样:

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() 始终是 test 类需要的,所以没有理由把这个导入从最上面移开。就把它留在那里,不用担心。

撰写回答