【问题标题】:Create constants using a "settings" module?使用“设置”模块创建常量?
【发布时间】:2010-09-29 17:57:03
【问题描述】:

我对 Python 比较陌生。我希望创建一个“设置”模块,其中将存储各种特定于应用程序的常量。

这是我想要设置我的代码的方式:

settings.py

CONSTANT = 'value'

脚本.py

import settings

def func():
    var = CONSTANT
    # do some more coding
    return var

我收到一条 Python 错误说明:

global name 'CONSTANT' is not defined.

我在 Django 的源代码中注意到他们的 settings.py 文件有一些常量,就像我一样。我对如何将它们导入脚本并通过应用程序引用感到困惑。

编辑

感谢您的所有回答!我尝试了以下方法:

import settings

print settings.CONSTANT

我遇到同样的错误

ImportError: cannot import name CONSTANT

【问题讨论】:

  • 这没有意义。如果settings 没有定义CONSTANT,你应该得到一个AttributeError,如果它不能导入设置,你应该得到一个ImportError,在这种情况下它甚至不会看CONSTANT
  • 那我是不是做错了什么?
  • 将您最后发布的两行完全按照您发布的方式自己放入文件中,看看它是否有效。
  • 感谢大家的帮助。我想到了。它与 init.py 文件的位置有关。我试图导入设置,所以 python 正在寻找找不到它,所以一旦我引用了“模块”目录设置,一切正常。所以基本上我的导入语句看起来像这样:从模块导入设置。我认为有一个更好的方法可以做到这一点,更 Pythonic,所以我将尝试不同的组合。再次感谢您的所有回答。

标签: python


【解决方案1】:

最简单的方法是让设置成为一个模块。

(设置.py)

CONSTANT1 = "value1"
CONSTANT2 = "value2"

(消费者.py)

import settings

print settings.CONSTANT1
print settings.CONSTANT2

当你导入一个 python 模块时,你必须在你从中提取的变量前面加上模块名称。如果您确切知道要在给定文件中使用哪些值并且您不担心它们在执行期间会发生变化,那么您可以这样做

from settings import CONSTANT1, CONSTANT2

print CONSTANT1
print CONSTANT2

但我不会对最后一个得意忘形。阅读您的代码的人很难分辨出值的来源。如果另一个客户端模块更改了这些值,则会阻止这些值被更新。最后一种方法是

import settings as s

print s.CONSTANT1
print s.CONSTANT2

这样可以节省您的打字时间,会传播更新,并且只需要读者记住s 之后的任何内容都来自设置模块。

【讨论】:

  • @delnan 我特别避免提及机制,以免您的答案过时;)
  • 嗯,实际上已经过时了 ;) 知道确切的语义是有用且可取的,但要使其工作,它不是必需的 - 尽管有必要知道它的含义,这在你的答案。
  • 我虽然常量的想法是它不能在运行时改变?
  • @Lie Ryan,Python 没有常量。在多程序员项目中,你永远不知道。
  • @AaronMcSmoot:是的,但是如果您甚至打算在运行时更改常量,那很可能是您的设计错误。
【解决方案2】:

第一步:在同一目录下新建文件settings.py,方便访问。

#database configuration settings

database = dict(
    DATABASE = "mysql",
    USER     = "Lark",
    PASS     = ""
)

#application predefined constants

app = dict(
    VERSION   = 1.0,
    GITHUB    = "{url}"
)

第 2 步:将设置模块导入您的应用程序文件。

import settings as s            # s is aliasing settings & settings is the actual file you do not have to add .py 

print(s.database['DATABASE'])   # should output mysql

print(s.app['VERSION'])         # should output 1.0

如果你不喜欢使用像 s 这样的别名,你可以使用 不同的语法

from settings import database, app

print(database['DATABASE'])   # should output mysql

print(app['VERSION'])         # should output 1.0

注意第二种导入方式可以直接使用字典名

一个小技巧您可以使用 * 导入所有设置文件上的代码,以防您有一个大文件并且您会在您的应用程序中使用其上的大部分设置

from settings import *      # * represent all the code on the file, it will work like step 2


print(database['USER'])       # should output lark

print(app['VERSION'])         # should output 1.0

希望对你有帮助。

【讨论】:

    【解决方案3】:

    当你import settings 时,一个名为settingsmodule 对象被放置在全局命名空间中——并且这个对象带有settings.py 中的属性。 IE。在settings.py 之外,您将CONSTANT 称为settings.CONSTANT

    【讨论】:

      【解决方案4】:

      让你的 settings.py 保持原样,然后你可以像 Django 一样使用它:

      import settings
      
      def func():
          var = settings.CONSTANT
      

      【讨论】:

        【解决方案5】:

        ...或者,如果您真的希望将 settings.py 中的所有常量导入到全局命名空间中,您可以运行

        from settings import *
        

        ...但是,正如其他人在这里提到的那样,使用settings.CONSTANT 是完全正确的。

        【讨论】:

        • 查看我的回答,了解使用 import 语句的所有三种可能方式。
        • 其实这是不可取的。参见例如docs.python.org/howto/doanddont.html#from-module-import。尽管在这种情况下,它具有适当的副作用,即更改常量不会影响其他模块。
        • 说得好,@AaronMcSmooth。从技术上讲,我并没有说导入 * 是可取的,只是有可能:P
        • @delnan。我不太确定这是可取的。这取决于应用程序,但很可能应该传播更改(如果它们甚至发生)
        【解决方案6】:

        查看我发布到Can I prevent modifying an object in Python? 的答案,它可以满足您的需求(以及强制使用大写标识符)。实际上,这个问题的答案可能比另一个问题更好。

        【讨论】:

          【解决方案7】:

          这种方式效率更高,因为它只加载/评估您的设置变量一次。它适用于我所有的 Python 项目。

          pip install python-settings
          

          这里的文档:https://github.com/charlsagente/python-settings

          您需要一个包含所有已定义常量的 settings.py 文件,例如:

          # settings.py
          
          DATABASE_HOST = '10.0.0.1'
          

          然后您需要设置一个环境变量(导出 SETTINGS_MODULE=settings)或手动调用配置方法:

          # something_else.py
          
          from python_settings import settings
          from . import settings as my_local_settings
          
          settings.configure(my_local_settings) # configure() receives a python module
          

          该实用程序还支持对重负载对象进行延迟初始化,因此当您运行 python 项目时,它加载速度更快,因为它只在需要时评估设置变量

          # settings.py
          
          from python_settings import LazySetting
          from my_awesome_library import HeavyInitializationClass # Heavy to initialize object
          
          LAZY_INITIALIZATION = LazySetting(HeavyInitializationClass, "127.0.0.1:4222") 
          # LazySetting(Class, *args, **kwargs)
          

          只需配置一次,然后在需要的地方调用您的变量:

          # my_awesome_file.py
          
          from python_settings import settings 
          
          print(settings.DATABASE_HOST) # Will print '10.0.0.1'
          

          【讨论】:

            【解决方案8】:

            我是 python 新手,但是如果我们定义一个像函数这样的常量 在settings.py上

            def CONST1():
                return "some value"
            

            main.py

            import setings
            
            print setings.CONST1() ##take an constant value
            

            这里我只看到一个,值不能改变,但它的工作就像一个函数..

            【讨论】:

              【解决方案9】:

              试试这个:

              在settings.py中:

              CONSTANT = 5
              

              在您的主文件中:

              from settings import CONSTANT
              
              class A:
                  b = CONSTANT
              
                  def printb(self):
                       print self.b
              

              我认为您的上述错误来自设置文件导入得太晚。确保它位于文件的顶部。

              【讨论】:

                【解决方案10】:

                同样值得一试的是simple-settings 项目,它允许您在运行时将设置输入脚本,从而允许特定环境的设置(想想开发、测试、产品......)

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多