39

第一次使用堆栈溢出,我很高兴来到这里。

简介:我最近开始了进入 Python 编程世界的神奇冒险——我喜欢它。现在,在我从 C 语言的尴尬过渡中,一切都顺利进行了,但我在创建与 HEADER 文件 (.h) 同义的东西时遇到了麻烦。

问题:我有中等大小的字典和列表(大约 1,000 个元素)、冗长的枚举和“#defines”(不是真的),但我找不到一种干净的方式来组织它们。在 C 语言中,我会将它们全部放在一个头文件中,并且永远不会再考虑它,但是,在 Python 中这是不可能的,或者我认为是不可能的。

当前肮脏的解决方案:我正在初始化 MODULE 或 FUNCTION 顶部的所有 CONSTANT 变量(如果多个函数需要它,则为模块)。

结论:如果有人想出了一种干净地组织常量变量的方法,我将永远感激不尽。

太感谢了!

4

5 回答 5

25

将您的常量放入自己的模块中:

# constants.py

RED = 1
BLUE = 2
GREEN = 3

然后导入该模块并使用常量:

import constants

print "RED is", constants.RED

常量可以是你喜欢的任何值,我在这里展示了整数,但列表和字典的工作方式是一样的。

于 2012-06-20T01:23:39.323 回答
12

通常我这样做:

文件:常量.py

CONSTANT1 = 'asd'
CONSTANT_FOO = 123
CONSTANT_BAR = [1, 2, 5]

文件:your_script.py

from constants import CONSTANT1, CONSTANT_FOO
# or if you want *all* of them
# from constants import *

...

现在您的常量在一个文件中,您可以很好地导入和使用它们。

于 2012-06-20T01:24:08.660 回答
4

制作一个单独的文件constants.py,并将所有全局相关的常量放在那里。然后你可以import constants将它们称为constants.SPAMor 做 (有问题的)from constants import *将它们简单地称为SPAMor EGGS

当我们在这里时,请注意 Python 不支持常量。约定只是将它们命名ALL_CAPS并保证不会改变它们。

于 2012-06-20T01:24:36.760 回答
1

接受的答案很好,更进一步可以在定义常量时使用类型;您可以只指定 Final,或者更进一步并提供 Final[type],例如:

from typing import Final, List
CONSTANT1: Final = 'asd'
CONSTANT_FOO: Final[int] = 123
ADLS_ENVIRONMENTS: Final[List[str]] = ["sandbox", "dev", "uat", "prod"]

# etc.

https://www.python.org/dev/peps/pep-0591/#the-final-annotation

于 2021-08-25T16:57:11.847 回答
0

如果您想弄乱嵌套常量并且不喜欢 dicts,我想出了这个有趣的解决方案:

# Recursively transform a dict to instances of the desired class

import json
from collections import namedtuple

class DictTransformer():
    @classmethod
    def constantize(self, d):
        return self.transform(d, klass=namedtuple, klassname='namedtuple')

    @classmethod
    def transform(self, d, klass, klassname):
        return self._from_json(self._to_json(d), klass=klass, klassname=klassname)

    @classmethod
    def _to_json(self, d, access_method='__dict__'):
        return json.dumps(d, default=lambda o: getattr(o, access_method, str(o)))

    @classmethod
    def _from_json(self, jsonstr, klass, klassname):
        return json.loads(jsonstr, object_hook=lambda d: klass(klassname, d.keys())(*d.values()))

前任:

constants = {
  'A': {
    'B': {
      'C': 'D'
    }
  }
}
CONSTANTS = DictTransformer.transform(d, klass=namedtuple, klassname='namedtuple')
CONSTANTS.A.B.C == 'D'

优点:

  • 处理嵌套的字典
  • 可能会生成其他类型的字典/类
  • namedtuples 为常量提供不变性

缺点:

  • 如果您的 klass 上未提供 .keys 和 .values ,则可能无法响应(尽管您有时可以使用 ._fields 和 list(ABC) 进行模仿)

想法?

h/t 致 @hlzr 和你们的原创课程理念

于 2019-10-23T02:22:20.527 回答