This is a bit of a silly thing, but I want to know if there is concise way in Python to define class variables that contain string representations of their own names. For example, one can define:
class foo(object): bar = 'bar' baz = 'baz' baf = 'baf'
Probably a more concise way to write it in terms of lines consumed is:
class foo(object): bar, baz, baf = 'bar', 'baz', 'baf'
Even there, though, I still have to type each identifier twice, once on each side of the assignment, and the opportunity for typos is rife.
What I want is something like what
sympy provides in its
The above injects into the namespace the variables
c, defined as the corresponding
sympy symbolic variables.
Is there something comparable that would do this for plain strings?
class foo(object): [nifty thing]('bar', 'baz', 'baf')
EDIT: To note, I want to be able to access these as separate identifiers in code that uses
>>> f = foo(); print(f.bar) bar
ADDENDUM: Given the interest in the question, I thought I'd provide more context on why I want to do this. I have two use-cases at present: (1) typecodes for a set of custom exceptions (each
Exception subclass has a distinct typecode set); and (2) lightweight enum. My desired feature set is:
- Only having to type the typecode / enum name (or value) once in the source definition.
class foo(object): bar = 'bar'works fine but means I have to type it out twice in-source, which gets annoying for longer names and exposes a typo risk.
- Valid typecodes / enum values exposed for IDE autocomplete.
Values stored internally as comprehensible strings:
- For the
Exceptionsubclasses, I want to be able to define
myError.__str__as just something like
return self.typecode + ": " + self.message + " (" + self.source + ")", without having to do a whole lot of
dict-fu to back-reference an
self.typecodeto a comprehensible and meaningful string.
For the enums, I want to just be able to obtain
widgetas output from
e = myEnum.widget; print(e), again without a lot of
- I recognize this will increase overhead. My application is not speed-sensitive (GUI-based tool for driving a separate program), so I don't think this will matter at all.
- For the
Straightforward membership testing, by also including (say) a
frozensetcontaining all of the typecodes / enum string values as
myEnum.Eclasses. This addresses potential problems from accidental (or intentional.. but why?!) use of an invalid typecode / enum string via simple sanity checks like
if not enumVal in myEnum.E: raise(ValueError('Invalid enum value: ' + str(enumVal))).
- Ability to import individual enum / exception subclasses via, say,
from errmodule import squirrelerror, to avoid cluttering the namespace of the usage environment with non-relevant exception subclasses. I believe this prohibits any solutions requiring post-twiddling on the module level like what Sinux proposed.
- For the enum use case, I would rather avoid introducing an additional package dependency since I don't (think I) care about any extra functionality available in the official
enumclass. In any event, it still wouldn't resolve #1.
I've already figured out implementation I'm satisfied with for all of the above but #1. My interest in a solution to #1 (without breaking the others) is partly a desire to typo-proof entry of the typecode / enum values into source, and partly plain ol' laziness. (Says the guy who just typed up a gigantic SO question on the topic.)