我在python中编写一个包含许多常量变量的程序。我想创建一个文件,它将保存所有这些变量,如C中包含许多#define的.h文件。我尝试使用configparser,但我发现使用起来并不简单有趣。
你知道更好的方法吗?
答案 0 :(得分:13)
Python不允许像C或C ++这样的常量声明。
通常在Python中,常量是大写的(PEP 8标准),这有助于程序员知道它是常数。
实施例。 MY_CONSTANT = "Whatever"
另一种有效的方法是使用方法:
我不会使用但听说过的方法def MY_CONSTANT():
return "Whatever"
现在理论上,调用MY_CONSTANT()
就像一个常量。
修改强>
就像评论所说,有人可以通过调用
来改变价值MY_CONSTANT = lambda: 'Something else'
但请不要忘记同一个人可以在第一个示例中调用MY_CONSTANT = "Something else"
并更改初始值。在这两种情况下都不太可能,但可能。
答案 1 :(得分:6)
Python中没有常量,它们在C或Java中的存在方式。你可以通过功能来模仿它们:
def FOO():
return "foo"
您可以将函数调用包装在属性中,从而使其看起来像变量:
class Const:
@property
def FOO(self):
return "foo"
CONST = Const() # You need an instance
if something == CONST.FOO:
...
使用一些元元素,可以使用简洁的语法获取不可设置的属性:
def const(cls):
# Replace a class's attributes with properties,
# and itself with an instance of its doppelganger.
is_special = lambda name: (name.startswith("__") and name.endswith("__"))
class_contents = {n: getattr(cls, n) for n in vars(cls) if not is_special(n)}
def unbind(value): # Get the value out of the lexical closure.
return lambda self: value
propertified_contents = {name: property(unbind(value))
for (name, value) in class_contents.items()}
receptor = type(cls.__name__, (object,), propertified_contents)
return receptor() # Replace with an instance, so properties work.
@const
class Paths(object):
home = "/home"
null = "/dev/null"
现在,您可以将Paths.home
作为正常值访问,但无法分配给它。您可以定义使用@const
修饰的多个类,因为您可能会使用多个.h
文件。
答案 2 :(得分:2)
您可以使用以下内容:
文件结构:
myapp/
__init__.py
settings.py
main.py
settings.py
CONST_A = 'A'
CONST_B = 'B'
__初始化__。PY
from . import settings as global_settings
class Settings:
def __init__(self):
for setting in dir(global_settings):
if setting.isupper():
setattr(self, setting, getattr(global_settings, setting))
def __setattr__(self, attr, value):
if not getattr(self, attr, None):
super().__setattr__(attr, value)
else:
raise TypeError("'constant' does not support item assignment")
settings = Settings()
main.py
import settings
print(settings.CONST_A) # prints A
settings.CONST_A = 'C' # raises TypeError error
print(settings.CONST_A) # prints A
settings.CONST_C = 'C' # also able to add new constants
print(settings.CONST_C) # prints C
在设置类中覆盖__setattr__使所有属性都是只读的。 唯一的要求是将 settings.py 中的所有常量都用大写字母书写。 但请注意,如果直接导入变量,它将不起作用:
from settings import CONST_A
print(settings.CONST_A) # prints A
settings.CONST_A = 'C' # sets C
print(settings.CONST_A) # prints C
答案 3 :(得分:2)
Python 3.8 引入了 typing.Final
类型限定符,用于指示不应重新分配、重新定义或覆盖变量或属性。
PEP 591 -- Adding a final qualifier to typing
from typing import Final
# Annotate module variables
# (with or without an explicit type, using the syntax Final[<type>])
# (type is auto-determined in absence of an explicit type)
PI: Final[float] = 3.141592654
ANSWER_TO_EVERYTHING: Final = 42
# Annotate instance variables in class bodies
# (explicit type is needed if no value is assigned)
class Point:
x: Final[int]
y: Final = 0
def __init__(self, x: int):
self.x = x
# Annotate instance variables directly
# (only allowed in __init__ methods)
class Person:
def __init__(self, birth_year: int):
self.birth_year: Final = birth_year
如果您重新分配或重新定义 Final
变量,Linter 和类型检查器将向您显示警告。请注意,没有运行时检查,因此您仍然可以运行下面的代码。
ANSWER_TO_EVERYTHING: Final = 42
ANSWER_TO_EVERYTHING = 420 # shows warning
print(ANSWER_TO_EVERYTHING) # prints 420
还有 typing.final
装饰器,用于限制继承类和覆盖方法。
答案 4 :(得分:0)
Python尚未预处理。您可以只创建一个文件constant.py
#!/usr/bin/env python
# encoding: utf-8
"""
constant.py
"""
MY_CONSTANT = 50
在需要常量值时(例如下面的示例),导入constant.py文件。
#!/usr/bin/env python
# encoding: utf-8
"""
example.py
"""
import constant
print constant.MY_CONSTANT * 2
这样,您可以在整个项目中使用常量。
如果常量绑定到特定类并在该类中私下使用,以使它们特定于该类,则您也可以选择:
class Foo(object):
GOOD = 0
BAD = 1
def __init__(self...
如果要定义和使用整个模块,请将它们放在模块顶部
PIE = 3.47
class Foo(object):
def __init__(self...
答案 5 :(得分:0)
只需定义一个constants.py文件并编写所有常量即可。 Python中没有其他魔术。一般使用大写字母。