Search code examples
pythonpython-2.7variablesvariable-names

Concatenate string literals to generate variable name


Question

In python, what is the shortest/easiest way to create a function which allows me to access a variable by concatenating two string literals to generate the variable's name?


Background

In C, I can do something like so:

#define CONCAT(x,y) x ## _ ## y

Then, later in my code, I could do something like:

int i = CONCAT(PRODUCT,BANANA).

Assuming a macro exists with the name PRODUCT_BANANA, its value is now assigned to i. I can accomplish something similar in shell scripts via indirection.


Question - Redux

How can I accomplish this same functionality in python? I'm doing this because I have a python class with thousands of variables for dozens of different products, i.e.

class A(object):
    BANANA_ADDRESS0 = 0xABCD;
    PINEAPPLE_ADDRESS0 = 0x1234;
    BANANA_ADDRESS1 = 0x4567;
    PINEAPPLE_ADDRESS1 = 0x1000;

I'd like to be able to have a function that can be, for example, executed via someFunc("BANANA", "ADDRESS0"), resolve the value as A.BANANA_ADDRESS0, and return the associated value (0xABCD, in this case).


Extra

Assuming the above is possible, is it possible to have the function always interpret the supplied function arguments as string literals, so function calls don't need the arguments wrapped in single/double quotes? i.e. so it can be called via someFunc(BANANA, ADDRESS0), rather than someFunc("BANANA", "ADDRESS0")?


Solution

  • The first part is easy:

    class A(object):
        BANANA_ADDRESS0 = 0xABCD;
        PINEAPPLE_ADDRESS0 = 0x1234;
        BANANA_ADDRESS1 = 0x4567;
        PINEAPPLE_ADDRESS1 = 0x1000;
    
        @classmethod
        def some_func(cls, name_a, name_b):
            name = '{}_{}'.format(name_a, name_b)
            return getattr(cls, name)
    
    value = A.some_func('BANANA', 'ADDRESS1')
    

    But the second part is not possible unless you have a limited set of names, in which case you would also have to have

    BANANA = 'BANANA'
    PINEAPPLE = 'PINEAPPLE'
    

    etc