3

我有一个类似于这里提出的问题的问题:Importing a long list of constants to a Python file

基本上,我有一个单独的模块,它只包含一长串常量,例如

constants.py

x = 1.2
y = 30.4
.
.
.

在另一个模块中,我想导入这些常量并将它们初始化为实例属性。

class.py

class something(object):
    def __init__(self):
        import constants
        self.x = constants.x
        self.y = constants.y
        .
        .
        .

是否有一种更简单或更 Pythonic 的方法来执行此操作,而不是重新输入所有变量名?

4

5 回答 5

5

Python 开发人员开发了一个很酷的解决方案:它称为ConfigParser

一个实际的例子:config.ini

[constants]
key = value
x = 0
y = 1

类.py

from ConfigParser import SafeConfigParser
class MyClass(object):
    def __init__(self, **kwargs):
        self.config = SafeConfigParser(defaults=kwargs).read('config.ini')

    def get_x(self):
        return self.config.get('constants', 'x')

我希望这有帮助。

编辑:如果你需要实例属性,你可以这样做:

class MyClass(object):
    ...
    def __getattr__(self, key):
        return self.config.get('constants', key)

EDIT2:需要一个 Python 文件和一个 .ini 文件不是解决方案吗?

from . import config
class Myclass(object):
    def __getattr__(self, key):
        return getattr(config, key)
于 2012-10-31T13:01:45.487 回答
1

你可以做

for constant, value in constants.__dict__.values():
  setattr(self, constant, value)

为什么需要它们作为实例属性?

于 2012-10-31T11:57:35.717 回答
1

您可以将常量放在模块中的类中。这个类可以更容易地传递,或者用作任何需要这些常量作为类属性的类的混合类。

class Constants(object):
    x = 1.2
    y = 30.4


# optional 
class Base(object):
    pass

class Something(Constants, Base):
    pass


s = Something()

print(s.x)

但是,由于它只是数据,我可能只会使用某种类型的数据结构(例如字典)来保存它们。当任何代码都可以从模块中引用它们时,我不确定为什么需要将它们作为类属性。

于 2012-10-31T12:02:51.047 回答
1

总有这样的:

class something(object):
    def __init__(self):
        import constants
        for name in ['x', 'y', ...]:
            setattr(self, name, getattr(constants, name))

这样做的好处是可以避免多次重复self.X = constants.X,并且意味着您只在一个地方列出一次名称。

可以使用这个:

for name, value in constants.__dict__.iteritems():
    setattr(self, name, value)

constants不明确列出它们的情况下绑定所有名称,但我个人不会。something它使对象实际具有哪些属性变得不太清楚,并且 Python 模块容易最终包含比您意识到的更多的名称。例如,如果您必须在定义所有常量的过程中导入另一个模块(例如,mathconstants,那么您最终会得到所有实例的意外math属性。something

我认为明确列出您要导入的名称更清楚。另外,这意味着something如果您发现需要添加更多常量以供程序的其他部分使用(并且如果常量只能与它们相关,something那么它们确实应该列something在不在外部模块中)。

于 2012-10-31T12:04:27.087 回答
0

from constants import x, y只要确保你以后不会意外地覆盖你的变量(即不要使用通用名称)

于 2012-10-31T11:58:09.710 回答