使用from-import语句,仍然需要在Python 3中输入类名

时间:2013-04-05 22:39:37

标签: python import python-3.x module

我在同一目录中有三个Python模块。其中两个文件是我试图访问的类。我的印象是,如果我的一个模块中有以下代码(称为枚举):

class Directions:

    UP = 1
    DOWN = 2
    LEFT = 3
    RIGHT = 4

class Colors:
    RED = [255, 0, 0]

我可以使用以下语句:

from enum import Directions
from enum import Colors

能够像这样访问类成员:

foo = DOWN
bar = RED

但是,我必须像这样访问它们

foo = Directions.DOWN
bar = Colors.RED

否则会产生错误。有没有办法使用import / from-import语句来访问我的类成员而无需指定类名?或者我应该以不同的方式组织我的“枚举”?

4 个答案:

答案 0 :(得分:5)

直接从代码内部以外的任何地方访问类成员是不可能的。

尝试将枚举模块更改为以下内容:

__all__ = ['UP', 'DOWN', 'LEFT', 'RIGHT', 'RED']

# Directions
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4

# Colors
RED = [255, 0, 0]

然后在您希望访问这些变量的模块中使用from enum import *

此处不需要定义__all__,但最好还是使用它。它控制使用from foo import *时导入的名称。

答案 1 :(得分:3)

以不同的方式组织它们。没有直接的方法去做你想问的事。

另一方面,提到Directions.DOWNColors.RED是非常Pythonic。它是明确的(DOWN是指Direction,而不是MattressStuffing)并使用命名空间来包含数据(Colors.REDAlerts.RED不同)。这些都是好事。

答案 2 :(得分:2)

如果您的课程与您在此处发布的课程一样简单,那么他们就没有必要真正上课。但是,要获得你想要的代码,你需要这样做:

from enum import Directions
from enum import Colors

foo = Directions()    # This is called instantiation
foo.DOWN

bar = Colors()    # You can potentially instantiate as many of these as you want
bar.RED

rab = Colors()
rab.RED    # Try it, you'll see

类并不是真正意图保存你已经拥有的静态变量,但这段代码就是它的工作原理。

Python 不应的原因是您的代码可以正常工作是因为以下示例:

class Directions:

    UP = 1
    DOWN = 2
    LEFT = 3
    RIGHT = 4


class Directions2:

    UP = 9
    DOWN = 8
    LEFT = 7
    RIGHT = 6

然后导入

from enum import Directions
from enum import Directions2

如果您尝试使用foo = DOWN,那么Python如何知道您正在谈论的DOWN?此基础概念的技术术语是 namespace

答案 3 :(得分:1)

from enum import Directions

这将从模块Directions导入名称enum。内部发生的事情是,内部导入函数实际上将设置局部变量Directions为以这种方式导入的任何内容。特别是,它不会设置任何其他局部变量 - 这正是您使用from..import语法的原因,因此您可以完全控制设置的名称。

所以这样使用它,你就是无法设置变量DOWNRED

如果您想使用它们,则需要直接导入它们,例如from <something> import DOWN, REDfrom <something> import *,如果您只想导入所有内容(通常不鼓励)。

现在是<something>部分;您无法导入类型的属性,因此您必须以某种方式更改enum模块。一种详细的可能性是将每种类型DirectionsColors更改为单独的模块,因此您可以执行from enum.Directions import DOWN等。

另一种可能性是直接在枚举模块中公开这些变量,例如:

class Directions:
    UP = 1
    DOWN = 2
    LEFT = 3
    RIGHT = 4

UP = Directions.UP
DOWN = Directions.DOWN
LEFT = Directions.LEFT
RIGHT = Directions.RIGHT

当然,如果你甚至需要Directions类型,你可以争辩。通常,您实际上只想导入Directions并使用Directions.UP等明确指定每个枚举值。因此您实际上知道您所指的是什么类型的枚举。

相关问题