我在同一目录中有三个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语句来访问我的类成员而无需指定类名?或者我应该以不同的方式组织我的“枚举”?
答案 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.DOWN
和Colors.RED
是非常Pythonic。它是明确的(DOWN
是指Direction
,而不是MattressStuffing
)并使用命名空间来包含数据(Colors.RED
与Alerts.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
语法的原因,因此您可以完全控制设置的名称。
所以这样使用它,你就是无法设置变量DOWN
和RED
。
如果您想使用它们,则需要直接导入它们,例如from <something> import DOWN, RED
或from <something> import *
,如果您只想导入所有内容(通常不鼓励)。
现在是<something>
部分;您无法导入类型的属性,因此您必须以某种方式更改enum
模块。一种详细的可能性是将每种类型Directions
和Colors
更改为单独的模块,因此您可以执行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
等明确指定每个枚举值。因此您实际上知道您所指的是什么类型的枚举。