Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Grouped constants with possibility to iterate over group

Tags:

python

I have a module with constants (data types and other things).

Let's call the module constants.py

Let's pretend it contains the following:

# noinspection PyClassHasNoInit
class SimpleTypes:
    INT = 'INT'
    BOOL = 'BOOL'
    DOUBLE = 'DOUBLE'

# noinspection PyClassHasNoInit
class ComplexTypes:
    LIST = 'LIST'
    MAP = 'MAP'
    SET = 'SET'

This is pretty and works great, IDEs with inspection will be able to help out by providing suggestions when you code, which is really helpful. PyCharm example below:

IDE Help

But what if I now have a value of some kind and want to check if it is among the ComplexTypes, without defining them in one more place. Would this be possible?

To clarify even more, I want to be able to do something like:

if myVar in constants.ComplexTypeList:
    # do something

Which would of course be possible if I made a list "ComplexTypeList" with all the types in the constants module, but then I would have to add potentially new types to two locations each time (both the class and the list), is it possible to do something dynamically?

I want it to work in python 2.7, though suggestions on how to do this in later versions of python is useful knowledge as well.

SOLUTION COMMENTS:

I used inspect, as Prune suggested in the marked solution below. I made the list I mentioned above within the constants.py module as:

ComplexTypeList = [m[1] for m in inspect.getmembers(ComplexTypes) if not m[0].startswith('_')]

With this it is possible to do the example above.

like image 217
dargolith Avatar asked Jan 29 '16 00:01

dargolith


1 Answers

I think I have it. You can use inspect.getmembers to return the items in the module. Each item is a tuple of (name, value). I tried it with the following code. dir gives only the names of the module members; getmembers also returns the values. You can look for the desired value in the second element of each tuple.

constants.py

class ComplexTypes:
    LIST_N = 'LIST'
    MAP_N  = 'MAP'
    SET_N  = 'SET'

test code

from constants import ComplexTypes
from inspect import getmembers, isfunction

print dir(ComplexTypes)

for o in getmembers(ComplexTypes):
    print o

output:

['LIST_N', 'MAP_N', 'SET_N', '__doc__', '__module__']
('LIST_N', 'LIST')
('MAP_N', 'MAP')
('SET_N', 'SET')
('__doc__', None)
('__module__', 'constants')

You can request particular types of objects with the various is operators, such as

getmembers(ComplexTypes, inspect.isfunction)

to get the functions. Yes, you can remove things with such a simple package. I don't see a method to get you constants in a positive fashion. See documentation.

like image 191
Prune Avatar answered Oct 26 '22 12:10

Prune