问题
First time user on stack overflow and I'm excited to be here.
INTRO: I recently began the magical adventure into the world of Python programming - I love it. Now everything has gone smoothly in my awkward transition from C, but I'm having trouble creating something which would be synonymous to a HEADER file (.h).
PROBLEM: I have medium sized dictionaries and lists (about 1,000 elements), lengthy enums, and '#defines' (well not really), but I can't find a CLEAN way to organize them all. In C, I would throw them all in a header file and never think again about it, however, in Python that's not possible or so I think.
CURRENT DIRTY SOLUTION: I'm initializing all CONSTANT variables at the top of either the MODULE or FUNCTION (module if multiple functions need it).
CONCLUSION: I would be forever grateful if someone had come up with a way to CLEANLY organize constant variable's.
THANK YOU SO MUCH!
回答1:
Put your constants into their own module:
# constants.py
RED = 1
BLUE = 2
GREEN = 3
Then import that module and use the constants:
import constants
print "RED is", constants.RED
The constants can be any value you like, I've shown integers here, but lists and dicts would work just the same.
回答2:
Usually I do this:
File: constants.py
CONSTANT1 = 'asd'
CONSTANT_FOO = 123
CONSTANT_BAR = [1, 2, 5]
File: your_script.py
from constants import CONSTANT1, CONSTANT_FOO
# or if you want *all* of them
# from constants import *
...
Now your constants are in one file and you can nicely import and use them.
回答3:
Make a separate file constants.py
, and put all globally-relevant constants in there. Then you can import constants
to refer to them as constants.SPAM
or do the (questionable) from constants import *
to refer to them simply as SPAM
or EGGS
.
While we're here, note that Python doesn't support constant constants. The convention is just to name them in ALL_CAPS
and promise not to mutate them.
回答4:
If you want to mess with nested constants and don't like dicts, I came up with this fun solution:
# 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()))
Ex:
constants = {
'A': {
'B': {
'C': 'D'
}
}
}
CONSTANTS = DictTransformer.transform(d, klass=namedtuple, klassname='namedtuple')
CONSTANTS.A.B.C == 'D'
Pros:
- handles nested dicts
- can potentially generate other types of dicts/classes
- namedtuples provide immutability for constants
Cons:
- may not respond to .keys and .values if those are not provided on your klass (though you can sometimes mimic with ._fields and list(A.B.C))
Thoughts?
h/t to @hlzr and you guys for the original class idea
来源:https://stackoverflow.com/questions/11111632/python-best-cleanest-way-to-define-constant-lists-or-dictionarys