【问题标题】:python initialization of constants in separate filepython初始化单独文件中的常量
【发布时间】:2012-10-20 20:57:28
【问题描述】:

我有一个与此处提出的问题类似的问题: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 的方法来代替重新输入所有变量名?

【问题讨论】:

    标签: python class import constants


    【解决方案1】:

    你可以这样做

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

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

    【讨论】:

    • 谢谢。只是为了访问它们的语法:“instance.attribute”
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      class Constants(object):
          x = 1.2
          y = 30.4
      
      
      # optional 
      class Base(object):
          pass
      
      class Something(Constants, Base):
          pass
      
      
      s = Something()
      
      print(s.x)
      

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

      【讨论】:

      • 创建一个你从不打算实例化的类只是为了保存一堆属性有点反模式,恕我直言。模块本身也是一流的对象;只是传递模块而不是创建一个类并传递它。我承认将它用作 mixin 可能会很有用,但是你已经进行了多重继承(看到它只是一个简单的 class-var 转储,留给读者作为练习)。
      • @Ben 这就是我最后所说的。 :)
      • 谢谢。实际上你是对的,字典可能是保存它们的更好方法。我只是喜欢使用“instance.attribute”语法的想法
      【解决方案4】:

      总是有这样的:

      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 模块很容易最终包含比您意识到的更多的名称。例如,如果您在定义所有常量的过程中必须在 constants 中导入另一个模块(例如,math),那么您将在所有 something 实例中得到一个意想不到的 math 属性.

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

      【讨论】:

      • 谢谢,你是对的,明确列出它们会更清楚。
      【解决方案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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 1970-01-01
        相关资源
        最近更新 更多