使用“设置”模块创建常量?


78

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

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

settings.py

CONSTANT = 'value'

script.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


5
那没有道理。您应该得到一个AttributeErrorifsettings未定义CONSTANTImportErrorif无法导入设置,在这种情况下甚至不会查看CONSTANT
aaronasterling

那我在做错什么吗?
云雀

1
将您上次发布的两行与发布时完全一样,自动放置在文件中,然后看是否有效。
aaronasterling

1
谢谢大家的帮助。我想到了。它与init .py文件的放置有关。我试图导入设置,所以python找不到它,因此一旦我引用了“ modules”目录设置,一切就可以正常工作。因此,基本上我的导入语句如下所示:从模块导入设置。我认为有一种更好的方法可以做到这一点,多使用pythonic,所以我将尝试不同的组合。再次感谢您的所有答复。
Lark

Answers:


140

最简单的方法是将设置作为模块。

(settings.py)

CONSTANT1 = "value1"
CONSTANT2 = "value2"

(consumer.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我特别避免提及机制,以免使您的答案过时;)
aaronasterling 2010年

好吧,实际上已经过时了;)知道确切的语义是有用且可取的,但是要使它起作用,就不需要-尽管有必要知道它的含义,这在您的答案中已经很概括了。

3
我虽然常量的想法是不能在运行时更改它?
Lie Ryan

@Lie Ryan,Python没有常量。在多程序员项目中,您永远不会知道。
aaronasterling

1
@AaronMcSmoot:是的,但是如果您甚至打算在运行时之后更改常量,那很可能会怀疑您的设计错误。
Lie Ryan

17

第1步:在同一目录上创建一个新文件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

我希望有帮助。


5

当您将时import settingsmodule称为的对象settings放置在全局名称空间中-该对象带有的settings.py属性已经存在。即在外面settings.py,您CONSTANT称为settings.CONSTANT


4

完全保留您的settings.py,然后就可以像Django一样使用它:

import settings

def func():
    var = settings.CONSTANT

3

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

from settings import *

...但是使用settings.CONSTANT其他人在这里提到的方法是正确的。


有关使用该import语句的所有三种可能方式,请参阅我的答案。
aaronasterling

2
实际上,这是不可取的。参见例如docs.python.org/howto/doanddont.html#from-module-import。尽管在这种情况下,它具有可能的副作用,但常数的更改不会影响其他模块。

2
很好说,@ AaronMcSmooth。从技术上讲,我并不是说建议导入*,只是说它是可能的:P
ewall

@delnan。我不确定这是否理想。这取决于应用程序,但是很有可能应该传播更改(如果更改甚至发生)
aaronasterling


2

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

def CONST1():
    return "some value"

main.py

import setings

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

在这里,我只看到一个值不能更改,但其作用类似于函数。


2

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

pip install python-settings

此处的文档:https : //github.com/charlsagente/python-settings

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

# settings.py

DATABASE_HOST = '10.0.0.1'

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

# 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'

1

试试这个:

在settings.py中:

CONSTANT = 5

在您的主文件中:

from settings import CONSTANT

class A:
    b = CONSTANT

    def printb(self):
         print self.b

我认为您的上述错误是由于导入设置文件为时已晚。确保它在文件的顶部。


1

还值得一试的是simple-settings项目,该项目允许您在runtim处将设置输入到脚本中,从而可以进行特定于环境的设置(例如dev,test,prod等)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.